VS2026+QT6.9运行时描述类QMetaObject::QMetaProperty用法
2026/5/13 15:41:30 网站建设 项目流程

1、简介

QMetaProperty是 Qt 元对象系统里专门用来描述一个 Qt 属性(Q_PROPERTY的类,作用是运行时动态获取 / 修改对象属性、查询属性元信息,是反射的核心之一。
使用Q_PROPERTY宏来定义属性

2、用法

先定义对象属性

// ========== Qt 属性定义(核心) ========== //• QString : 属性的数据类型。 //• username : 属性的名称(在 QML、样式表或反射中使用的名字)。 //• READ getUsername : 读取函数。指定哪个成员函数用于获取该属性的值。这里对应函数 QString name() const; //• WRITE setUsername : 写入函数。指定哪个成员函数用于设置该属性的值。这里对应函数 void setName(const QString& newName); //• NOTIFY nameChanged : 通知信号。当属性值发生改变时,发射这个信号。这主要用于 QML 绑定或与其他对象同步 Q_PROPERTY(QString username READ getUsername WRITE setUsername NOTIFY nameChanged)

打印对象的所有属性

const QMetaObject* mainWin = m_mainWin->metaObject(); for (int i = 0; i < mainWin->propertyCount(); i++) { QMetaProperty prop = mainWin->property(i); // 打印所有属性值 qDebug() << prop.name() << prop.read(m_mainWin); }

运行时获取对象属性/查询,包括类名、位置、大小、鼠标等等信息,也包括定义的属性。简单来说会把祖宗十八代的属性都列出来

3、使用

#include "QtWidgetsApplication3.h" QtWidgetsApplication3::QtWidgetsApplication3(QWidget* parent) : QMainWindow(parent) { ui.setupUi(this); thread = new QThread(this); worker = new Worker(this); // 这里传递主窗口指针 使用元对象系统QMetaObject::invokeMethod worker->moveToThread(thread); connect(thread, &QThread::finished, worker, &QObject::deleteLater); connect(thread, &QThread::finished, thread, &QThread::deleteLater); thread->start(); // 成功修改主线程私有成员的通知 connect(this, &QtWidgetsApplication3::nameChanged, [this](const QString& name) { qDebug() << "主线程私有成员 m_str值修改为:" << name; }); // 子线程读主线程私有成员值 connect(ui.pushButton, &QPushButton::clicked, worker, &Worker::getname); // 子线程写主线程私有成员值 connect(ui.pushButton_2, &QPushButton::clicked, [this]() { worker->setname(ui.lineEdit->text()); }); // property获取属性值 connect(ui.pushButton_3, &QPushButton::clicked, [this]() { QString val = this->property("username").toString(); qDebug() << "property() 获取:" << val; }); // setProperty设置属性值 connect(ui.pushButton_4, &QPushButton::clicked, [this]() { this->setProperty("username", ui.lineEdit->text()); }); } // 析构安全退出兵删除子线程 QtWidgetsApplication3::~QtWidgetsApplication3() { if (thread && thread->isRunning()) { thread->quit(); thread->wait(); thread = nullptr; worker = nullptr; } } // 获取私有成员变量的值 QString QtWidgetsApplication3::getUsername() const { return m_str; } // 设置私有成员变量的值 void QtWidgetsApplication3::setUsername(const QString& name) { if (m_str == name) return; m_str = name; emit nameChanged(name); } // 子线程构造 Worker::Worker(QtWidgetsApplication3* mainWin) { m_mainWin = mainWin; qDebug() << "Worker::Worker()" << QThread::currentThread(); } // 子线程析构 Worker::~Worker() {} // 子线程设置主线程的私有成员值 void Worker::setname(const QString& name) { // 获取username属性位置 QMetaProperty prop = m_mainWin->metaObject()->property( m_mainWin->metaObject()->indexOfProperty("username") ); // 修改属性值 QMetaObject::invokeMethod(m_mainWin, [=]() { prop.write(m_mainWin, name); }, Qt::QueuedConnection); } // 子线程获取主线程的私有成员值 void Worker::getname() { const QMetaObject* mainWin = m_mainWin->metaObject(); for (int i = 0; i < mainWin->propertyCount(); i++) { QMetaProperty prop = mainWin->property(i); // 打印所有属性值 qDebug() << prop.name() << prop.read(m_mainWin); // 找到username属性 保存值到m_str if (QString(prop.name()) == "username") { m_str = prop.read(m_mainWin).toString(); } } qDebug() << "子线程获取到 m_str:" << m_str; }
#pragma once #include <QtWidgets/QMainWindow> #include "ui_QtWidgetsApplication3.h" #include <QThread> #include <QObject> #include <QMetaProperty> class Worker; class QtWidgetsApplication3 : public QMainWindow { Q_OBJECT // ========== Qt 属性定义(核心) ========== //• QString : 属性的数据类型。 //• username : 属性的名称(在 QML、样式表或反射中使用的名字)。 //• READ getUsername : 读取函数。指定哪个成员函数用于获取该属性的值。这里对应函数 QString name() const; //• WRITE setUsername : 写入函数。指定哪个成员函数用于设置该属性的值。这里对应函数 void setName(const QString& newName); //• NOTIFY nameChanged : 通知信号。当属性值发生改变时,发射这个信号。这主要用于 QML 绑定或与其他对象同步 Q_PROPERTY(QString username READ getUsername WRITE setUsername NOTIFY nameChanged) public: QtWidgetsApplication3(QWidget* parent = nullptr); ~QtWidgetsApplication3(); QThread* thread; Worker* worker; // Getter 获取私有成员变量的值(只读访问) 通过 Q_INVOKABLE 修饰符修饰 Q_INVOKABLE QString getUsername() const; public slots: // Setter 修改私有成员变量的值(可写修改) 槽函数slots可以不写 Q_INVOKABLE 修饰符 void setUsername(const QString& name); private: Ui::QtWidgetsApplication3Class ui; QString m_str = "20260512"; signals: // 属性变化通知信号 void nameChanged(const QString& name); }; // 线程类 class Worker : public QObject { Q_OBJECT public: explicit Worker(QtWidgetsApplication3* mainWin); // 这里要接受主窗口的指针 ~Worker(); private: QtWidgetsApplication3* m_mainWin; QString m_str; public slots: void getname(); void setname(const QString& name); // 不加引用每次都复制 加引用传地址效率高 };

运行效果:

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询