QT 常用的宏

QT中有很多宏,你可能经常看到 Q_OBJECT、Q_PROPERTY,但是除了这个之外,还有其他的宏,以下是QT中常用的宏的整理:

1、Q_OBJECT

作用:启用元对象系统功能,包括:

• 信号槽机制

• 属性系统

• 动态类型转换

• 国际化

• 元对象反射

cpp 复制代码
class MyClass : public QObject {
    Q_OBJECT  // 必须放在类的私有部分
public:
    MyClass(QObject *parent = nullptr);
signals:
    void mySignal();
public slots:
    void mySlot();
};

2、Q_GADGET

信号槽实现的关键是必须继承QObject,那么有没有不继承QObject实现元对象的宏或类呢?答案是有的,即Q_GADGET,它是 Qt 元对象系统提供的一个宏,用于为非 QObject 派生类提供轻量级的元对象支持。它的功能类似 Q_OBJECT(用于 QObject 派生类),但更轻量:

  • 支持元对象信息(如类名、属性、枚举)的反射;
  • 可通过 QMetaObject 访问类的元信息;
  • 支持 Q_PROPERTY、Q_ENUMS(或 Q_ENUM)等元对象特性;
  • 不支持信号槽(因无需继承 QObject,避免了 QObject 的额外开销)。
  • 兼容 Qt 元类型系统:可通过 qRegisterMetaType 注册,支持在 QVariant 中存储。
  • 适用于需要元对象支持但无需信号槽的轻量级类(如数据结构体、枚举容器等)。
cpp 复制代码
class MyGadget {
    Q_GADGET
    Q_PROPERTY(int value READ getValue WRITE setValue)
public:
    int getValue() const { return m_value; }
    void setValue(int v) { m_value = v; }
private:
    int m_value = 0;
};

3、Q_PROPERTY

作用:声明对象属性,启用属性系统功能

cpp 复制代码
class MyClass : public QObject {
    Q_OBJECT
    Q_PROPERTY(QString name READ getName WRITE setName NOTIFY nameChanged)
    Q_PROPERTY(int count READ getCount CONSTANT)
    Q_PROPERTY(bool enabled READ isEnabled WRITE setEnabled STORED false)
    
    // 枚举属性
    Q_PROPERTY(Status status READ getStatus WRITE setStatus NOTIFY statusChanged)
    
public:
    enum Status { Idle, Running, Error };
    Q_ENUM(Status)
    
    QString getName() const { return m_name; }
    void setName(const QString &name) {
        if (m_name != name) {
            m_name = name;
            emit nameChanged();
        }
    }
    
signals:
    void nameChanged();
    void statusChanged();
};

4、Q_ENUM

作用:将枚举注册到元对象系统,支持动态类型转换

cpp 复制代码
class MyClass : public QObject {
    Q_OBJECT
public:
    enum Priority { Low, Medium, High, VeryHigh };
    Q_ENUM(Priority)
    
    void test() {
        int value = MyClass::High;  // 2
        QString name = QMetaEnum::fromType<MyClass::Priority>()
                      .valueToKey(2);  // "High"
    }
};

5、Q_FLAG

作用:将枚举注册为标志枚举,支持位运算

cpp 复制代码
class MyClass : public QObject {
    Q_OBJECT
public:
    enum Permission {
        NoPermission   = 0x00,
        ReadPermission = 0x01,
        WritePermission = 0x02,
        ExecutePermission = 0x04
    };
    Q_DECLARE_FLAGS(Permissions, Permission)
    Q_FLAG(Permissions)
    
    void setPermissions(Permissions perms) {
        if (perms & ReadPermission) { /* ... */ }
    }
};
Q_DECLARE_OPERATORS_FOR_FLAGS(MyClass::Permissions)

6、Q_DISABLE_COPY

作用:禁止类的拷贝构造函数和拷贝赋值运算符

cpp 复制代码
Class(const Class &) = delete;
Class &operator=(const Class &) = delete;
cpp 复制代码
class NonCopyableClass {
    Q_DISABLE_COPY(NonCopyableClass)
public:
    NonCopyableClass() = default;
};

7、Q_DECLARE_METATYPE

作用:声明自定义类型可用于QVariant和信号槽

cpp 复制代码
struct CustomData {
    int id;
    QString name;
};
Q_DECLARE_METATYPE(CustomData)

// 可以在QVariant中使用
CustomData data{1, "test"};
QVariant var = QVariant::fromValue(data);

8、Q_INVOKABLE

作用:标记成员函数可从元对象系统调用

cpp 复制代码
class Calculator : public QObject {
    Q_OBJECT
public:
    Q_INVOKABLE int add(int a, int b) { return a + b; }
    
    // 可以从元对象系统调用
    // QMetaObject::invokeMethod(calc, "add", 
    //   Q_RETURN_ARG(int, result), 
    //   Q_ARG(int, 1), 
    //   Q_ARG(int, 2));
};

