QObject Class
QObject 类是所有 Qt 对象的基类。更多内容...
注意:该类中的所有函数均为可重入的。
注意:以下函数也是线程安全的:
- connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
- connect(const QObject *sender, const char *signal, const char *method, Qt::ConnectionType type) const
- connect(const QObject *sender, PointerToMemberFunction signal, const QObject *receiver, PointerToMemberFunction method, Qt::ConnectionType type)
- connect(const QObject *sender, PointerToMemberFunction signal, Functor functor)
- connect(const QObject *sender, 成员函数指针 signal, const QObject *context, 函数对象 functor, Qt::ConnectionType type)
- disconnect(const QObject *sender, const char *signal, const QObject *receiver, const char *method)
- disconnect(const char *信号, const QObject *接收者, const char *方法) const
- disconnect(const QObject *sender, PointerToMemberFunction signal, const QObject *receiver, PointerToMemberFunction method)
- deleteLater()
属性
- objectName : QString
公共函数
| QObject(QObject *parent = nullptr) | |
| virtual | ~QObject() |
| QBindable<QString> | bindableObjectName() |
| bool | blockSignals(bool block) |
| const QObjectList & | children() const |
| QMetaObject::Connection | connect(const QObject *sender, const char *signal, const char *method, Qt::ConnectionType type = Qt::AutoConnection) const |
| bool | disconnect(const QObject *receiver, const char *method = nullptr) const |
| bool | disconnect(const char *signal = nullptr, const QObject *receiver = nullptr, const char *method = nullptr) const |
| void | dumpObjectInfo() const |
| void | dumpObjectTree() const |
| QList<QByteArray> | dynamicPropertyNames() const |
| virtual bool | event(QEvent *e) |
| virtual bool | eventFilter(QObject *watched, QEvent *event) |
| T | findChild(QAnyStringView name, Qt::FindChildOptions options = Qt::FindChildrenRecursively) const |
(since 6.7) T | findChild(Qt::FindChildOptions options = Qt::FindChildrenRecursively) const |
| QList<T> | findChildren(QAnyStringView name, Qt::FindChildOptions options = Qt::FindChildrenRecursively) const |
(since 6.3) QList<T> | findChildren(Qt::FindChildOptions options = Qt::FindChildrenRecursively) const |
| QList<T> | findChildren(const QRegularExpression &re, Qt::FindChildOptions options = Qt::FindChildrenRecursively) const |
| bool | inherits(const char *className) const |
| void | installEventFilter(QObject *filterObj) |
(since 6.11) bool | isQmlExposed() const |
(since 6.4) bool | isQuickItemType() const |
| bool | isWidgetType() const |
| bool | isWindowType() const |
| void | killTimer(int id) |
(since 6.8) void | killTimer(Qt::TimerId id) |
| virtual const QMetaObject * | metaObject() const |
| bool | moveToThread(QThread *targetThread) |
| QString | objectName() const |
| QObject * | parent() const |
| QVariant | property(const char *name) const |
| void | removeEventFilter(QObject *obj) |
| void | setObjectName(const QString &name) |
(since 6.4) void | setObjectName(QAnyStringView name) |
| void | setParent(QObject *parent) |
| bool | setProperty(const char *name, const QVariant &value) |
(since 6.6) bool | setProperty(const char *name, QVariant &&value) |
| bool | signalsBlocked() const |
| int | startTimer(int interval, Qt::TimerType timerType = Qt::CoarseTimer) |
| int | startTimer(std::chrono::nanoseconds interval, Qt::TimerType timerType = Qt::CoarseTimer) |
| QThread * | thread() const |
公共槽位
| void | deleteLater() |
信号
| void | destroyed(QObject *obj = nullptr) |
| void | objectNameChanged(const QString &objectName) |
静态公共成员
| QMetaObject::Connection | connect(const QObject *sender, const QMetaMethod &signal, const QObject *receiver, const QMetaMethod &method, Qt::ConnectionType type = Qt::AutoConnection) |
| QMetaObject::Connection | connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type = Qt::AutoConnection) |
| QMetaObject::Connection | connect(const QObject *sender, PointerToMemberFunction signal, Functor functor) |
| QMetaObject::Connection | connect(const QObject *sender, PointerToMemberFunction signal, const QObject *context, Functor functor, Qt::ConnectionType type = Qt::AutoConnection) |
| QMetaObject::Connection | connect(const QObject *sender, PointerToMemberFunction signal, const QObject *receiver, PointerToMemberFunction method, Qt::ConnectionType type = Qt::AutoConnection) |
(since 6.12) bool | disconnect(QMetaObject::Connection &connection) |
(since 6.12) bool | disconnect(QMetaObject::Connection &&connection) |
| bool | disconnect(const QMetaObject::Connection &connection) |
| bool | disconnect(const QObject *sender, const QMetaMethod &signal, const QObject *receiver, const QMetaMethod &method) |
| bool | disconnect(const QObject *sender, const char *signal, const QObject *receiver, const char *method) |
| bool | disconnect(const QObject *sender, PointerToMemberFunction signal, const QObject *receiver, PointerToMemberFunction method) |
| const QMetaObject | staticMetaObject |
| QString | tr(const char *sourceText, const char *disambiguation = nullptr, int n = -1) |
受保护的函数
| virtual void | childEvent(QChildEvent *event) |
| virtual void | connectNotify(const QMetaMethod &signal) |
| virtual void | customEvent(QEvent *event) |
| virtual void | disconnectNotify(const QMetaMethod &signal) |
| bool | isSignalConnected(const QMetaMethod &signal) const |
| int | receivers(const char *signal) const |
| QObject * | sender() const |
| int | senderSignalIndex() const |
| virtual void | timerEvent(QTimerEvent *event) |
相关非成员
| QObjectList | |
(since 6.8) enum class | TimerId { Invalid } |
| T | qobject_cast(QObject *object) |
| T | qobject_cast(const QObject *object) |
宏
(since 6.7) | QT_NO_CONTEXTLESS_CONNECT |
(since 6.12) | QT_NO_DISCONNECT_CONST_CONNECTION |
| QT_NO_NARROWING_CONVERSIONS_IN_CONNECT | |
| Q_CLASSINFO(Name, Value) | |
| Q_EMIT | |
| Q_ENUM(...) | |
| Q_ENUM_NS(...) | |
| Q_FLAG(...) | |
| Q_FLAG_NS(...) | |
| Q_GADGET | |
(since 6.3) | Q_GADGET_EXPORT(EXPORT_MACRO) |
| Q_INTERFACES(...) | |
| Q_INVOKABLE | |
(since 6.0) | Q_MOC_INCLUDE |
| Q_NAMESPACE | |
| Q_NAMESPACE_EXPORT(EXPORT_MACRO) | |
| Q_OBJECT | |
| Q_PROPERTY(...) | |
| Q_REVISION | |
| Q_SET_OBJECT_NAME(Object) | |
| Q_SIGNAL | |
| Q_SIGNALS | |
| Q_SLOT | |
| Q_SLOTS |
详细说明
QObject 是 Qt对象模型的核心。该模型的核心特性是一种名为“信号与槽”的、用于实现无缝对象通信的强大机制。 您可以使用 `connect()` 将信号连接到槽,并使用 `disconnect()` 断开连接。为避免无休止的通知循环,您可以使用 `blockSignals()` 暂时阻塞信号。受保护函数 `connectNotify()` 和 `disconnectNotify()` 使得追踪连接成为可能。
QObject 对象以对象树的形式组织。当您创建一个以另一个对象为父对象的 QObject 时,该对象会自动将自身添加到父对象的children() 列表中。 父对象将拥有该对象的所有权;也就是说,它会在其析构函数中自动删除其子对象。您可以使用findChild() 或findChildren() 按名称(可选按类型)查找对象。
每个对象都具有objectName()方法,其类名可通过相应的metaObject()方法获取(参见QMetaObject::className())。您可以使用inherits()函数来判断该对象的类是否继承了QObject继承层次结构中的另一个类。
当对象被删除时,它会发出一个destroyed()信号。您可以捕获此信号,以避免对QObject的悬空引用。
QObject 可以通过event() 接收事件,并过滤其他对象的事件。详情请参阅installEventFilter() 和eventFilter()。可以重写便捷处理函数childEvent() 来捕获子对象的事件。
最后但同样重要的是,QObject 在 Qt 中提供了基本的定时器支持;有关定时器的高级支持,请参阅QChronoTimer 。
请注意,对于任何实现信号、槽或属性的对象,Q_OBJECT 宏都是强制要求的。您还需要对源文件运行Meta-Object Compiler。 我们强烈建议在所有 QObject 的子类中使用此宏,无论它们是否实际使用信号、槽和属性,因为如果不这样做,可能会导致某些函数表现出异常行为。
所有 Qt 控件都继承自 QObject。便捷函数isWidgetType() 可返回该对象是否确实为控件。其运行速度远快于qobject_cast<QWidget *>(obj) 或obj->inherits("QWidget")。
某些 QObject 函数(例如children())会返回一个QObjectList 。QObjectList 是QList<QObject *> 的 typedef 定义。
线程亲和性
一个 QObject 实例被认为具有线程亲和性,或者说它存在于某个特定的线程中。当一个 QObject 接收一个queued signal 或一个已发布的事件时,该槽或事件处理程序将在该对象所在的线程中运行。
注意:如果 一个 QObject 没有线程亲和性(即thread() 返回零),或者它所在的线程中没有正在运行的事件循环,那么它就无法接收队列中的信号或已发布的事件。
默认情况下,QObject 位于其被创建的线程中。可以通过thread() 查询对象的线程亲和性,并通过moveToThread() 对其进行更改。
所有 QObject 都必须与其父对象位于同一个线程中。因此:
- setParent如果涉及的两个 QObject 位于不同的线程中,() 将失败。
- 当一个 QObject 被移动到另一个线程时,其所有子对象也会自动被移动。
- moveToThread如果该 QObject 有父对象,() 将失败。
- 如果 QObject 在 `QThread::run()` 中创建,则它们无法成为 `QThread ` 对象的子对象,因为 `QThread ` 并不位于调用 `QThread::run()` 的线程中。
注意:QObject的 成员变量不会自动成为其子对象 。必须通过传递指向子对象constructor 的指针,或者调用setParent()来建立父子关系。如果不执行此步骤,在调用moveToThread()时,该对象的成员变量将保留在旧线程中。
无复制构造函数或赋值运算符
QObject 既没有复制构造函数,也没有赋值运算符。这是设计使然。 实际上,它们已被声明,但位于使用宏Q_DISABLE_COPY() 的private 部分中。事实上,所有从 QObject 派生(直接或间接)的 Qt 类都使用此宏将它们的复制构造函数和赋值运算符声明为私有。其理由可在 Qt对象模型页面中关于“身份与值”的讨论中找到。
主要后果是:在原本可能倾向于将 QObject 子类作为值使用的地方,你应该改用指向 QObject(或你的 QObject 子类)的指针。例如,如果没有复制构造函数,你就无法将 QObject 的子类作为值存储在容器类中。 你必须存储指针。
自动连接
Qt的元对象系统提供了一种机制,可自动连接QObject子类及其子类之间的信号和槽。只要对象使用适当的名称定义,且槽遵循简单的命名约定,QMetaObject::connectSlotsByName()函数即可在运行时完成此连接。
uic生成的代码会调用此函数,从而在由 Qt Widgets Designer。有关如何在应用程序中使用自动连接的 Qt Widgets Designer Qt Widgets Designer 的更多信息,请参阅 Qt Widgets Designer 手册中“在您的应用程序中使用 xml-ph-0000@deepl.internal UI 文件”一节中。
动态属性
动态属性可在运行时向 QObject 实例添加或从其中移除。动态属性无需在编译时声明,但它们具有与静态属性相同的优势,且使用相同的 API 进行操作——使用property() 读取属性,使用setProperty() 写入属性。
动态属性受以下内容支持: Qt Widgets Designer,无论是标准的 Qt Widgets 控件还是用户创建的表单,均可赋予动态属性。
国际化(I18n)
所有 QObject 子类都支持 Qt 的翻译功能,从而能够将应用程序的用户界面翻译成不同的语言。
另请参阅 QMetaObject 、QPointer 、QObjectCleanupHandler 、Q_DISABLE_COPY() 以及“对象树与所有权”。
属性文档
[bindable] objectName : QString
注意:此 属性支持QProperty 绑定。
该属性保存此对象的名称
您可以使用findChild()按名称(和类型)查找对象。您还可以使用findChildren()查找一组对象。
qDebug("MyClass::setPrecision(): (%s) 精度 %f 无效",
qPrintable(objectName()), newPrecision);默认情况下,此属性包含一个空字符串。
访问函数:
| QString | objectName() const |
| void | setObjectName(const QString &name) |
| void | setObjectName(QAnyStringView name) |
通知信号:
| void | objectNameChanged(const QString &objectName) | [see note below] |
注意:这是一个 私有信号。它可在信号连接中使用,但用户无法触发该信号。
另请参阅 metaObject() 和QMetaObject::className()。
成员函数文档
[explicit invokable] QObject::QObject(QObject *parent = nullptr)
创建一个父对象为parent 的对象。
对象的父对象可视为该对象的所有者。例如,dialog box 是其包含的OK 和Cancel 按钮的父对象。
父对象的析构函数会销毁所有子对象。
将 `parent ` 设置为 `nullptr ` 将创建一个没有父对象的对象。如果该对象是小部件,它将成为顶级窗口。
注意: 可通过元对象系统和 QML 调用此 函数。参见Q_INVOKABLE 。
另请参阅 parent()、findChild() 和findChildren()。
[virtual noexcept] QObject::~QObject()
销毁该对象,并删除其所有子对象。
该对象的所有信号收发都会自动断开,且该对象所有待处理的已发布事件都会从事件队列中移除。不过,通常使用 `deleteLater()` 比直接删除 `QObject ` 的子类更为安全。
警告:所有 子对象都将被删除。如果这些对象中有任何一个位于栈上或为全局对象,您的程序迟早会崩溃。我们不建议在父对象外部持有指向子对象的指针。如果您仍要这样做,destroyed() 信号可让您检测到对象何时被销毁。
警告: 在 `QObject ` 正在处理已投递给它的事件时将其删除 ,可能会导致程序崩溃。如果 `QObject ` 存在于与当前执行线程不同的线程中,则绝不能直接删除它。请改用 `deleteLater()`,该函数会使事件循环在所有待处理事件均已投递完毕后删除该对象。
另请参阅 deleteLater()。
[noexcept] bool QObject::blockSignals(bool block)
如果 `block ` 为真,则该对象发出的信号将被阻塞(即,发出信号不会触发任何与其关联的处理程序)。如果 `block ` 为假,则不会发生此类阻塞。
返回值为signalsBlocked() 的上一次值。
请注意,即使该对象的信号已被阻塞,destroyed() 信号仍会被发出。
在被阻塞期间发出的信号不会被缓冲。
另请参阅 signalsBlocked() 和QSignalBlocker 。
[virtual protected] void QObject::childEvent(QChildEvent *event)
可以在子类中重写此事件处理程序,以接收子节点事件。该事件通过event 参数传递进来。
QEvent::ChildAdded 当子对象被添加或移除时,系统会向对象发送QEvent::ChildRemoved 事件。在这两种情况下,您只能假设该子对象是QObject ,或者当isWidgetType()返回true 时,该子对象是QWidget 。(这是因为,在ChildAdded 的情况下,子对象尚未完全构造完成;而在ChildRemoved 的情况下,它可能已被销毁。)
QEvent::ChildPolished 当子控件完成“polished”操作,或已“polished”的子控件被添加时,事件会发送给控件。若收到子控件的“polished”事件,通常表示该子控件的构建已完成。但这并非绝对保证,在控件构造函数执行期间,可能会收到多个“polished”事件。
对于每个子控件,你会收到一个 `ChildAdded ` 事件、零个或多个 `ChildPolished ` 事件,以及一个 `ChildRemoved ` 事件。
如果子控件在添加后立即被移除,则会省略ChildPolished 事件。如果子控件在构造和销毁过程中被多次polished,您可能会收到针对同一子控件的多个childpolished事件,每次事件对应的虚拟表都不同。
另请参阅 event()。
const QObjectList &QObject::children() const
返回一个子对象列表。QObjectList 类在头文件<QObject> 中定义如下:
typedef QList<QObject*> QObjectList;列表中第一个添加的子对象是 `first ` 对象,最后一个添加的子对象是 `last ` 对象,即新添加的子对象会被追加到列表末尾。
请注意,当QWidget 的子项为raised 或lowered 时,列表顺序会发生变化。被提升的小部件将成为列表中的最后一个对象,而被降低的小部件将成为列表中的第一个对象。
另请参阅 findChild()、findChildren()、parent() 以及setParent()。
[static] QMetaObject::Connection QObject::connect(const QObject *sender, const QMetaMethod &signal, const QObject *receiver, const QMetaMethod &method, Qt::ConnectionType type = Qt::AutoConnection)
创建从sender 对象中的signal 到receiver 对象中的method 的连接,该连接基于给定的type 。返回该连接的句柄,该句柄可用于稍后断开连接。
如果无法建立连接(例如参数无效),则该连接句柄将失效。您可以通过将其强制转换为 bool 类型来检查QMetaObject::Connection 是否有效。
该函数的工作方式与 `connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type) ` 相同,但使用 `QMetaMethod ` 来指定信号和方法。
另请参阅 connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)。
[static] QMetaObject::Connection QObject::connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type = Qt::AutoConnection)
创建一个连接,将sender 对象中的signal 中的给定type 与receiver 对象中的method 连接起来。返回该连接的句柄,该句柄可用于稍后断开连接。
在指定 `signal ` 和 `method` 时,必须使用 `SIGNAL() ` 和 `SLOT() ` 宏,例如:
QLabel *label = new QLabel;
QScrollBar *scrollBar = new QScrollBar;
QObject::connect(scrollBar, SIGNAL(valueChanged(int)),
label, SLOT(setNum(int)));此示例确保标签始终显示当前滚动条的数值。请注意,信号和插槽参数中不得包含任何变量名,只能指定类型。例如,以下代码将无法正常工作并返回 false:
// WRONG
QObject::connect(scrollBar, SIGNAL(valueChanged(int value)),
label, SLOT(setNum(int value)));信号还可以连接到另一个信号:
class MyWidget : public QWidget
{
Q_OBJECT
public:
MyWidget();
signals:
void buttonClicked();
private:
QPushButton *myButton;
};
MyWidget::MyWidget()
{
myButton = new QPushButton(this);
connect(myButton, SIGNAL(clicked()),
this, SIGNAL(buttonClicked()));
}在此示例中,MyWidget 构造函数转发来自私有成员变量的信号,并使其以与MyWidget 相关的名称提供。
一个信号可以连接到多个插槽和信号。一个插槽也可以连接到多个信号。
如果一个信号连接到多个槽,则当该信号被发出时,这些槽将按照建立连接时的顺序依次被激活。
如果该函数成功将信号连接到插槽,则返回一个QMetaObject::Connection ,该对象表示连接的句柄。如果无法建立连接,例如QObject 无法验证signal 或method 是否存在,或者它们的签名不兼容,则该连接句柄将无效。您可以通过将其强制转换为bool类型来检查句柄是否有效。
默认情况下,每次建立连接时都会触发一个信号;若建立重复连接,则会触发两个信号。您可以通过一次disconnect()调用断开所有这些连接。 若传入Qt::UniqueConnection type ,则仅当连接非重复时才会建立。若已存在重复连接(即对同一对象上完全相同的信号与完全相同的槽的连接),则连接将失败,且connect将返回一个无效的QMetaObject::Connection 。
注意:Qt ::UniqueConnections 不适用于 lambda 表达式、非成员函数和 functor;它们仅适用于连接成员函数。
可选参数type 用于描述要建立的连接类型。具体而言,它决定了特定信号是立即传递给槽,还是被排队以便稍后传递。 如果信号被排队,参数的类型必须是 Qt 元对象系统所认知的,因为 Qt 需要在后台将参数复制并存储到事件中。如果您尝试使用排队连接并收到错误信息
QObject::connect: Cannot queue arguments of type 'MyType'
(Make sure 'MyType' is registered using qRegisterMetaType().)请在建立连接之前调用 `qRegisterMetaType()` 来注册该数据类型。
注意:此函数是线程安全的。
另请参阅 disconnect()、sender()、qRegisterMetaType()、Q_DECLARE_METATYPE()以及“基于字符串的连接与基于函子的连接之间的区别”。
[static] template <typename PointerToMemberFunction, typename Functor> QMetaObject::Connection QObject::connect(const QObject *sender, PointerToMemberFunction signal, Functor functor)
在sender 对象中,从signal 建立到functor 的连接,并返回该连接的句柄
该信号必须是在头文件中作为信号声明的函数。槽函数可以是任何能够与该信号连接的函数或 functor。如果信号的参数个数至少与槽函数的参数个数相同,则槽函数即可与该信号连接。信号和槽中对应参数的类型之间必须存在隐式转换。
示例:
void someFunction();
//...
void someOtherFunction()
{
QPushButton *button = new QPushButton;
QObject::connect(button, &QPushButton::clicked, someFunction);
}也可以使用 lambda 表达式:
QByteArray page = "...";
QTcpSocket *socket = new QTcpSocket;
socket->connectToHost("qt-project.org", 80);
QObject::connect(socket, &QTcpSocket::connected, [=] () {
socket->write("GET " + page + "\r\n");
});如果发送者被销毁,连接将自动断开。但是,您应确保在发出信号时,函数对象内部使用的任何对象仍然存活。
因此,建议使用那个同时将QObject 作为接收者/上下文的connect()重载。可以通过定义QT_NO_CONTEXTLESS_CONNECT 宏来禁用无上下文的重载。
可以借助 `qOverload` 来解析重载函数。
此函数重载了 `QObject::connect()`。
注意:此函数是线程安全的。
QMetaObject::Connection QObject::connect(const QObject *sender, const char *signal, const char *method, Qt::ConnectionType type = Qt::AutoConnection) const
将sender 对象中的signal 连接到该对象的method 。
等同于 connect(sender,signal,this,method,type)。
每次建立连接都会触发一个信号,因此重复建立连接会触发两个信号。您可以使用disconnect() 断开连接。
该函数重载了QObject::connect()。
注意:此函数是线程安全的。
另请参阅 disconnect()。
[static] template <typename PointerToMemberFunction, typename Functor> QMetaObject::Connection QObject::connect(const QObject *sender, PointerToMemberFunction signal, const QObject *context, Functor functor, Qt::ConnectionType type = Qt::AutoConnection)
创建一个连接,将sender 对象中signal 的type 连接到functor ,并将其放置在context 的特定事件循环中,同时返回该连接的句柄。
注意:Qt ::UniqueConnections 不适用于 lambda 表达式、非成员函数和函数对象;它们仅适用于连接到成员函数。
信号必须是在头文件中作为信号声明的函数。槽函数可以是任何能够与该信号连接的函数或函子。如果信号的参数个数至少与槽函数的参数个数相同,则该槽函数即可连接到该信号。信号和槽中对应参数的类型之间必须存在隐式转换。
示例:
void someFunction();
//...
void someOtherFunction()
{
QPushButton *button = new QPushButton;
QObject::connect(button, &QPushButton::clicked, this, someFunction, Qt::QueuedConnection);
}也可以使用 lambda 表达式:
QByteArray page = "...";
QTcpSocket *socket = new QTcpSocket;
socket->connectToHost("qt-project.org", 80);
QObject::connect(socket, &QTcpSocket::connected, this, [=] () {
socket->write("GET " + page + "\r\n");
}, Qt::AutoConnection);如果发送者或上下文被销毁,连接将自动断开。但是,应确保在信号被触发时,函子内部使用的任何对象仍然存在。
可以借助 `qOverload` 来解析重载函数。
此函数重载了 `QObject::connect()`。
注意:此函数是线程安全的。
[static] template <typename PointerToMemberFunction> QMetaObject::Connection QObject::connect(const QObject *sender, PointerToMemberFunction signal, const QObject *receiver, PointerToMemberFunction method, Qt::ConnectionType type = Qt::AutoConnection)
创建从sender 对象中的signal 到receiver 对象中的method 的连接,该连接基于给定的type 。返回该连接的句柄,该句柄可用于日后断开连接。
该信号必须是在头文件中作为信号声明的函数。槽函数可以是任何能够与该信号连接的成员函数。如果信号的参数个数至少与槽函数的参数个数相同,且信号与槽函数中对应参数的类型之间存在隐式转换,则该槽函数即可与该信号建立连接。
示例:
QLabel *label = new QLabel;
QLineEdit *lineEdit = new QLineEdit;
QObject::connect(lineEdit, &QLineEdit::textChanged,
label, &QLabel::setText);此示例确保标签始终显示当前行编辑框中的文本。
一个信号可以连接到多个槽和信号。一个槽可以连接到多个信号。
如果一个信号连接到多个槽,则当信号被触发时,这些槽将按照连接建立时的顺序依次被激活
如果函数成功将信号连接到插槽,则返回一个连接句柄。如果无法建立连接(例如,当QObject 无法验证signal 是否存在时——若该信号未被声明为信号),则该连接句柄将无效。您可以通过将其强制转换为bool类型来检查QMetaObject::Connection 是否有效。
默认情况下,每次建立连接都会触发一个信号;若建立重复连接,则会触发两个信号。您可以通过一次disconnect() 调用断开所有这些连接。 若将 `Qt::UniqueConnection ` 作为 `type` 参数传入,则仅当连接非重复时才会建立。若已存在重复连接(即对同一对象上完全相同的槽发送完全相同的信号),连接将失败,且 `connect` 会返回一个无效的 `QMetaObject::Connection`。
可选参数type 用于描述要建立的连接类型。具体而言,它决定特定信号是立即传递给槽,还是被排队以供稍后传递。 如果信号被排队,参数的类型必须是 Qt 元对象系统所识别的,因为 Qt 需要在后台将参数复制并存储到事件中。如果您尝试使用排队连接却收到错误信息
QObject::connect: Cannot queue arguments of type 'MyType'
(Make sure 'MyType' is registered using qRegisterMetaType().)请确保使用Q_DECLARE_METATYPE
可以借助qOverload 来解析重载函数。
该函数重载了QObject::connect()。
注意:此函数是线程安全的。
另请参阅 “基于字符串的连接与基于函子的连接之间的区别”。
[virtual protected] void QObject::connectNotify(const QMetaMethod &signal)
当有对象连接到该对象的signal 时,将调用此虚拟函数。
若要将signal 与特定信号进行比较,可按如下方式使用QMetaMethod::fromSignal():
if (signal == QMetaMethod::fromSignal(&MyObject::valueChanged)) {
// signal is valueChanged
}警告:此 函数违反了面向对象的模块化原则。不过,当您仅需在信号被连接时才执行耗时操作时,它可能会派上用场。
警告:此 函数由执行连接操作的线程调用,该线程可能与本对象所在的线程不同。此外,此函数还可能在QObject 内部互斥锁被锁定时被调用。因此,不允许从您的重写实现中再次进入任何QObject 函数,包括isSignalConnected()。 如果您在重写中锁定了一个互斥量,请确保不要在其他地方持有该互斥量的情况下调用QObject 函数,否则将导致死锁。
另请参阅 connect() 和disconnectNotify()。
[virtual protected] void QObject::customEvent(QEvent *event)
可以在子类中重写此事件处理程序以接收自定义事件。自定义事件是由用户定义的事件,其类型值至少与QEvent::Type 枚举中的QEvent::User 项一样大,通常是QEvent 的子类。该事件通过event 参数传递进来。
[slot] void QObject::deleteLater()
将此对象排入删除队列。
当控制权返回事件循环时,该对象将被删除。如果在调用此函数时事件循环未运行(例如,在调用QCoreApplication::exec()之前对某个对象调用了deleteLater()),则该对象将在事件循环启动后被删除。 如果在主事件循环停止后调用 deleteLater(),则该对象不会被删除。如果对位于没有运行中事件循环的线程中的对象调用 deleteLater(),则该对象将在线程结束时被销毁。
在QThread 中使用工作者QObject 时,一种常见的模式是将线程的finished() 信号连接到工作者的deleteLater() 槽,以确保其被安全删除:
请注意,进入或离开一个新的事件循环(例如通过打开模态对话框)并不会执行延迟删除;要使对象被删除,控制权必须返回至最初调用 deleteLater() 的那个事件循环。 这不适用于在先前嵌套事件循环仍在运行时被删除的对象:Qt 事件循环会在新的嵌套事件循环开始时立即删除这些对象。
在 Qt 未通过 `QCoreApplication::exec()` 或 `QEventLoop::exec()` 等方式驱动事件分发器的情况下,延迟删除操作不会自动处理。为确保在此场景下执行延迟删除,可采用以下变通方案:
const auto *eventDispatcher = QThread::currentThread()->eventDispatcher();
QObject::connect(eventDispatcher, &QAbstractEventDispatcher::aboutToBlock,
QThread::currentThread(), []{
if (QThread::currentThread()->loopLevel() == 0)
QCoreApplication::sendPostedEvents(nullptr, QEvent::DeferredDelete);
}
);注意:此函数是线程安全的。
[signal] void QObject::destroyed(QObject *obj = nullptr)
该信号在对象obj 被销毁之前立即发出,且在所有QPointer 的实例均已收到通知之后,并且无法被阻塞。
该信号发出后,该对象的所有子对象将立即被销毁。
另请参阅 deleteLater() 和QPointer 。
[static, since 6.12] bool QObject::disconnect(QMetaObject::Connection &connection)
[static, since 6.12] bool QObject::disconnect(QMetaObject::Connection &&connection)
断开连接。
如果 `connection ` 为 `invalid ` 或已断开连接,则不执行任何操作并返回 `false`。
注意:在 Qt 6.12 之前的版本中,此函数仅接受const-& 作为参数。
这些函数是在 Qt 6.12 中引入的。
另请参阅 connect()。
[static] bool QObject::disconnect(const QMetaObject::Connection &connection)
断开connection 连接,并将其重置为invalid 。
如果connection 无效或已被断开连接,则不执行任何操作并返回 false。
注意: Qt的未来 版本在此处可能仅接受非 const 对象。
另请参阅 QT_NO_DISCONNECT_CONST_CONNECTION 和connect()。
[static] bool QObject::disconnect(const QObject *sender, const QMetaMethod &signal, const QObject *receiver, const QMetaMethod &method)
断开对象sender 中signal 与对象receiver 中method 之间的连接。若连接成功断开,则返回true ;否则返回false 。
该函数提供的功能与disconnect(const QObject *sender, const char *signal, const QObject *receiver, const char *method) 相同,但使用QMetaMethod 来表示待断开的信号及其对应的方法。
此外,在以下情况下,该函数将返回 false,且不会断开任何信号和插槽:
- signal 该信号并非发送者类的成员,也不是其父类之一的成员。
- method 不是接收者类或其父类之一的成员。
- signal instance 代表的不是信号。
注意: 在connect() 和相应的 disconnect() 调用中,请使用与 SIGNAL 和SLOT 宏相同的语法,即成员函数指针或基于字符串的语法。
为避免不匹配,请保存connect() 返回的连接句柄,并在调用disconnect() 时使用它。
注意:如果 queued connection 被断开,已排程的事件仍可能被传递,导致连接断开后接收器仍被调用。
QMetaMethod() 可作为通配符,表示“任何信号”或“接收对象中的任何槽”。同样地,nullptr 也可用于receiver ,表示“任何接收对象”。在这种情况下,方法也应为 QMetaMethod()。sender 参数绝不能是nullptr 。
注意:断开 所有信号-插槽连接也会断开QObject::destroyed()信号(如果该信号已连接)。此操作可能会对依赖该信号进行资源清理的类产生不利影响。建议仅断开由应用程序代码连接的特定信号。
另请参阅 disconnect(const QObject *sender, const char *signal, const QObject *receiver, const char *method)。
[static] bool QObject::disconnect(const QObject *sender, const char *signal, const QObject *receiver, const char *method)
断开对象sender 中signal 与对象receiver 中method 之间的连接。如果连接成功断开,则返回true ;否则返回false 。
当涉及的任一对象被销毁时,信号-槽连接即被解除。
如下例所示,disconnect() 通常有三种用法。
- 断开与对象信号关联的所有连接:
QObject::disconnect(myObject, nullptr, nullptr, nullptr);等同于非静态重载函数
myObject->disconnect(); - 断开与特定信号相关的所有连接:
QObject::disconnect(myObject, SIGNAL(mySignal()), nullptr, nullptr);等同于非静态重载函数
myObject->disconnect(SIGNAL(mySignal())); - 断开特定接收器的连接:
QObject::disconnect(myObject, nullptr, myReceiver, nullptr);等同于非静态重载函数
myObject->disconnect(myReceiver);
注意: 在connect()和相应的disconnect()调用中,请使用与 SIGNAL 和SLOT 宏相同的语法,即成员函数指针或基于字符串的形式。
为避免不匹配,请保存connect() 返回的连接句柄,并在调用disconnect() 时使用该句柄。
注意:如果 queued connection 被断开,已排程的事件仍可能被传递,导致在连接断开后仍会调用接收器。
nullptr 可作为通配符使用,分别表示“任何信号”、“任何接收对象”或“接收对象中的任何槽”。
sender 绝不能是nullptr 。(您无法在单次调用中断开多个对象的信号连接。)
如果 `signal ` 为 `nullptr`,则会将 `receiver ` 和 `method ` 从所有信号中断开连接。否则,仅指定信号会被断开。
如果receiver 为nullptr ,则会断开与signal 连接的所有内容。否则,除receiver 以外的其他对象中的槽将不会被断开。
若method 为nullptr ,则会断开所有连接到receiver 的信号。否则,仅会断开名为method 的槽,其他所有槽均保持不变。若省略receiver ,则method 必须为nullptr ,因此无法断开所有对象上特定名称的槽。
注意:断开 所有信号-插槽连接也会断开QObject::destroyed()信号(如果该信号已连接)。此操作可能会对依赖该信号来清理资源的类产生不利影响。建议仅断开由应用程序代码连接的特定信号。
注意:此函数是线程安全的。
另请参阅 connect()。
bool QObject::disconnect(const QObject *receiver, const char *method = nullptr) const
将该对象中的所有信号与receiver 的method 断开连接。
注意: 在调用connect()及相应的disconnect()时,请使用 与SIGNAL 和SLOT 宏相同的语法,即成员函数指针或字符串形式。
为避免不匹配,请保存connect() 返回的连接句柄,并在调用disconnect() 时使用该句柄。
注意:如果 queued connection 被断开,已排程的事件仍可能被传递,导致连接断开后接收器仍被调用。
当涉及的任一对象被销毁时,信号-插槽连接将被删除。
此函数重载了QObject::disconnect() 函数。
bool QObject::disconnect(const char *signal = nullptr, const QObject *receiver = nullptr, const char *method = nullptr) const
将signal 从receiver 中的method 移除。
注意: 在connect() 函数及相应的 disconnect() 调用中,请使用与 SIGNAL 和SLOT 宏相同的语法(即成员函数指针或基于字符串的语法)。
为避免不匹配,请保存connect() 返回的连接句柄,并在调用disconnect() 时使用该句柄。
注意:如果 queued connection 被断开连接,已排程的事件仍可能被传递,导致连接断开后接收器仍被调用。
当涉及的任一对象被销毁时,信号-插槽连接将被移除。
注意: 如果QObject::destroyed()信号已连接,断开 所有信号-槽连接也会断开该信号。这样做可能会对依赖该信号清理资源的类产生不利影响。建议仅断开由应用程序代码连接的特定信号。
此函数重载了QObject::disconnect()。
注意:此函数是线程安全的。
[static] template <typename PointerToMemberFunction> bool QObject::disconnect(const QObject *sender, PointerToMemberFunction signal, const QObject *receiver, PointerToMemberFunction method)
断开对象sender 中signal 与对象receiver 中method 之间的连接。若连接成功断开,则返回true ;否则返回false 。
当参与信号-插槽连接的任一对象被销毁时,该连接即被解除。
如下例所示,disconnect() 通常有三种用法。
- 断开与对象信号相关联的所有连接:
QObject::disconnect(myObject, nullptr, nullptr, nullptr); - 断开与特定信号关联的所有连接:
QObject::disconnect(myObject, &MyObject::mySignal, nullptr, nullptr); - 断开与特定接收器的连接:
QObject::disconnect(myObject, nullptr, myReceiver, nullptr); - 断开某个特定信号与某个特定插槽之间的连接:
nullptr 可作为通配符使用,分别表示“任何信号”、“任何接收对象”或“接收对象中的任何插槽”。
sender 绝不能是nullptr 。(您无法在单次调用中将信号从多个对象上断开。)
如果signal 为nullptr ,则会将receiver 和method 从所有信号中断开。否则,仅断开指定的信号。
如果receiver 是nullptr ,则会断开与signal 连接的所有内容。否则,仅断开指定接收器中的槽。当disconnect()的receiver 不为空时,也会断开那些以receiver 作为上下文对象连接的槽函数。
如果method 为nullptr ,则会断开所有连接到receiver 的内容。否则,仅会断开名为method 的槽,其余所有槽均保持不变。若省略receiver ,则method 必须为nullptr ,因此无法对所有对象上的特定名称槽进行断开操作。
注意:无法 使用此重载来断开连接到函子或lambda表达式的信号。这是因为无法对它们进行比较。请改用接受QMetaObject::Connection 的那个重载。
注意:除非 `method ` 是 `nullptr`,否则该函数也不会断开使用字符串版本的 `connect()` 建立的连接。要断开此类连接,请使用 `disconnect()` 的相应字符串版本重载。
此函数重载了QObject::disconnect()。
注意:此函数是线程安全的。
另请参阅 connect()。
[virtual protected] void QObject::disconnectNotify(const QMetaMethod &signal)
当该对象中的signal 发生断开连接时,会调用此虚拟函数。
有关如何将signal 与特定信号进行比较的示例,请参阅connectNotify()。
如果所有信号都已从该对象断开连接(例如,disconnect() 的 signal 参数为nullptr ),则 disconnectNotify() 仅被调用一次,且signal 将是一个无效的QMetaMethod (QMetaMethod::isValid() 返回false )。
警告:此 函数违反了面向对象的模块化原则。不过,它可能有助于优化对资源消耗较大的资源的访问。
警告:此 函数由执行断开连接的线程调用,该线程可能与该对象所在的线程不同。此外,在锁定QObject 内部互斥量的情况下,此函数也可能被调用。因此,不允许在您的重实现中重新进入任何QObject 函数,包括isSignalConnected()。 如果您在重写版本中锁定了一个互斥锁,请确保不要在其他地方持有该互斥锁的情况下调用QObject 函数,否则将导致死锁。
另请参阅 disconnect() 和connectNotify()。
void QObject::dumpObjectInfo() const
将该对象的信号连接等相关信息输出到调试日志中。
注意:在 Qt 5.9之前 ,此函数并非 const 类型。
另请参阅 dumpObjectTree()。
void QObject::dumpObjectTree() const
将子节点树输出到调试日志中。
注意:在 Qt 5.9之前 ,该函数并非 const 类型。
另请参阅 dumpObjectInfo()。
QList<QByteArray> QObject::dynamicPropertyNames() const
返回使用 `setProperty()` 动态添加到对象中的所有属性的名称。
[virtual] bool QObject::event(QEvent *e)
此虚拟函数用于接收发送到对象的事件,如果识别并处理了e 事件,则应返回true。
可以重写 event() 函数来定制对象的行为。
请确保对于所有未处理的事件,都要调用父事件类的实现。
示例:
class MyClass : public QWidget
{
Q_OBJECT
public:
MyClass(QWidget *parent = nullptr);
~MyClass();
bool event(QEvent* ev) override
{
if (ev->type() == QEvent::PolishRequest) {
// overwrite handling of PolishRequest if any
doThings();
return true;
} else if (ev->type() == QEvent::Show) {
// complement handling of Show if any
doThings2();
QWidget::event(ev);
return true;
}
// Make sure the rest of events are handled
return QWidget::event(ev);
}
};另请参阅 installEventFilter()、timerEvent()、QCoreApplication::sendEvent() 和QCoreApplication::postEvent()。
[virtual] bool QObject::eventFilter(QObject *watched, QEvent *event)
如果该对象已被安装为watched 对象的事件过滤器,则对事件进行过滤。
在您对该函数的重写中,若要过滤掉event 事件(即停止对其进行进一步处理),请返回true;否则返回false。
示例:
classMainWindow :publicQMainWindow
{
public:
MainWindow();
protected:
booleventFilter(QObject*obj,QEvent*ev) override;
private:
QTextEdit*textEdit;
};
MainWindow::MainWindow()
{
textEdit= newQTextEdit;
setCentralWidget(textEdit);
textEdit->installEventFilter(this);
}
boolMainWindow::eventFilter(QObject*obj,QEvent*event)
{
if(obj==textEdit) {
if(event->type()==QEvent::KeyPress) {
QKeyEvent*keyEvent = static_cast<QKeyEvent*>(event);
qDebug() << "Ate key press" << keyEvent->key();
return true;
}else{
return false;
}
}else{
// 将事件传递给父类
returnQMainWindow::eventFilter(obj,event);
}
}请注意,在上面的示例中,未处理的事件会被传递给基类的 eventFilter() 函数,因为基类可能出于其自身的内部目的而重新实现了 eventFilter() 函数。
某些事件(例如QEvent::ShortcutOverride )必须通过显式调用accept()来接受,以防止其传播。
警告:若 在此函数中删除了接收器对象,请务必返回 true。否则,Qt 会将事件转发给已被删除的对象,导致程序可能崩溃。
另请参阅 installEventFilter()。
template <typename T> T QObject::findChild(QAnyStringView name, Qt::FindChildOptions options = Qt::FindChildrenRecursively) const
返回该对象的子对象,该子对象可被转换为类型 T,且名称为name ;若不存在此类对象,则返回nullptr 。当name 参数为空时,将匹配所有对象。当name 为空且不为空时,仅匹配objectName 为空的对象。搜索以递归方式进行,除非options 指定了 FindDirectChildrenOnly 选项。
如果有多个子节点符合搜索条件,则返回最直接的祖先。如果有多个最直接的祖先,则返回children()中的第一个子节点。在这种情况下,最好使用findChildren()来获取所有子节点的完整列表。
此示例返回parentWidget 的一个子元素QPushButton ,其名称为"button1" ,即使该按钮并非父元素的直接子元素:
QPushButton *button = parentWidget->findChild<QPushButton *>("button1");此示例返回parentWidget 的子元素QListWidget :
QListWidget *list = parentWidget->findChild<QListWidget *>();此示例返回parentWidget (其直接父元素)的子元素QPushButton ,名称为"button1" :
QPushButton *button = parentWidget->findChild<QPushButton *>("button1", Qt::FindDirectChildrenOnly);此示例返回parentWidget (其直接父对象)的一个QListWidget 子对象:
QListWidget *list = parentWidget->findChild<QListWidget *>(Qt::FindDirectChildrenOnly);注意:在 Qt 6.7 之前的版本中,此函数将 `name ` 视为 `QString`,而非 `QAnyStringView`。
另请参阅 findChildren()。
[since 6.7] template <typename T> T QObject::findChild(Qt::FindChildOptions options = Qt::FindChildrenRecursively) const
返回该对象中可转换为类型 T 的子对象;若不存在此类对象,则返回nullptr 。搜索过程采用递归方式进行,除非options 指定了 FindDirectChildrenOnly 选项。
如果有多个子对象符合搜索条件,则返回最直接的祖先。如果有多个最直接的祖先,则返回children()中的第一个子对象。在这种情况下,最好使用findChildren()来获取所有子对象的完整列表。
这是一个重载函数。
该函数在 Qt 6.7 中引入。
另请参阅 findChildren()。
template <typename T> QList<T> QObject::findChildren(QAnyStringView name, Qt::FindChildOptions options = Qt::FindChildrenRecursively) const
返回该对象下所有具有给定name 且可转换为类型T的子对象,若不存在此类对象,则返回空列表。若name 参数为null,则匹配所有对象;若为空,则仅匹配objectName 为空的对象。搜索过程采用递归方式进行,除非options 指定了FindDirectChildrenOnly选项。
以下示例演示了如何查找指定parentWidget (名为widgetname )的所有子QWidget:
此示例返回所有作为parentWidget 子节点的QPushButton:
QList<QPushButton *> allPButtons = parentWidget->findChildren<QPushButton *>();此示例返回所有作为parentWidget 的直接子元素的QPushButton:
QList<QPushButton *> childButtons = parentWidget.findChildren<QPushButton *>(Qt::FindDirectChildrenOnly);注意:在 Qt 6.7 之前的版本中,此函数将 `name ` 作为 `QString` 而非 `QAnyStringView` 处理。
另请参阅 findChild()。
[since 6.3] template <typename T> QList<T> QObject::findChildren(Qt::FindChildOptions options = Qt::FindChildrenRecursively) const
返回该对象的所有子对象,这些子对象均可转换为类型 T;如果不存在此类对象,则返回空列表。搜索过程采用递归方式进行,除非在 `options ` 中指定了 `FindDirectChildrenOnly` 选项。
这是一个重载函数。
该函数在 Qt 6.3 中引入。
另请参阅 findChild()。
template <typename T> QList<T> QObject::findChildren(const QRegularExpression &re, Qt::FindChildOptions options = Qt::FindChildrenRecursively) const
返回该对象的子对象中,既可转换为类型 T,且名称与正则表达式re 匹配的那些;如果不存在此类对象,则返回空列表。搜索操作将递归进行,除非在options 中指定了 FindDirectChildrenOnly 选项。
此函数重载了QObject::findChildren()。
bool QObject::inherits(const char *className) const
如果该对象是继承了className 的类的实例,或者是一个继承了className 的QObject 子类的实例,则返回true ;否则返回false 。
一个类被视为继承自身。
示例:
QTimer *timer = new QTimer; // QTimer inherits QObject
timer->inherits("QTimer"); // returns true
timer->inherits("QObject"); // returns true
timer->inherits("QAbstractButton"); // returns false
// QVBoxLayout inherits QObject and QLayoutItem
QVBoxLayout *layout = new QVBoxLayout;
layout->inherits("QObject"); // returns true
layout->inherits("QLayoutItem"); // returns true (even though QLayoutItem is not a QObject)若需判断某个对象是否为特定类的实例(以便进行类型转换),建议改用qobject_cast<Type *>(object) 方法。
另请参阅 metaObject() 和qobject_cast()。
void QObject::installEventFilter(QObject *filterObj)
在此对象上安装一个名为filterObj 的事件过滤器。例如:
monitoredObj->installEventFilter(filterObj);事件过滤器是一个会接收发送到该对象的所有事件的对象。该过滤器既可以阻止事件,也可以将其转发给该对象。事件过滤器filterObj 通过其eventFilter()函数接收事件。如果需要过滤(即阻止)该事件,eventFilter()函数必须返回true;否则必须返回false。
如果单个对象上安装了多个事件过滤器,则最后安装的过滤器将首先被激活。
如果该对象上已安装了filterObj ,则此函数会将其移至最后,使其行为如同最后安装的一样。
以下是一个KeyPressEater 类,它会捕获其监视对象的按键操作:
classKeyPressEater :publicQObject
{
Q_OBJECT
public:
KeyPressEater(QObject*parent =nullptr) : QObject(parent) {}
//...
protected:
booleventFilter(QObject*obj,QEvent*event) override;
};
boolKeyPressEater::eventFilter(QObject*obj,QEvent*event)
{
if(event->type()==QEvent::KeyPress) {
QKeyEvent*keyEvent = static_cast<QKeyEvent*>(event);
qDebug("Ate key press %d", keyEvent->key());
return true;
}else{
// 标准事件处理
returnQObject::eventFilter(obj,event);
}
}以下是在两个小部件上安装它的方法:
KeyPressEater *keyPressEater = new KeyPressEater(this);
QPushButton *pushButton = new QPushButton(this);
QListView *listView = new QListView(this);
pushButton->installEventFilter(keyPressEater);
listView->installEventFilter(keyPressEater);例如,QShortcut 类就使用了这种技术来拦截快捷键的按下操作。
警告:如果您在 `eventFilter()` 函数中删除了接收器对象,请务必返回 `true`。如果返回 `false`,Qt 会将事件发送到已被删除的对象,导致程序崩溃。
请注意,过滤对象必须与该对象位于同一线程中。如果 `filterObj ` 位于不同线程中,则该函数不会执行任何操作。如果在调用此函数后,`filterObj ` 或该对象被移至不同线程,则事件过滤器将不会被调用,直到两个对象再次具有相同的线程亲和性(且该亲和性未被移除)。
另请参阅 removeEventFilter()、eventFilter() 和event()。
[noexcept, since 6.11] bool QObject::isQmlExposed() const
返回该对象是由 QML 引擎创建的,还是通过 `QJSEngine::setObjectOwnership()` 显式设置了所有权。
该函数在 Qt 6.11 中引入。
[since 6.4] bool QObject::isQuickItemType() const
如果该对象是QQuickItem ,则返回true ;否则返回false 。
调用此函数等同于调用inherits("QQuickItem") ,但速度要快得多。
该函数在 Qt 6.4 中引入。
[protected] bool QObject::isSignalConnected(const QMetaMethod &signal) const
如果signal 连接到至少一个接收器,则返回true ;否则返回false 。
signal 必须是该对象的信号成员,否则行为未定义。
static const QMetaMethod valueChangedSignal = QMetaMethod::fromSignal(&MyObject::valueChanged);
if (QObject::isSignalConnected(valueChangedSignal)) {
QByteArray data;
data = get_the_value(); // expensive operation
emit valueChanged(data);
}如上面的代码片段所示,您可以使用此函数来避免耗时的操作或发出无人监听的信号。
警告:在 多线程应用程序中 ,连续调用此函数不能保证产生相同的结果。
警告:此 函数违反了面向对象的模块化原则。特别是,不得从connectNotify()或disconnectNotify()的重写方法中调用此函数,因为这些方法可能会被任何线程调用。
另请参阅 receivers()。
bool QObject::isWidgetType() const
如果该对象是一个控件,则返回true ;否则返回false 。
调用此函数等同于调用inherits("QWidget") ,但速度要快得多。
bool QObject::isWindowType() const
如果该对象是一个窗口,则返回 `true `;否则返回 `false`。
调用此函数等同于调用inherits("QWindow") ,但速度要快得多。
void QObject::killTimer(int id)
终止具有定时器标识符id 的定时器。
该定时器标识符由startTimer() 在启动定时器事件时返回。
另请参阅 timerEvent() 和startTimer()。
[since 6.8] void QObject::killTimer(Qt::TimerId id)
这是一个重载函数。
该函数在 Qt 6.8 中引入。
[virtual] const QMetaObject *QObject::metaObject() const
返回指向该对象元对象的指针。
元对象包含继承了QObject 的类的相关信息,例如类名、超类名、属性、信号和插槽。每个包含Q_OBJECT 宏的QObject 子类都将拥有一个元对象。
信号/插槽连接机制和属性系统都需要元对象信息。inherits() 函数也会使用元对象。
如果您没有指向实际对象实例的指针,但仍希望访问某个类的元对象,可以使用staticMetaObject 。
示例:
QObject *obj = new QPushButton;
obj->metaObject()->className(); // returns "QPushButton"
QPushButton::staticMetaObject.className(); // returns "QPushButton"另请参阅 staticMetaObject 。
bool QObject::moveToThread(QThread *targetThread)
更改此对象及其子对象的线程亲和性,并在成功时返回true 。如果该对象有父对象,则无法将其移动。事件处理将在targetThread 中继续进行。
若要将对象移动到主线程,请使用QApplication::instance()获取当前应用程序的指针,然后使用QApplication::thread()获取该应用程序所在的线程。例如:
myObject->moveToThread(QApplication::instance()->thread());如果 `targetThread ` 返回 `nullptr`,则该对象及其子对象的所有事件处理都将停止,因为它们不再与任何线程相关联。
请注意,该对象的所有活动定时器都将被重置。定时器首先会在当前线程中停止,然后在targetThread 中(以相同的间隔)重新启动。因此,不断在不同线程之间移动对象可能会无限期推迟定时器事件。
在线程亲和性(thread affinity)发生变更之前,会向该对象发送一个QEvent::ThreadChange 事件。您可以处理此事件以执行任何特殊处理。请注意,只要该对象的在线程亲和性未被设置为nullptr ,所有新发布的事件都将在targetThread 中处理;当在线程亲和性被设置为nullptr 时,该对象及其子对象将无法进行任何事件处理,因为它们已不再与任何线程相关联。
警告:此 函数不具备线程安全性;当前线程必须与当前线程亲和性一致。换言之,此函数只能将对象从当前线程“推送”到其他线程,而无法将对象从任意线程“拉取”到当前线程。 不过,此规则有一个例外:没有线程亲和性的对象可以被“拉取”到当前线程。
在 Qt 6.7 之前的版本中,该函数没有返回值(void )。
另请参阅 thread()。
[private signal] void QObject::objectNameChanged(const QString &objectName)
在对象名称被更改后,会发出此信号。新对象名称作为objectName 参数传递。
注意:这是一个 私有信号。它可以在信号连接中使用,但用户无法触发它。
注意: 这是属性 `objectName`的通知 信号。
另请参阅 QObject::objectName 。
QObject *QObject::parent() const
返回指向父对象的指针。
QVariant QObject::property(const char *name) const
返回对象的name 属性的值。
如果不存在此属性,则返回的变体无效。
有关所有可用属性的信息可通过metaObject() 和dynamicPropertyNames() 获取。
另请参阅 setProperty()、QVariant::isValid()、metaObject() 和dynamicPropertyNames()。
[protected] int QObject::receivers(const char *signal) const
返回连接到signal 的接收器数量。
由于插槽和信号均可作为信号的接收器,且同一连接可以建立多次,因此接收器的数量即等于该信号建立的连接数量。
调用此函数时,可以使用SIGNAL() 宏来传递一个特定的信号:
if (receivers(SIGNAL(valueChanged(QByteArray))) > 0) {
QByteArray data;
get_the_value(&data); // expensive operation
emit valueChanged(data);
}如上面的代码片段所示,您可以使用此函数来避免耗时的操作,或避免发出无人监听的信号。
警告:在 多线程应用程序中,连续调用此函数无法保证产生相同的结果。
警告:此 函数违反了面向对象的模块化原则。特别是,不得从connectNotify()或disconnectNotify()的重写方法中调用此函数,因为这些方法可能被任何线程调用。
另请参阅 isSignalConnected()。
void QObject::removeEventFilter(QObject *obj)
从该对象中移除事件过滤器对象obj 。如果尚未安装该事件过滤器,则忽略此请求。
当该对象被销毁时,其所有事件过滤器都会被自动移除。
移除事件过滤器始终是安全的,即使在事件过滤器激活期间(即从eventFilter() 函数中调用)也是如此。
另请参阅 installEventFilter()、eventFilter() 和event()。
[protected] QObject *QObject::sender() const
如果在由信号激活的插槽中调用此函数,则返回发送该信号的对象的指针;否则返回nullptr 。该指针仅在从该对象的线程上下文中调用此函数的插槽执行期间有效。
如果发送者被销毁,或者该槽与发送者的信号断开连接,则该函数返回的指针将失效。
警告:此 函数违反了面向对象的模块化原则。然而,当许多信号连接到单个槽时,获取发送者的信息可能会很有用。
警告:如 上所述,当通过Qt::DirectConnection 从与该对象线程不同的线程调用该槽时,此函数的返回值无效。请勿在此类场景中使用此函数。
另请参阅 senderSignalIndex()。
[protected] int QObject::senderSignalIndex() const
返回调用当前正在执行的槽的信号的元方法索引,该槽是sender()返回的类的成员。如果是在非由信号激活的槽之外调用此函数,则返回-1。
对于具有默认参数的信号,无论在connect() 中使用了哪个参数,该函数始终返回包含所有参数的索引。例如,信号destroyed(QObject *obj = \nullptr) 将有两个不同的索引(带参数和不带参数),但该函数始终返回带参数的索引。当使用不同参数重载信号时,此规则不适用。
警告:此 函数违反了面向对象的模块化原则。然而,当多个信号连接到同一个插槽时,获取信号索引可能会很有用。
警告: 当通过Qt::DirectConnection 从与该对象线程不同的线程调用插槽时,此函数的返回值无效。请勿在此类场景中使用此函数。
另请参见 sender()、QMetaObject::indexOfSignal() 和QMetaObject::method()。
void QObject::setObjectName(const QString &name)
将对象的名称设置为name 。
注意: 这是属性objectName 的设置器 函数。
另请参阅 objectName()。
[since 6.4] void QObject::setObjectName(QAnyStringView name)
注: 属性objectName 的赋值 函数。
这是一个重载函数。
该函数在 Qt 6.4 中引入。
void QObject::setParent(QObject *parent)
将该对象设为parent 的子对象。
bool QObject::setProperty(const char *name, const QVariant &value)
将对象的name 属性的值设置为value 。
如果该属性是在类中通过Q_PROPERTY 定义的,则成功时返回 true,否则返回 false。如果该属性未通过Q_PROPERTY 定义,因此未在元对象中列出,则将其作为动态属性添加,并返回 false。
有关所有可用属性的信息可通过metaObject() 和dynamicPropertyNames() 获取。
动态属性可通过property() 再次查询,并通过将属性值设置为无效的QVariant 来移除。更改动态属性的值会导致向对象发送QDynamicPropertyChangeEvent 。
注意:以“_q_”开头的动态属性保留用于内部用途。
另请参阅 property()、metaObject()、dynamicPropertyNames() 和QMetaProperty::write()。
[since 6.6] bool QObject::setProperty(const char *name, QVariant &&value)
该函数重载了QObject::setProperty 。
该函数在 Qt 6.6 中引入。
[noexcept] bool QObject::signalsBlocked() const
如果信号被阻塞,则返回true ;否则返回false 。
默认情况下,信号不会被阻塞。
另请参阅 blockSignals() 和QSignalBlocker 。
int QObject::startTimer(int interval, Qt::TimerType timerType = Qt::CoarseTimer)
这是一个重载函数,它将启动一个类型为timerType 的定时器,并设置超时时间为interval 毫秒。这相当于调用:
startTimer(std::chrono::milliseconds{interval}, timerType);从 Qt 6.10 开始,设置负间隔将导致运行时警告,且该值会被重置为 1 毫秒。 在 Qt 6.10 之前,Qt Timer 虽然允许设置负间隔,但行为可能出人意料(例如,如果计时器正在运行则会停止,或者根本不启动)。
另请参阅 timerEvent(),killTimer(),QChronoTimer 以及QBasicTimer 。
int QObject::startTimer(std::chrono::nanoseconds interval, Qt::TimerType timerType = Qt::CoarseTimer)
启动一个计时器并返回计时器标识符;如果无法启动计时器,则返回零。
在调用killTimer()之前,定时器事件将每interval 触发一次。如果interval 等于std::chrono::duration::zero() ,则定时器事件在控制权每次返回事件循环时触发一次,即当没有更多原生窗口系统事件需要处理时。
从 Qt 6.10 开始,设置负间隔会引发运行时警告,且该值将被重置为 1 毫秒。 在 Qt 6.10 之前,虽然可以为 Qt Timer 设置负间隔,但其行为可能出人意料(例如,如果计时器正在运行则会停止,或者根本不会启动)。
当定时器事件发生时,会通过QTimerEvent 事件参数类调用虚拟函数timerEvent()。请重写此函数以获取定时器事件。
如果有多个计时器正在运行,可以使用QTimerEvent::id()方法来确定是哪一个计时器被触发的。
示例:
classMyObject :publicQObject
{
Q_OBJECT
public:
MyObject(QObject*parent =nullptr);
Q_SIGNALS:
voidvalueChanged();
protected:
voidtimerEvent(QTimerEvent*event) override;
};
MyObject::MyObject(QObject*parent)
: QObject(parent)
{
using namespacestd::chrono_literals;
startTimer(50ms);
startTimer(5s);
startTimer(10min);
startTimer(1h);
}
voidMyObject::timerEvent(QTimerEvent*event)
{
qDebug() << "Timer ID:" << event->id();
}请注意,计时器的精度取决于底层操作系统和硬件。
通过timerType 参数,您可以自定义定时器的精度。有关不同定时器类型的信息,请参阅Qt::TimerType 。大多数平台支持 20 毫秒的精度;部分平台支持更高的精度。如果 Qt 无法提供请求数量的定时器事件,它将静默丢弃其中一部分。
QTimer 和QChronoTimer 类提供了一个高级编程接口,使用单次触发定时器和定时器信号代替事件。此外还有QBasicTimer 类,它比QChronoTimer 更轻量,但比直接使用定时器 ID 更便捷。
注意: 从 Qt 6.8开始, interval 的类型为std::chrono::nanoseconds ,此前为std::chrono::milliseconds 。此更改与 Qt 的旧版本向后兼容。
注意:在 Qt 6.8 中,QObject 已更改为使用Qt::TimerId 来表示定时器 ID。出于向后兼容性的考虑,该方法会将TimerId 转换为 int,但您可以使用Qt::TimerId 来检查该方法返回的值,例如:
QObject *obj;
//...
const auto id = Qt::TimerId {obj->startTimer(100ms)};
if (id != Qt::TimerId::Invalid)
{
// The timer has been started successfully
}这是一个重载函数。
另请参阅 timerEvent()、killTimer()、QChronoTimer 以及QBasicTimer 。
QThread *QObject::thread() const
返回包含该对象的线程。
另请参阅 ` moveToThread()`。
[virtual protected] void QObject::timerEvent(QTimerEvent *event)
可以在子类中重写此事件处理程序,以接收该对象的定时器事件。
QChronoTimer 该接口为定时器功能提供了更高层次的接口,同时也提供了关于定时器的更通用信息。定时器事件通过event 参数传递进来。
另请参阅 startTimer()、killTimer() 和event()。
[static] QString QObject::tr(const char *sourceText, const char *disambiguation = nullptr, int n = -1)
返回sourceText 的翻译版本,可选地基于disambiguation 字符串以及n 的值(适用于包含复数形式的字符串);否则,若无合适的翻译字符串,则返回QString::fromUtf8 (sourceText )。
示例:
void SpreadSheet::setupMenuBar()
{
QMenu *fileMenu = menuBar()->addMenu(tr("&File"));
...如果在同一上下文中,同一sourceText 在不同角色中被使用,则可在disambiguation 中传递一个额外的标识字符串(默认值为nullptr )。
示例:
MyWindow::MyWindow()
{
QLabel *senderLabel = new QLabel(tr("Name:"));
QLabel *recipientLabel = new QLabel(tr("Name:", "recipient"));
...有关 Qt 翻译机制的详细说明,请参阅《编写待翻译源代码》;有关消除歧义的信息,请参阅“消除相同文本的歧义”一节。
警告: 仅当在调用此方法之前已安装所有翻译器时,此 方法才具有可重入性。不支持在执行翻译过程中安装或移除翻译器。此操作可能会导致程序崩溃或其他不良行为。
另请参阅 ` QCoreApplication::translate()` 以及《使用 Qt 进行国际化》。
成员变量文档
const QMetaObject QObject::staticMetaObject
该变量存储该类的元对象。
元对象包含有关继承了QObject 的类的信息,例如类名、超类名、属性、信号和插槽。每个包含Q_OBJECT 宏的类都将拥有一个元对象。
信号/槽连接机制和属性系统都需要元对象信息。inherits() 函数也会使用元对象。
如果你有一个指向对象的指针,可以使用metaObject() 来获取与该对象关联的元对象。
示例:
QPushButton::staticMetaObject.className(); // returns "QPushButton"
QObject *obj = new QPushButton;
obj->metaObject()->className(); // returns "QPushButton"另请参阅 metaObject()。
相关非成员
QObjectList
[since 6.8] enum class TimerId
该类型用于表示定时器 ID(例如,QTimer 和QChronoTimer )。其底层类型为int 。您可以使用qToUnderlying() 将 Qt::TimerId 转换为int 。
| 常量 | 值 | 描述 |
|---|---|---|
QObject::TimerId::Invalid | 0 | 表示一个无操作定时器 ID;其用法取决于上下文,例如,这是 `QObject::startTimer()` 返回的值,用于指示无法启动定时器;而 `QChronoTimer::id()` 在定时器处于非活动状态时会返回此值,即 `timer.isActive() ` 返回 `false`。 |
该枚举在 Qt 6.8 中引入。
另请参阅 QTimer::id()、QChronoTimer::id() 和QObject::startTimer()。
template <typename T> T qobject_cast(QObject *object)
template <typename T> T qobject_cast(const QObject *object)
如果对象的类型为 T(或其子类),则返回将给定的 `object ` 强制转换为类型 T 的结果;否则返回 `nullptr`。如果 `object ` 为 `nullptr `,则还会返回 `nullptr`。
类 T 必须(直接或间接)继承QObject ,并且必须使用Q_OBJECT 宏进行声明。
一个类被视为继承其自身。
示例:
QObject *obj = new QTimer; // QTimer inherits QObject
QTimer *timer = qobject_cast<QTimer *>(obj);
// timer == (QObject *)obj
QAbstractButton *button = qobject_cast<QAbstractButton *>(obj);
// button == nullptrqobject_cast() 函数的行为与标准 C++ 中的dynamic_cast() 类似,其优点在于无需 RTTI 支持,且可在动态库边界之间正常工作。
qobject_cast() 还可以与接口配合使用。
警告:如果 T 未通过Q_OBJECT 宏进行声明,则该函数的返回值未定义。
另请参阅 QObject::inherits()。
宏文档
[since 6.7] QT_NO_CONTEXTLESS_CONNECT
定义此宏将禁用QObject::connect()的重载形式——该形式用于将信号连接到一个函子,但未同时指定QObject 作为接收器/上下文对象(即QObject::connect()的3个参数重载形式)。
使用无上下文的重载容易引发错误,因为很容易将其连接到依赖接收端某些局部状态的函子。如果此类局部状态被销毁,连接不会自动断开。
此外,此类连接始终是直接连接,这在多线程场景中可能会引发问题(例如,当信号由另一个线程发出时)。
该宏在 Qt 6.7 中引入。
另请参阅 QObject::connect 和Qt::ConnectionType 。
[since 6.12] QT_NO_DISCONNECT_CONST_CONNECTION
禁用 `const & ` 对 `QObject::disconnect()` 的重载,以强制调用者传递非 const 对象。
建议传递非 const 对象,因为它们可以立即被重置,从而更早地释放资源。 不同版本的 Qt 对 const 重载的处理方式各不相同。在较旧的 Qt 版本中,若使用最初声明为const 的 Connection 调用 const 重载,可能会引发未定义行为。当前的 Qt 版本在此方面是安全的,但未来的 Qt 版本可能会移除 const 重载,或者使其延迟释放资源,直到 Connection 对象被重新赋值或销毁为止。
传递非 const 对象可避免上述所有问题。
设置此宏后编译通过的代码,即使未启用该宏,也能在 Qt 5.0 及以后的所有版本中正常编译(且不会引发未定义行为)。
该宏于 Qt 6.12 中引入。
QT_NO_NARROWING_CONVERSIONS_IN_CONNECT
定义此宏将禁用信号和插槽之间参数的类型缩窄以及浮点数到整数的转换,前提是该信号和插槽是通过基于 PMF 的语法进行连接的。
另请参阅 QObject::connect 。
Q_CLASSINFO(Name, Value)
该宏为类关联了额外信息,可通过调用 `QObject::metaObject()` 获取。这些额外信息包括一个 `Name ` 字符串和一个 `Value ` 字面量字符串。
示例:
class MyClass : public QObject
{
Q_OBJECT
Q_CLASSINFO("Author", "Pierre Gendron")
Q_CLASSINFO("URL", "http://www.my-organization.qc.ca")
public:
//...
};Qt 在 Qt D-Bus 和 Qt Qml 模块中使用该宏。例如,在 C++ 中定义QML Object Types 时,可以将某个属性指定为默认属性:
Q_CLASSINFO("DefaultProperty", "content")另请参阅 QMetaObject::classInfo()、使用Qt D-Bus 适配器 以及从 C++ 定义 QML 类型。
Q_EMIT
当您希望在第三方信号/槽机制中使用 Qt 信号与槽时,请使用此宏来替换用于发出信号的emit 关键字。
该宏通常在.pro 文件中通过CONFIG 变量指定no_keywords 时使用,但即使未指定no_keywords ,也可使用该宏。
Q_ENUM(...)
该宏将一个枚举类型注册到元对象系统中。它必须放置在包含Q_OBJECT 、Q_GADGET 或Q_GADGET_EXPORT 宏的类中的枚举声明之后。若涉及命名空间,请改用Q_ENUM_NS()。
例如:
class MyClass : public QObject
{
Q_OBJECT
public:
MyClass(QObject *parent = nullptr);
~MyClass();
enum Priority { High, Low, VeryHigh, VeryLow };
Q_ENUM(Priority)
void setPriority(Priority priority);
Priority priority() const;
};使用 Q_ENUM 声明的枚举,其QMetaEnum 会在外围的QMetaObject 中注册。您还可以使用QMetaEnum::fromType() 获取QMetaEnum 。
已注册的枚举也会自动注册到 Qt 元类型系统中,从而使 `QMetaType ` 能够识别它们,而无需使用 `Q_DECLARE_METATYPE()`。这将启用一些有用的功能;例如,如果在 `QVariant` 中使用,您可以将其转换为字符串。同样,将其传递给 `QDebug ` 将会打印出它们的名称。
另请参阅 Qt 的属性系统。
Q_ENUM_NS(...)
该宏用于将枚举类型注册到元对象系统中。它必须置于枚举声明之后,且位于包含Q_NAMESPACE 宏的命名空间内。其作用与Q_ENUM 相同,但适用于命名空间。
使用 Q_ENUM_NS 声明的枚举,其QMetaEnum 会注册在包含它的QMetaObject 中。您还可以使用QMetaEnum::fromType() 来获取QMetaEnum 。
已注册的枚举也会自动注册到 Qt 元类型系统中,从而使 `QMetaType ` 能够识别它们,而无需使用 `Q_DECLARE_METATYPE()`。这将启用一些有用的功能;例如,如果在 `QVariant` 中使用,您可以将其转换为字符串。同样,将其传递给 `QDebug ` 将打印出它们的名称。
另请参阅 Qt 的属性系统。
Q_FLAG(...)
该宏将单个flags type 注册到元对象系统中。它通常用于类定义中,用于声明给定枚举的值可作为标志使用,并可通过位或运算符进行组合。对于命名空间,请改用Q_FLAG_NS()。
该宏必须置于枚举声明之后。flags 类型的声明使用Q_DECLARE_FLAGS() 宏完成。
例如,在QItemSelectionModel 中,SelectionFlags 标志的声明方式如下:
class Q_CORE_EXPORT QItemSelectionModel : public QObject
{
Q_OBJECT
...
public:
enum SelectionFlag {
NoUpdate = 0x0000,
Clear = 0x0001,
Select = 0x0002,
Deselect = 0x0004,
Toggle = 0x0008,
Current = 0x0010,
Rows = 0x0020,
Columns = 0x0040,
SelectCurrent = Select | Current,
ToggleCurrent = Toggle | Current,
ClearAndSelect = Clear | Select
};
Q_DECLARE_FLAGS(SelectionFlags, SelectionFlag)
Q_FLAG(SelectionFlags)
};注意: Q_FLAG宏会 自动将各个标志值注册到元对象系统中,因此无需在此宏之外额外使用Q_ENUM()。
另请参阅 Qt 的属性系统。
Q_FLAG_NS(...)
该宏将单个flags type 注册到元对象系统中。它用于包含Q_NAMESPACE 宏的命名空间中,用于声明某个枚举的值可作为标志使用,并可通过位或运算符进行组合。其作用与Q_FLAG 相同,但仅限于命名空间内。
该宏必须置于枚举声明之后。
注意: Q_FLAG_NS宏会 自动将各个标志值注册到元对象系统中,因此无需在此宏之外额外使用Q_ENUM_NS()。
另请参阅 Qt 的属性系统。
Q_GADGET
Q_GADGET 宏是Q_OBJECT 宏的简化版本,适用于那些不继承自QObject 类,但仍希望使用QMetaObject 提供的某些反射功能的类。
注意:该宏 展开以 `private` 访问限定符结尾。若在该宏之后立即声明成员,这些成员也将被设为私有。若要在宏之后紧接着添加公有(或受保护)成员,请使用 `public: `(或 `protected:`)访问限定符。
Q_GADGET 可以具有Q_ENUM 、Q_PROPERTY 和Q_INVOKABLE ,但不能具有信号或槽。
Q_GADGET 提供了一个类成员staticMetaObject 。staticMetaObject 的类型为QMetaObject ,用于访问通过Q_ENUM 声明的枚举。
另请参阅 Q_GADGET_EXPORT 。
[since 6.3] Q_GADGET_EXPORT(EXPORT_MACRO)
Q_GADGET_EXPORT 宏的工作原理与Q_GADGET 宏完全相同。不过,由此提供的staticMetaObject 变量(参见Q_GADGET )是在声明时附加了EXPORT_MACRO 修饰符的。 当需要从动态库中导出某个对象,但其外围类整体不应被导出时(例如,因为该类主要由内联函数组成),此特性非常有用。
注意:此宏 展开以private: 访问限定符结尾。若在该宏之后紧接着声明成员,这些成员也将被设为私有。若要在宏之后紧接着添加公有(或受保护)成员,请使用public: (或protected: )访问限定符。
例如:
class Point {
Q_GADGET_EXPORT(EXPORT_MACRO)
Q_PROPERTY(int x MEMBER x)
Q_PROPERTY(int y MEMBER y)
~~~该宏首次引入于 Qt 6.3。
Q_INTERFACES(...)
该宏用于告知 Qt 该类实现了哪些接口。在实现插件时会用到它。
另请参阅 Q_DECLARE_INTERFACE()、Q_PLUGIN_METADATA() 以及《如何创建 Qt 插件》。
Q_INVOKABLE
将此宏应用于成员函数的声明中,以便通过元对象系统调用这些函数。该宏应写在返回类型之前,如下例所示:
class Window : public QWidget
{
Q_OBJECT
public:
Window();
void normalMethod();
Q_INVOKABLE void invokableMethod();
};函数 `invokableMethod() ` 通过 `Q_INVOKABLE` 进行了标记,从而使其在元对象系统中注册,并允许使用 `QMetaObject::invokeMethod()` 调用它。由于函数 `normalMethod() ` 未以这种方式注册,因此无法使用 `QMetaObject::invokeMethod()` 调用它。
如果可调用成员函数返回指向 `QObject ` 或 `QObject ` 子类的指针,且该函数是从 QML 中调用的,则适用特殊的所有权规则。有关更多信息,请参阅《QML 与 C++ 之间的数据类型转换》。
[since 6.0] Q_MOC_INCLUDE
Q_MOC_INCLUDE 宏可在类内或类外使用,用于指示Meta-Object Compiler添加包含语句。
// Put this in your code and the generated code will include this header.
Q_MOC_INCLUDE("myheader.h")如果作为属性或信号/插槽参数使用的类型是前向声明的,则此功能非常有用。
该宏在 Qt 6.0 中首次引入。
Q_NAMESPACE
Q_NAMESPACE 宏可用于为命名空间添加QMetaObject 功能。
Q_NAMESPACE 可以包含Q_CLASSINFO 、Q_ENUM_NS 、Q_FLAG_NS ,但不能包含Q_ENUM 、Q_FLAG 、Q_PROPERTY 、Q_INVOKABLE 、信号或插槽。
Q_NAMESPACE 使外部变量staticMetaObject 可用。staticMetaObject 的类型为QMetaObject ,并可访问使用Q_ENUM_NS/Q_FLAG_NS 声明的枚举。
例如:
namespace test {
Q_NAMESPACE
...另请参阅 Q_NAMESPACE_EXPORT 。
Q_NAMESPACE_EXPORT(EXPORT_MACRO)
Q_NAMESPACE_EXPORT 宏可用于向命名空间添加QMetaObject 功能。
其工作原理与Q_NAMESPACE 宏完全相同。不过,在命名空间中定义的外部变量staticMetaObject 会带有提供的EXPORT_MACRO 限定符。如果需要将该对象从动态库中导出,此功能非常有用。
例如:
namespace test {
Q_NAMESPACE_EXPORT(EXPORT_MACRO)
...另请参阅 Q_NAMESPACE 和《创建共享库》。
Q_OBJECT
Q_OBJECT 宏用于启用元对象功能,例如动态属性、信号和槽。
您可以将 Q_OBJECT 宏添加到类定义的任何部分,只要该部分声明了自身的信号和槽,或者使用了 Qt 元对象系统提供的其他服务。
注意:该宏的 展开以访问限定符 `private` 结尾。若在该宏之后立即声明成员,这些成员也将被设为私有。若要在宏之后紧接着添加公有(或受保护)成员,请使用访问限定符 `public: `(或 `protected:`)。
示例:
#include <QObject>
class Counter : public QObject
{
Q_OBJECT
// Note. The Q_OBJECT macro starts a private section.
// To declare public members, use the 'public:' access modifier.
public:
Counter() { m_value = 0; }
int value() const { return m_value; }
public slots:
void setValue(int value);
signals:
void valueChanged(int newValue);
private:
int m_value;
};注意:此 宏要求类是QObject 的子类。若要使元对象系统支持非QObject 子类的类中的枚举,请使用Q_GADGET 或Q_GADGET_EXPORT 代替Q_OBJECT。
另请参阅 “元对象系统”、“信号与槽”以及“Qt 的属性系统”。
Q_PROPERTY(...)
该宏用于在继承自QObject 的类中声明属性。这些属性的行为与类数据成员类似,但具有可通过元对象系统访问的额外功能。
Q_PROPERTY(type name
(READ getFunction [WRITE setFunction] |
MEMBER memberName [(READ getFunction | WRITE setFunction)])
[RESET resetFunction]
[NOTIFY notifySignal]
[REVISION int | REVISION(int[, int])]
[DESIGNABLE bool]
[SCRIPTABLE bool]
[STORED bool]
[USER bool]
[BINDABLE bindableProperty]
[CONSTANT]
[FINAL]
[VIRTUAL]
[OVERRIDE]
[REQUIRED])必须指定属性名称、类型以及READ 函数。类型可以是QVariant 支持的任何类型,也可以是用户自定义类型。其余项为可选,但通常会指定WRITE 函数。各属性的默认值为true,但USER 除外,其默认值为false。
例如:
Q_PROPERTY(QString title READ title WRITE setTitle USER true)有关如何使用此宏的更多详细信息及其更详细的使用示例,请参阅关于Qt 属性系统的讨论。
另请参阅 Qt 的属性系统。
Q_REVISION
将此宏应用于成员函数的声明中,以便在元对象系统中为其标记修订号。该宏应写在返回类型之前,如下例所示:
class Window : public QWidget
{
Q_OBJECT
Q_PROPERTY(int normalProperty READ normalProperty)
Q_PROPERTY(int newProperty READ newProperty REVISION(2, 1))
public:
Window();
int normalProperty();
int newProperty();
public slots:
void normalMethod();
Q_REVISION(2, 1) void newMethod();
};当使用元对象系统将对象动态暴露给另一个 API 时,此功能非常有用,因为您可以匹配该 API 多个版本所期望的版本。请考虑以下简化示例:
Window window;
int expectedRevision = 0;
const QMetaObject *windowMetaObject = window.metaObject();
for (int i=0; i < windowMetaObject->methodCount(); i++)
if (windowMetaObject->method(i).revision() <= expectedRevision)
exposeMethod(windowMetaObject->method(i));
for (int i=0; i < windowMetaObject->propertyCount(); i++)
if (windowMetaObject->property(i).revision() <= expectedRevision)
exposeProperty(windowMetaObject->property(i));使用与前例相同的 Window 类,只有当预期版本为2.1 或更高时,此代码中才会暴露 newProperty 和 newMethod。
由于所有未标记的方法均被视为属于修订版0 ,因此Q_REVISION(0) 或Q_REVISION(0, 0) 格式的标签均无效且会被忽略。
您可以向Q_REVISION 传递一个或两个整数参数。如果传递一个参数,则仅表示次版本号。这意味着主版本号未指定。如果传递两个参数,则第一个参数为主版本号,第二个参数为次版本号。
元对象系统本身并不使用此标签。目前仅由QtQml 模块使用。
有关更通用的字符串标签,请参阅QMetaMethod::tag()
另请参阅 QMetaMethod::revision()。
Q_SET_OBJECT_NAME(Object)
该宏将“Object”类型(objectName )赋值给Object 。
无论 `Object ` 是否为指针都无所谓,该宏会自动进行判断。
另请参阅 QObject::objectName()。
Q_SIGNAL
这是一个额外的宏,可用于将单个函数标记为信号。它非常实用,特别是在使用不支持 `signals ` 或 `Q_SIGNALS ` 组格式的第三方源代码解析器时。
当您希望在第三方信号/槽机制中使用 Qt 信号与槽时,请使用此宏来替换类声明中的signals 关键字。
该宏通常在.pro 文件中通过CONFIG 变量指定no_keywords 时使用,但即使未指定no_keywords ,也可以使用该宏。
Q_SIGNALS
当您希望在结合第三方信号/槽机制使用 Qt 信号和槽时,请使用此宏来替换类声明中的signals 关键字。
该宏通常在.pro 文件中通过CONFIG 变量指定no_keywords 时使用,但即使未指定no_keywords ,也可以使用该宏。
Q_SLOT
这是一个额外的宏,可让您将单个函数标记为槽。它非常有用,尤其是在使用无法识别 `slots ` 或 `Q_SLOTS ` 组名的第三方源代码解析器时。
当您希望在结合第三方信号/槽机制使用 Qt 信号与槽时,请使用此宏来替换类声明中的slots 关键字。
该宏通常在.pro 文件中通过CONFIG 变量指定no_keywords 时使用,但即使未指定no_keywords ,也可使用该宏。
Q_SLOTS
当您希望在第三方信号/槽机制中使用 Qt 信号与槽时,请使用此宏来替换类声明中的slots 关键字。
该宏通常在.pro 文件中通过CONFIG 变量指定了no_keywords 时使用,但即使未指定no_keywords ,也可以使用该宏。
© 2026 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.