9、Q_SIGNAL, Q_SLOT

作用:显式声明信号和槽函数

cpp 复制代码
class MyClass : public QObject {
    Q_OBJECT
public:
    // 等价于: signals: void valueChanged(int);
    Q_SIGNAL void valueChanged(int newValue);
    
    // 等价于: public slots: void setValue(int v);
    Q_SLOT void setValue(int v) { /* ... */ }
};

10、Q_ASSERT, Q_ASSERT_X

cpp 复制代码
void process(int *data) {
    Q_ASSERT(data != nullptr);
    Q_ASSERT_X(data != nullptr, "process", "data不能为nullptr");
}

11、平台检测宏

操作系统检测

cpp 复制代码
#ifdef Q_OS_WIN
    // Windows平台代码
    #include <windows.h>
#elif defined(Q_OS_LINUX)
    // Linux平台代码
    #include <unistd.h>
#elif defined(Q_OS_MACOS)
    // macOS平台代码
    #include <CoreFoundation/CoreFoundation.h>
#endif

编译器检测

cpp 复制代码
#ifdef Q_CC_GNU
    // GCC编译器
    #pragma GCC diagnostic ignored "-Wunused-parameter"
#elif defined(Q_CC_MSVC)
    // MSVC编译器
    #pragma warning(disable: 4100)
#endif

12、类型转换宏

qobject_cast

cpp 复制代码
QObject *obj = new QPushButton;
QPushButton *button = qobject_cast<QPushButton*>(obj);
if (button) {
    // 转换成功
}

qvariant_cast

cpp 复制代码
QVariant var = 42;
int value = qvariant_cast<int>(var);

13、私有实现模式宏

Q_DECLARE_PRIVATE, Q_DECLARE_PUBLIC

cpp 复制代码
// 在公有类中
class MyClass {
    Q_DECLARE_PRIVATE(MyClass)
protected:
    MyClass(MyClassPrivate &dd, QObject *parent = nullptr);
private:
    MyClassPrivate *d_ptr;
};

Q_D, Q_Q

cpp 复制代码
// 在公有类成员函数中
void MyClass::publicMethod() {
    Q_D(MyClass);  // MyClassPrivate * const d = d_func();
    d->privateMethod();
}

// 在私有类成员函数中
void MyClassPrivate::privateMethod() {
    Q_Q(MyClass);  // MyClass * const q = q_func();
    q->publicMethod();
}

14、版本检测宏

QT_VERSION, QT_VERSION_CHECK

cpp 复制代码
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
    // Qt6代码
    QRandomGenerator::global()->bounded(100);
#else
    // Qt5代码
    qrand() % 100;
#endif

15、接口声明宏

Q_INTERFACES

cpp 复制代码
class MyInterface {
public:
    virtual ~MyInterface() {}
    virtual void doSomething() = 0;
};
Q_DECLARE_INTERFACE(MyInterface, "com.example.MyInterface")

class MyClass : public QObject, public MyInterface {
    Q_OBJECT
    Q_INTERFACES(MyInterface)
public:
    void doSomething() override { /* ... */ }
};

16、国际化宏

QT_TR_NOOP, QT_TRANSLATE_NOOP
cpp 复制代码
static const char *greeting = QT_TR_NOOP("Hello World");
static const char *messages[] = {
    QT_TRANSLATE_NOOP("MainWindow", "Open"),
    QT_TRANSLATE_NOOP("MainWindow", "Save"),
};

17、属性绑定宏

Q_MOC_INCLUDE
cpp 复制代码
class MyClass : public QObject {
    Q_OBJECT
    Q_MOC_INCLUDE("mydata.h")
    
    Q_PROPERTY(MyData data READ getData WRITE setData NOTIFY dataChanged)
    // ...
};

18、工具宏

Q_UNLIKELY, Q_LIKELY
cpp 复制代码
if (Q_UNLIKELY(ptr == nullptr)) {
    qCritical() << "空指针";
    return;
}

if (Q_LIKELY(value > 0)) {
    // 大部分情况会执行这里
    process(value);
}

19、资源系统宏

Q_INIT_RESOURCE
cpp 复制代码
int main(int argc, char *argv[]) {
    QApplication app(argc, argv);
    Q_INIT_RESOURCE(myresources);  // 加载myresources.qrc
    // ...
}

20、弃用警告宏

QT_DEPRECATED
cpp 复制代码
QT_DEPRECATED void oldFunction();
QT_DEPRECATED_X("使用newFunction代替") void oldFunction();
QT_DEPRECATED_VERSION_X(6, 0, "使用新API")
void legacyFunction();

21、元对象调用辅助宏

Q_ARG, Q_RETURN_ARG
cpp 复制代码
int result = 0;
bool ok = QMetaObject::invokeMethod(obj, "calculate",
                                    Q_RETURN_ARG(int, result),
                                    Q_ARG(int, 10),
                                    Q_ARG(int, 20));