QObject 类
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, PointerToMemberFunction signal, const context, Functor functor, Qt::ConnectionType type)
- disconnect(const QObject *sender, const char *signal, const QObject *receiver, const char *method)
- disconnect(const char *signal, const QObject *receiver, const char *method) 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 char *signal = nullptr, const QObject *receiver = nullptr, const char *method = nullptr) const |
bool | disconnect(const QObject *receiver, 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.4) bool | isQuickItemType() const |
bool | isWidgetType() const |
bool | isWindowType() const |
void | killTimer(int 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::milliseconds 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 char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type = Qt::AutoConnection) |
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, PointerToMemberFunction signal, const QObject *receiver, PointerToMemberFunction 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) |
bool | disconnect(const QObject *sender, const char *signal, const QObject *receiver, const char *method) |
bool | disconnect(const QObject *sender, const QMetaMethod &signal, const QObject *receiver, const QMetaMethod &method) |
bool | disconnect(const QMetaObject::Connection &connection) |
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 | |
T | qobject_cast(QObject *object) |
T | qobject_cast(const QObject *object) |
宏
(自6.7起) | QT_NO_CONTEXTLESS_CONNECT |
QT_NO_NARROWING_CONVERSIONS_IN_CONNECT | |
Q_CLASSINFO(Name, Value) | |
Q_EMIT | |
Q_ENUM(...) | |
Q_ENUM_NS(...) | |
Q_FLAG(...) | |
Q_FLAG_NS(...) | |
Q_GADGET | |
(自6.3起) | Q_GADGET_EXPORT(EXPORT_MACRO) |
Q_INTERFACES(...) | |
Q_INVOKABLE | |
(自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()信号。您可以通过捕获这个信号来避免对QObjects的悬挂引用。
QObject可以通过event()接收事件并过滤其他对象的事件。有关详细信息,请参阅installEventFilter()和eventFilter()。可以通过重写childEvent()函数来捕获子事件,这提供了一个便利的处理程序。
最后但同样重要的,QObject在Qt中提供了基本的定时器支持;有关定时器的高级支持,请参阅QTimer。
请注意,实现信号、槽或属性的任何对象都必须使用Q_OBJECT宏。您还需要在源文件上运行元对象编译器。我们强烈建议在QObject的所有子类中(无论它们是否实际使用信号、槽和属性)使用此宏,因为不这样做可能会导致某些函数显示异常行为。
所有Qt小部件都继承自QObject。便利函数isWidgetType()返回一个对象是否实际上是小部件。它与qobject_cast<QWidget *>(obj)或obj->inherits("QWidget")相比要快得多。
一些QObject函数,例如children(),返回一个QObjectList。QObjectList是QList<QObject *>的一个类型别名。
线程亲和力
据说,一个QObject实例有一个线程亲和力,或者它存在于某个线程中。当一个QObject接收到一个队列信号或一个已发布的事件时,槽或事件处理程序将在对象所处的线程中运行。
注意:如果一个QObject没有线程亲和力(即thread()返回零),或者它存在于一个没有运行事件循环的线程中,那么它就不能接收队列信号或已发布的事件。
默认情况下,一个QObject存在于它被创建的线程中。可以通过使用thread()查询一个对象的线程亲和力,并使用moveToThread()进行更改。
所有QObjects必须存在于与它们相同的线程中。因此
- 如果涉及的两个QObjects存在于不同的线程中,则setParent()将失败。
- 当一个QObject被移至另一个线程时,所有的子将自动被移动。
- 如果QObject有父对象,则moveToThread()将失败。
- 如果QObjects在QThread::run()中创建,它们不能成为QThread对象的后代,因为QThread不存在于调用QThread::run()的线程中。
注意:QObject的成员变量不会自动成为其子对象。必须通过传递子对象构造函数的指针或调用setParent()来设置父-child关系。不进行此步骤,对象成员变量将在moveToThread()调用时保留在旧线程中。
没有复制构造函数或赋值运算符
QObject既没有复制构造函数也没有赋值运算符。这是设计选择。实际上,它们被声明,但位于带有宏 Q_DISABLE_COPY() 的 private
部分中。实际上,所有从 QObject 派生的 Qt 类(直接或间接)都使用这个宏来将它们的复制构造函数和赋值运算符声明为私有。理由可以在 Qt 对象模型 页上的 标识与值 讨论中找到。
主要后果是,你应该在使用指针的 QObject(或者你的 Qobject 子类)的任何地方使用 Qobject 子类作为值。例如,没有复制构造函数,你不能将 Qobject 子类作为值存储在容器类中的一个。你必须存储指针。
自动连接
Qt 的元对象系统提供了一个在 QObject 子类及其子类之间自动连接信号和槽的机制。只要对象带有合适的对象名,并且槽遵循简单的命名约定,这种连接就可以通过函数 QMetaObject::connectSlotsByName() 在运行时执行。
uic 生成的代码会调用这个函数,以在由 Qt Designer 创建的表单上的小部件之间执行自动连接。有关使用 Qt Designer 的自动连接的更多信息,请参阅 Qt Designer 手册中的 在您的应用程序中使用 Designer UI 文件 部分。
动态属性
可以在运行时向 QObject 实例添加和删除动态属性。动态属性不需要在编译时声明,但它们提供了与静态属性相同的好处,并且使用相同的 API (使用 property() 读取它们,使用 setProperty() 写入它们)来操作。
Qt Designer 支持动态属性,可以给标准 Qt 小部件和用户创建的形式赋予动态属性。
国际化 (I18n)
所有 QObject 子类都支持 Qt 的翻译功能,这使得将应用程序的用户界面翻译成不同语言成为可能。
另请参阅 QMetaObject,QPointer,QObjectCleanupHandler,Q_DISABLE_COPY() 和 对象树 & 所有权。
属性文档
[可绑定]
objectName : QString
注意:这个属性支持 QProperty 绑定。
这个属性保存了这个对象的名字
您可以使用 findChild() 通过名字(和类型)找到对象。您可以使用 findChildren() 找到一组对象。
qDebug("MyClass::setPrecision(): (%s) invalid precision %f", qPrintable(objectName()), newPrecision);
默认情况下,这个属性包含一个空字符串。
另请参阅:metaObject() 和 QMetaObject::className().
成员函数文档
[显式可调用]
QObject::QObject(QObject *parent = nullptr)
使用父对象parent构造一个对象。
对象父可以被看作是该对象的拥有者。例如,一个对话框是其中OK和Cancel按钮的父。
父对象的析构函数销毁所有子对象。
将parent设置为nullptr
构造一个没有父对象的对象。如果该对象是一个小部件,它将成为一个顶层窗口。
注意:此函数可以通过元对象系统从QML调用。参见Q_INVOKABLE。
另请参阅:parent(),findChild(),和findChildren。
[虚拟 nothrow]
QObject::~QObject()
销毁对象,删除所有子对象。
自动断开对象的所有信号,并从事件队列中移除对该对象的任何挂起的已发布事件。然而,通常使用deleteLater()比直接删除QObject子类更安全。
警告:所有子对象都会被删除。如果这些对象中的任何一个在堆或全局中,程序迟早会崩溃。我们不推荐在父对象外部持有子对象的指针。如果仍然持有,destroyed()信号会给你一个检测对象何时被销毁的机会。
警告:如果在处理发送到QObject的事件时删除它,可能会导致崩溃。如果该QObject存在于不同于当前执行的线程中,请不要直接删除它。使用deleteLater()代替,这将导致事件循环在这个对象的所有挂起事件都已传递给它后删除该对象。
另请参阅:deleteLater。
[nothrow]
bool QObject::blockSignals(bool block)
如果block为true,此对象的信号发射会被阻塞(即,发射信号将不会调用连接到它的任何内容)。如果block为false,则不会发生此阻塞。
返回值是signalsBlocked的先前值。
即使在信号被阻塞的情况下,也会发射destroyed信号。
被阻塞时发射的信号不会缓存在。
另请参阅:signalsBlocked()和QSignalBlocker。
[虚拟受保护]
void QObject::childEvent(QChildEvent *event)
这个事件处理可以在子类中重写以接收子事件。事件通过event参数传递。
QEvent::ChildAdded 和 QEvent::ChildRemoved 事件在添加或删除子对象时发送给对象。在这两种情况下,您只能依赖于该子对象是一个 QObject,或者如果 isWidgetType() 返回 true
,那么是一个 QWidget。 (这是因为在 ChildAdded 的情况下,子对象尚未完全构建,在 ChildRemoved 的情况下,它可能已经被销毁)。
QEvent::ChildPolished 事件在子对象被打磨或添加打磨子对象时发送给小部件。如果您收到一个打磨子对象事件,则子对象的构建通常已完成。但是,这并不保证,当一个小部件的构造函数执行时,可能会发送多个打磨事件。
对于每个子小部件,您将接收一个 ChildAdded 事件,零个或多个 ChildPolished 事件,以及一个 ChildRemoved 事件。
如果一个子对象在添加后立即被删除,则省略 ChildPolished 事件。如果在构建和销毁过程中子对象被打磨多次,您可能会收到针对同一子对象的多个子打磨事件,每次事件都带有不同的虚表。
另请参阅 event()。
const QObjectList &QObject::children() const
返回子对象列表。在 <QObject>
头文件中定义了 QObjectList 类,如下所示
typedef QList<QObject*> QObjectList;
添加的第一个子对象是列表中的第一个对象,最后添加的子对象是列表中的最后一个对象,即新子对象被附加到末尾。
请注意,当 QWidget 子对象 升起 或 降低 时,列表顺序会改变。升起的小部件变为列表中的最后一个对象,降低的小部件变为列表中的第一个对象。
另请参阅 findChild()、findChildren()、parent() 和 setParent()。
[静态]
QMetaObject::Connection QObject::connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type = Qt::AutoConnection)
从发送器的 signal 到接收器的 method 创建给定 type 的连接。返回一个可以用于稍后断开连接的连接句柄。
当指定 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无法验证信号或方法的存在,或者它们的签名不兼容),则连接句柄将无效。您可以通过将其转换为bool来检查句柄是否有效。
默认情况下,每创建一个连接就会发出一个信号;重复连接会发出两个信号。您可以通过单个disconnect()调用来断开所有这些连接。如果您传递Qt::UniqueConnection 类型,则仅在它不是重复的时才会建立连接。如果已经存在重复(即在对同一对象的同一信号和槽的精确相同的连接),则连接将失败,connect将返回一个无效的QMetaObject::Connection。
注意:Qt::UniqueConnections不适用于lambda、非成员函数和functor;它们仅适用于连接到成员函数。
可选的类型参数描述要建立的连接类型。特别是,它确定是否将特定信号立即传递给槽,还是将其排队,稍后再传递。如果信号排队,则参数类型必须是Qt元对象系统所知的类型,因为Qt需要复制参数以在幕后存储在事件中。如果您尝试使用排队连接并收到错误消息
QObject::connect: Cannot queue arguments of type 'MyType' (Make sure 'MyType' is registered using qRegisterMetaType().)
在建立连接之前调用qRegisterMetaType()来注册数据类型。
注意:此函数是线程安全的。
另请参阅disconnect(断开连接),sender(发送者),qRegisterMetaType(注册元类型),Q_DECLARE_METATYPE(声明元类型),以及字符串连接和函数式连接之间的差异。
[静态]
QMetaObject::Connection QObject::connect(const QObject *sender, const QMetaMethod &signal, const QObject *receiver, const QMetaMethod &method, Qt::ConnectionType type = Qt::AutoConnection)
从发送器的 signal 到接收器的 method 创建给定 type 的连接。返回一个可以用于稍后断开连接的连接句柄。
如果无法创建连接(例如,参数无效),则连接句柄将无效。您可以通过将其转换为bool来检查QMetaObject::Connection是否有效。
此函数的行为与connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
相同,但它使用QMetaMethod来指定信号和方法。
另请参阅connect(连接)。
QMetaObject::Connection QObject::connect(const QObject *sender, const char *signal, const char *method, Qt::ConnectionType type = Qt::AutoConnection) const
此函数是 connect() 的重载。
将 sender 对象的 signal 连接到此对象的 method。
相当于 connect(sender, signal, this
, method, type)。
你建立的每个连接都会发出一个信号,因此重复连接会发出两个信号。你可以使用 disconnect() 来断开连接。
注意:此函数是线程安全的。
另请参阅 disconnect().
[静态]
模板 <typename PointerToMemberFunction> QMetaObject::Connection QObject::connect(const QObject *sender, PointerToMemberFunction signal, const QObject *receiver, PointerToMemberFunction method, Qt::ConnectionType type = Qt::AutoConnection)
此函数是 connect() 的重载。
从发送器的 signal 到接收器的 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 类型,则仅在它不是重复的时才会建立连接。如果已经存在重复(即在对同一对象的同一信号和槽的精确相同的连接),则连接将失败,connect将返回一个无效的QMetaObject::Connection。
可选的类型参数描述要建立的连接类型。特别是,它确定是否将特定信号立即传递给槽,还是将其排队,稍后再传递。如果信号排队,则参数类型必须是Qt元对象系统所知的类型,因为Qt需要复制参数以在幕后存储在事件中。如果您尝试使用排队连接并收到错误消息
QObject::connect: Cannot queue arguments of type 'MyType' (Make sure 'MyType' is registered using qRegisterMetaType().)
请确保使用 Q_DECLARE_METATYPE 声明参数类型。
可以借助 qOverload 来解析重载函数。
注意:此函数是线程安全的。
另请参阅 基于字符串和基于函数指针的连接的区别.
[静态]
模板 <typename PointerToMemberFunction, typename Functor> QMetaObject::Connection QObject::connect(const QObject *sender, PointerToMemberFunction signal, Functor functor)
此函数是 connect() 的重载。
从 sender 对象中的 signal 创建到 functor 的连接,并返回连接句柄。
该信号必须在头文件中声明为一个信号。槽函数可以是任何可以连接到信号的函数或函数对象。如果信号参数和槽参数之间存在隐式转换,则槽函数可以连接到给定信号。信号参数的数量必须不少于槽函数参数的数量。
示例
void someFunction(); 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"); });
如果发送者被销毁,连接将自动断开。但是,你应该注意,在信号发出时,用于 funtor 内部的任何对象都应该仍然处于活动状态。
因此,建议使用同时接收QObject实例作为接收器/上下文的connect()重载版本。可以通过定义宏QT_NO_CONTEXTLESS_CONNECT
来禁用不带上下文的重载版本的使用。
可以借助 qOverload 来解析重载函数。
注意:此函数是线程安全的。
[静态]
模板 <typename PointerToMemberFunction, typename Functor> QMetaObject::Connection QObject::connect(const QObject *sender, PointerToMemberFunction signal, const QObject *context, Functor functor, Qt::ConnectionType type = Qt::AutoConnection)
此函数是 connect() 的重载。
从发送者对象中的信号创建指定类型的连接到functor,放置在上下文的特定事件循环中,并返回连接句柄。
注意:Qt::UniqueConnections不适用于lambda、非成员函数和functor;它们仅适用于连接到成员函数。
该信号必须在头文件中声明为一个信号。槽函数可以是任何可以连接到信号的函数或函数对象。如果信号参数和槽参数之间存在隐式转换,则槽函数可以连接到给定信号。信号参数的数量必须不少于槽函数参数的数量。
示例
void someFunction(); 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);
如果发送者或上下文被销毁,连接将自动断开。但是,请注意,在信号被发出时,用于functor中的任何对象都必须仍然存活。
可以借助 qOverload 来解析重载函数。
注意:此函数是线程安全的。
[虚受保护]
void QObject::connectNotify(const QMetaMethod &signal)
当本对象中的信号被连接到某个东西时,会调用此虚函数。
如果您想将信号与特定信号进行比较,可以使用QMetaMethod::fromSignal()如下所示
if (signal == QMetaMethod::fromSignal(&MyObject::valueChanged)) { // signal is valueChanged }
注意:此函数违反了面向对象的原则模块化。然而,在需要仅当某个东西连接到信号才执行昂贵的初始化时,可能很有用。
注意:此函数由执行连接的线程调用,这可能不是此对象所在的线程。这个函数可能也在一个带有QObject内部互斥锁被锁定的线程中被调用。因此,不允许从您的重实现中重新进入任何QObject函数,包括isSignalConnected()。如果在您的重实现中锁定互斥锁,请确保不要在其他地方使用该互斥锁持有互斥锁调用QObject函数,否则会导致死锁。
另请参阅 connect() 和 disconnectNotify()。
[虚受保护]
void QObject::customEvent(QEvent *event)
此事件处理器可以在子类中重新实现以接收自定义事件。自定义事件是用户定义的事件,其类型值至少与枚举QEvent::Type中的QEvent::User项一样大,通常是QEvent的子类。事件通过{i translate="no">event参数传入。
[槽]
void QObject::deleteLater()
安排此对象进行删除。
对象将在控制返回事件循环时被删除。如果在调用此函数时事件循环尚未运行(例如,在调用QCoreApplication::exec之前调用deleteLater()或在对象存活的线程中没有运行的事件循环上调用deleteLater()),一旦事件循环启动,对象将被删除。如果在主事件循环停止后调用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); } );
注意:此函数是线程安全的。
[信号]
void QObject::destroyed(QObject *obj = nullptr)
此信号在对象obj被销毁之前立即发出,在所有QPointer实例被通知后,且无法被阻塞。
在此信号发出后,该对象的全部子对象都将被立即销毁。
另请参阅deleteLater和QPointer。
[静态]
bool QObject::disconnect(const QObject *sender, const char *signal, const QObject *receiver, const char *method)
断开对象sender中的signal与对象receiver中的method之间的连接。如果连接成功断开则返回true
;否则返回false
。
当涉及的对象中的任意对象被销毁时,信号-槽连接将被移除。
disconnect()通常以以下三种方式使用,以下示例将演示这些用法。
- 断开与对象信号相连的所有连接
disconnect(myObject, nullptr, nullptr, nullptr);
与以下非静态重载函数等价
myObject->disconnect();
- 断开与特定信号相连的所有连接
disconnect(myObject, SIGNAL(mySignal()), nullptr, nullptr);
与以下非静态重载函数等价
myObject->disconnect(SIGNAL(mySignal()));
- 断开特定的接收者
disconnect(myObject, nullptr, myReceiver, nullptr);
与以下非静态重载函数等价
myObject->disconnect(myReceiver);
nullptr
可作为通配符使用,分别表示“任何信号”、“任何接收对象”或“接收对象中的任何槽”。
sender永远不能为nullptr
。(您不能在单个调用中从多个对象中断开信号。)
如果signal为nullptr
,它将断开receiver和method与任何信号的连接。如果不为nullptr
,则只断开指定的信号。
如果receiver为nullptr
,则断开与signal相关的所有连接。如果不为nullptr
,则除了receiver以外的对象中的槽不将被断开。
如果method为nullptr
,则断开与receiver相关的所有连接。如果不为nullptr
,则只有名为method的槽将被断开,其他槽保持不变。如果省略receiver,则method必须为nullptr
,因此您不能断开所有对象上特定命名的槽。
注意:断开所有信号-槽连接也会断开如果连接了的话QObject::destroyed() 信号。这样做可能会对公司资源进行清理的类产生不良影响。建议只断开由应用程序代码连接的特定信号。
注意:此函数是线程安全的。
另请参阅connect。
[静态]
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 实例不表示信号。
QMetaMethod() 可以用作代表 "任何信号" 或 "接收对象中的任何槽" 的通配符。同样的,nullptr
可以用于 receiver,表示 "任何接收对象"。在这种情况下,方法也应为 QMetaMethod()。sender 参数不得为 nullptr
。
注意:断开所有信号-槽连接也会断开如果连接了的话QObject::destroyed() 信号。这样做可能会对公司资源进行清理的类产生不良影响。建议只断开由应用程序代码连接的特定信号。
另请参阅disconnect(const QObject *sender, const char *signal, const QObject *receiver, const char *method)。
bool QObject::disconnect(const char *signal = nullptr, const QObject *receiver = nullptr, const char *method = nullptr) const
此函数是 disconnect() 的重载。
从接收者 receiver 的 method 中断开 signal。
当涉及的对象中的任意对象被销毁时,信号-槽连接将被移除。
注意:断开所有信号-槽连接也会断开如果连接了的话QObject::destroyed() 信号。这样做可能会对公司资源进行清理的类产生不良影响。建议只断开由应用程序代码连接的特定信号。
注意:此函数是线程安全的。
bool QObject::disconnect(const QObject *receiver, const char *method = nullptr) const
此函数是 disconnect() 的重载。
从此对象的所有信号中断开接收者 receiver 的 method。
当涉及的对象中的任意对象被销毁时,信号-槽连接将被移除。
[静态]
bool QObject::disconnect(const QMetaObject::Connection &connection)
断开一个连接。
如果 connection 无效或已被断开,则不执行任何操作并返回 false。
另请参阅connect。
[静态]
模板 <typename PointerToMemberFunction> bool QObject::disconnect(const QObject *sender, PointerToMemberFunction signal, const QObject *receiver, PointerToMemberFunction method)
此函数是 disconnect() 的重载。
断开对象sender中的signal与对象receiver中的method之间的连接。如果连接成功断开则返回true
;否则返回false
。
当涉及的对象中的任意对象被销毁时,信号-槽连接将被移除。
disconnect()通常以以下三种方式使用,以下示例将演示这些用法。
- 断开与对象信号相连的所有连接
disconnect(myObject, nullptr, nullptr, nullptr);
- 断开与特定信号相连的所有连接
disconnect(myObject, &MyObject::mySignal(), nullptr, nullptr);
- 断开特定的接收者
disconnect(myObject, nullptr, myReceiver, nullptr);
- 断开从特定信号到特定槽的连接
nullptr
可作为通配符使用,分别表示“任何信号”、“任何接收对象”或“接收对象中的任何槽”。
sender永远不能为nullptr
。(您不能在单个调用中从多个对象中断开信号。)
如果signal为nullptr
,它将断开receiver和method与任何信号的连接。如果不为nullptr
,则只断开指定的信号。
如果 receiver 是 nullptr
,则断开与 signal 相连的任何内容。如果不是,则只断开指定接收者中的槽。使用非空 receiver 的 disconnect() 还会断开使用 receiver 作为其上下文对象的连接。
如果method为nullptr
,则断开与receiver相关的所有连接。如果不为nullptr
,则只有名为method的槽将被断开,其他槽保持不变。如果省略receiver,则method必须为nullptr
,因此您不能断开所有对象上特定命名的槽。
注意:无法使用这个重载断开连接到函数子或lambda表达式的信号。这是因为无法比较它们。相反,请使用接受QMetaObject::Connection的重载
注意:此函数是线程安全的。
另请参阅connect。
[虚,保护]
void QObject::disconnectNotify(const QMetaMethod &signal)
当此对象中的 signal 被断开连接时,将调用此虚拟函数。
查看 connectNotify() 了解如何比较 signal 与特定信号。
如果所有信号都已从该对象断开连接(例如,disconnect() 的信号参数为 nullptr
),则 disconnectNotify() 只被调用一次,而 signal 将是一个无效的 QMetaMethod (QMetaMethod::isValid() 返回 false
)。
警告:此函数违反了面向对象模块化原则。然而,在优化对昂贵资源的访问时可能很有用。
警告:此函数是由执行断开的线程调用的,这可能不同于该对象所在的线程。此函数还可以在对象内部锁定的情况下调用。因此,不允许从您自己的重实现中重新进入任何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()动态添加到对象的属性名称。
[虚拟]
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()。
[虚拟]
bool QObject::eventFilter(QObject *watched, QEvent *event)
如果此对象被安装为监视对象的过滤器,则过滤事件。
在您对此函数的重实现中,如果想要过滤掉事件,即停止事件被进一步处理,则返回 true;否则返回 false。
示例
class MainWindow : public QMainWindow { public: MainWindow(); protected: bool eventFilter(QObject *obj, QEvent *ev) override; private: QTextEdit *textEdit; }; MainWindow::MainWindow() { textEdit = new QTextEdit; setCentralWidget(textEdit); textEdit->installEventFilter(this); } bool MainWindow::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 { // pass the event on to the parent class return QMainWindow::eventFilter(obj, event); } }
注意上述示例中将未处理的事件传递到基类的 eventFilter() 函数,因为基类可能已经为自身内部目的重写了 eventFilter()。
某些事件,例如 QEvent::ShortcutOverride,必须显式接受(通过对它们调用 accept())以防止传播。
警告:如果在函数中删除了接收器对象,请确保返回 true。否则,Qt 会将事件转发到已删除的对象,程序可能会崩溃。
另请参阅 installEventFilter。
模板 <typename T> T QObject::findChild(QAnyStringView name, Qt::FindChildOptions options = Qt::FindChildrenRecursively) const
返回此对象的子对象,该子对象可以转换为类型 T,并且名称为 name,如果没有此类对象,则返回 nullptr
。如果 name 参数为 null,则匹配所有对象。一个空且非 null 的 name 只匹配 objectName 为空的那些对象。搜索是递归的,除非 options 指定了选项 FindDirectChildrenOnly。
如果在搜索中有多个匹配的子对象,将返回最直接的祖先。如果有几个最直接的祖先,则返回 children() 中的第一个子对象。在这种情况下,最好使用 findChildren() 来获取所有子对象的完整列表。
此示例返回名为 "button1"
的 QPushButton
子对象,即使该按钮不是父对象的直接子对象
QPushButton *button = parentWidget->findChild<QPushButton *>("button1");
此示例返回 QListWidget
子对象,该子对象属于 parentWidget
QListWidget *list = parentWidget->findChild<QListWidget *>();
此示例返回名为 "button1"
的 QPushButton
子对象(其直接父对象)
QPushButton *button = parentWidget->findChild<QPushButton *>("button1", Qt::FindDirectChildrenOnly);
此示例返回属于 parentWidget
的 QListWidget
子对象,其直接父对象
QListWidget *list = parentWidget->findChild<QListWidget *>(Qt::FindDirectChildrenOnly);
注意:在 6.7 版本之前的 Qt 中,此函数将 name 作为 QString
而不是 QAnyStringView
处理。
另请参阅 findChildren。
[since 6.7]
模板 <typename T> T QObject::findChild(Qt::FindChildOptions options = Qt::FindChildrenRecursively) const
这是一个重载函数。
返回可以转换为类型 T 的子对象,如果没有此类对象,则返回 nullptr
。除非 options 指定了选项 FindDirectChildrenOnly,否则搜索是递归的。
如果在搜索中有多个匹配的子对象,将返回最直接的祖先。如果有几个最直接的祖先,则返回 children() 中的第一个子对象。在这种情况下,最好使用 findChildren() 来获取所有子对象的完整列表。
此函数是在 Qt 6.7 中引入的。
另请参阅 findChildren。
模板 <typename T> QList<T> QObject::findChildren(QAnyStringView name, Qt::FindChildOptions options = Qt::FindChildrenRecursively) const
返回具有给定 name 且可转换为类型 T 的所有子对象,如果没有此类对象,则返回空列表。如果 name 参数为 null,则匹配所有对象,如果为空则仅匹配 objectName 为空的那些对象。除非 options 指定了选项 FindDirectChildrenOnly,否则搜索是递归的。
以下示例展示了如何找到名为widgetname
的指定parentWidget
的所有子QWidget列表。
此示例返回所有parentWidget
的子QPushButton
控件。
QList<QPushButton *> allPButtons = parentWidget.findChildren<QPushButton *>();
此示例返回所有直接为parentWidget
子控件的QPushButton
控件。
QList<QPushButton *> childButtons = parentWidget.findChildren<QPushButton *>(Qt::FindDirectChildrenOnly);
注意:在 6.7 版本之前的 Qt 中,此函数将 name 作为 QString
而不是 QAnyStringView
处理。
另请参阅 findChild
[自6.3以来]
模板 <typename T> QList<T> QObject::findChildrenQt::FindChildOptions options = Qt::FindChildrenRecursively) const
这是一个重载函数。
返回所有可以转换为类型T的对象的子对象,如果没有此类对象则返回空列表。除非options指定了FindDirectChildrenOnly选项,否则搜索是递归的。
此函数自Qt 6.3开始引入。
另请参阅 findChild
模板 <typename T> QList<T> QObject::findChildrenQRegularExpression &re, Qt::FindChildOptions options = Qt::FindChildrenRecursively) const
此函数重载了findChildren。
返回可以转换为类型T且名称匹配正则表达式re的所有子对象,如果没有此类对象则返回空列表。除非options指定了FindDirectChildrenOnly选项,否则搜索是递归的。
bool QObject::inherits(const char *className) const
如果此对象是继承自className的类的实例,或者继承自QObject子类并且继承自className,则返回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
类,它吞噬它监视的对象的按键
class KeyPressEater : public QObject { Q_OBJECT ... protected: bool eventFilter(QObject *obj, QEvent *event) override; }; bool KeyPressEater::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 { // standard event processing return QObject::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()。
[since 6.4]
bool QObject::isQuickItemType() const
如果对象是 QQuickItem,则返回 true
;否则返回 false
。
调用此函数相当于调用 inherits("QQuickItem")
,但速度更快。
此函数是在 Qt 6.4 中引入的。
[受保护]
bool QObject::isSignalConnected(const QMetaMethod &signal) const
如果signal 至少连接了一个接收器,则返回 true
;否则返回 false
。
signal 必须是此对象的一个信号成员,否则行为是未定义的。
static const QMetaMethod valueChangedSignal = QMetaMethod::fromSignal(&MyObject::valueChanged); if (isSignalConnected(valueChangedSignal)) { QByteArray data; data = get_the_value(); // expensive operation emit valueChanged(data); }
如上述代码片段所示,您可以使用此函数来避免昂贵的初始化或发出没有人监听的事件。然而,在多线程应用程序中,连接可能会在此函数返回之后和信号发出之前更改。
警告:此函数违反了面向对象的设计模块化原则。特别是,不应从 connectNotify() 或 disconnectNotify 的重写中调用此函数,因为它们可能从任何线程中被调用。
bool QObject::isWidgetType() const
如果对象是窗口;否则返回 false
。
调用此函数相当于调用 inherits("QWidget")
,但速度更快。
bool QObject::isWindowType() const
如果对象是窗口;否则返回 false
。
调用此函数相当于调用 inherits("QWindow")
,但速度更快。
void QObject::killTimer(int id)
停止具有定时器标识符 id 的计时器。
当定时器事件开始时,由 startTimer() 返回定时器标识符。
另请参阅timerEvent() 和 startTimer()。
[纯虚函数]
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中重新启动(具有相同的间隔)。因此,不断在线程之间移动对象可以将计时器事件无限期推迟。
在更改线程亲和力之前,向此对象发送QEvent::ThreadChange事件。您可以通过处理此事件来完成任何特殊处理。注意,如果targetThread不是nullptr
,则将在此对象上处理任何新发布的事件,并且在targetThread中处理,如果它是nullptr
,则不对此对象或其子对象进行任何事件处理,因为它们不再与任何线程相关联。
警告:该函数不是线程安全的;当前线程必须与当前线程亲和力相同。换句话说,这个函数只能“推送”当前线程上的对象到其他线程,而不能从任何任意的线程“拉取”对象到当前线程。然而,有一条例外规则:没有线程亲和力的对象可以被“拉取”到当前线程。
另请参阅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()。
[保护]
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); }
注意:此函数违反了面向对象的原则模块化。然而,在需要仅当某个东西连接到信号才执行昂贵的初始化时,可能很有用。
另请参阅 isSignalConnected()。
void QObject::removeEventFilter(QObject *obj)
从该对象移除事件过滤器对象obj。如果这样的过滤器尚未安装,则忽略请求。
当该对象被销毁时,将自动移除该对象的所有事件过滤器。
在事件过滤器激活期间(即从eventFilter()函数)移除事件过滤器总是安全的。
另请参阅 installEventFilter(),eventFilter(),以及event()。
[保护]
QObject *QObject::sender() const
如果在由信号激活的槽中调用,则返回发送信号的对象的指针;否则返回 nullptr
。该指针仅在从该对象的线程上下文执行调用此函数的槽的执行期间有效。
如果发送器被销毁,或从发送者的信号中断开槽,则此函数返回的指针变为无效。
警告:此函数违反了面向对象的原则——模块化。然而,在许多信号连接到单个槽的情况下,获取发送者的访问权限可能是有用的。
警告:如前所述,当槽通过来自不同于该对象线程的Qt::DirectConnection方式调用时,此函数的返回值无效。不要在此类场景中使用此函数。
另请参阅 senderSignalIndex()。
[保护]
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()。
[自 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()。
[自 6.6]
bool QObject::setProperty(const char *name, QVariant &&value)
这个函数是对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);
另请参阅:timerEvent(),killTimer()和QTimer::singleShot()。
int QObject::startTimer(std::chrono::milliseconds interval, Qt::TimerType timerType = Qt::CoarseTimer)
这是一个重载函数。
启动计时器并返回计时器标识符,如果无法启动计时器则返回零。
在调用 killTimer() 之前,每当没有更多窗口系统事件处理时,计数器事件将每 interval 次出现一次。如果 interval 等于 std::chrono::duration::zero()
,则每次没有更多窗口系统事件处理时计时器事件发生一次。
当计数器事件发生时,会使用 QTimerEvent 事件参数类调用虚拟函数 timerEvent()。通过重写此函数可以获取计时器事件。
如果正在运行多个计时器,则可以使用 QTimerEvent::timerId() 来找出哪个计时器被激活。
示例
class MyObject : public QObject { Q_OBJECT public: MyObject(QObject *parent = nullptr); protected: void timerEvent(QTimerEvent *event) override; }; MyObject::MyObject(QObject *parent) : QObject(parent) { startTimer(50); // 50-millisecond timer startTimer(1000); // 1-second timer startTimer(60000); // 1-minute timer using namespace std::chrono; startTimer(milliseconds(50)); startTimer(seconds(1)); startTimer(minutes(1)); // since C++14 we can use std::chrono::duration literals, e.g.: startTimer(100ms); startTimer(5s); startTimer(2min); startTimer(1h); } void MyObject::timerEvent(QTimerEvent *event) { qDebug() << "Timer ID:" << event->timerId(); }
请注意,QTimer 的精度取决于底层操作系统和硬件。《i translate="no">timerType》参数允许您自定义计时器的精度。有关不同计时器类型的信息,请参阅Qt::TimerType。大多数平台支持20毫秒的精度;有些提供更高的精度。如果 Qt 无法传递请求的计时器事件数量,它将以静默方式丢弃一些。
QTimer 类提供了一种高级编程接口,其中使用了单次计时的计时器和计时器信号,而不是事件。还有一个更轻量级的 QBasicTimer 类,它比 QTimer 更轻量级,比直接使用计时器 ID 更易于使用。
另请参阅:timerEvent(),killTimer()和QTimer::singleShot()。
QThread *QObject::thread() const
返回对象所生活的线程。
另请参阅 moveToThread()。
[virtual protected]
void QObject::timerEvent(QTimerEvent *event)
此事件处理程序可以在子类中重写以接收对象的计时器事件。
QTimer 提供了一个更高级别的计时器功能接口,以及有关计时器的更一般信息。计时器事件通过 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 的翻译机制的一般描述,以及有关 Disambiguate Identical Text 部分以获取歧义解决信息。
警告: 此方法只有在所有翻译器在调用此方法之前都已安装时才是可重入的。在执行翻译时安装或删除翻译器是不受支持的。这样做可能会导致崩溃或其他不可预期的行为。
另请参阅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().
相关非成员
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 == nullptr
qobject_cast() 函数的行为类似于标准 C++ dynamic_cast()
,其优点是不需要 RTTI 支持并且可以在动态库边界之间工作。
qobject_cast() 还可以与接口一起使用。
注意:如果 T 没有使用 }Q_OBJECT 宏声明,则此函数的返回值是未定义的。
另请参阅QObject::inherits().
QObjectList
宏文档
[自 6.7 版起]
QT_NO_CONTEXTLESS_CONNECT
定义此宏将禁用 }QObject::connect() 的重载,该重载连接一个信号到一个处理函数,而不指定一个 }QObject 作为接收器/上下文对象(即,}QObject::connect() 的 3 个参数重载)。
使用无上下文的重载是易出错的,因为它很容易连接到依赖于接收端某些本地状态的处理函数。如果这种本地状态被销毁,连接不会自动断开。
此外,此类连接始终是直接连接,这可能在多线程场景中引起问题(例如,如果信号是从另一个线程发出的)。
此宏在 Qt 6.7 中引入。
另请参阅QObject::connect 和 Qt::ConnectionType.
QT_NO_NARROWING_CONVERSIONS_IN_CONNECT
定义此宏将禁用信号和槽在 PMF 语法中连接时,参数的缩放转换和浮点数到整数的转换。
另请参阅QObject::connect.
Q_CLASSINFO(名称, 值)
此宏将附加信息关联到类,这些信息可以通过QObject::metaObject() 使用。附加信息以 名称 字符串和 值 字面字符串的形式存在。
示例
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 对象类型 时,可以将属性指定为 默认 属性
Q_CLASSINFO("DefaultProperty", "content")
参阅QMetaObject::classInfo(),使用 Qt D-Bus Adaptors,和 从 C++ 定义 QML 类型。
Q_EMIT
当您想要使用 Qt Signals 和 Slots 与一个 第三方信号/槽机制 时,请使用此宏来替换 emit
关键字。
通常情况下,此宏在指定了 no_keywords
的 .pro
文件中的 CONFIG
变量时使用,但如果未指定 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 声明的枚举将在包含的 QMetaObject 中注册其 QMetaEnum。您也可以使用 QMetaEnum::fromType() 来获取 QMetaEnum。
已注册的枚举将自动注册到 Qt 元类型系统中,使它们无需使用 Q_DECLARE_METATYPE 即可通过 QMetaType 访问。这将启用一些有用的功能;例如,如果用于一个 QVariant,您可以将其转换为字符串。同样,将它们传递到 QDebug 将会打印出它们的名称。
请注意,枚举值以有符号的 int
在元对象系统中存储。将值注册为超出 int
有效值范围的枚举将导致溢出,并通过元对象系统访问时可能出现未定义的行为。例如,QML 通过元对象系统访问已注册的枚举。
参阅Qt 的属性系统。
Q_ENUM_NS(...)
此宏将枚举类型注册到元对象系统中。必须将此宏放置在具有 Q_NAMESPACE 宏的命名空间中。它与 Q_ENUM 功能相同,但用于命名空间。
使用 Q_ENUM_NS 声明的枚举将在包含的 QMetaObject 中注册其 QMetaEnum。您也可以使用 QMetaEnum::fromType() 来获取 QMetaEnum。
已注册的枚举将自动注册到 Qt 元类型系统中,使它们无需使用 Q_DECLARE_METATYPE 即可通过 QMetaType 访问。这将启用一些有用的功能;例如,如果用于一个 QVariant,您可以将其转换为字符串。同样,将它们传递到 QDebug 将会打印出它们的名称。
请注意,枚举值以有符号的 int
在元对象系统中存储。将值注册为超出 int
有效值范围的枚举将导致溢出,并通过元对象系统访问时可能出现未定义的行为。例如,QML 通过元对象系统访问已注册的枚举。
参阅Qt 的属性系统。
Q_FLAG(...)
此宏将单个 flags 类型 注册到元对象系统中。它通常用于类定义中,以声明给定枚举的值可以用作标记并且可以使用按位或运算符组合。对于命名空间,请使用 Q_FLAG_NS()。
该宏必须在枚举声明之后放置。flag类型的声明是通过使用Q_DECLARE_FLAGS() 宏来完成的。
例如,在QItemSelectionModel中,SelectionFlags 标志的声明方式如下
class 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 宏负责将单个flag值注册到元对象系统中,因此除了这个宏之外,没有必要使用Q_ENUM()。
参阅Qt 的属性系统。
Q_FLAG_NS(...)
这个宏将单个flags类型注册到元对象系统。它在具有Q_NAMESPACE宏的命名空间中使用,用来声明给定枚举的值可以作为标志并使用按位或运算符进行组合。它与Q_FLAG相同,但位于命名空间中。
该宏必须放在枚举声明之后。
注意: Q_FLAG_NS 宏负责将单个flag值注册到元对象系统,因此除了这个宏之外,没有必要使用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
变量是以所提供的EXPORT_MACRO修饰符声明的(参见Q_GADGET)。这对于需要从动态库导出对象但整个封装类不应导出的情况很有用(例如,因为它们主要由内联函数组成)。
注意: 这个宏扩展以一个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 或其子类的指针,并且从 QML 调用,则适用特殊的所有权规则。有关更多信息,请参阅 QML 和 C++ 之间的数据类型转换。
[since 6.0]
Q_MOC_INCLUDE
Q_MOC_INCLUDE 宏可以在类内部或外部使用,并告诉 元对象编译器 添加包含。
// 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。
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] [REQUIRED])
需要属性名称和类型以及READ
函数。类型可以是QVariant支持的任何类型,也可以是用户自定义类型。其他项都是可选的,但常见的有一个WRITE
函数。默认情况下,除了USER
属性默认为false之外,所有属性默认为true。
例如
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
或更高时,新属性和新方法才会在这个代码中公开。
如果未标记,则认为所有方法都属于修订0
,因此标记为Q_REVISION(0)
或Q_REVISION(0, 0)
是无效的,将被忽略。
您可以向Q_REVISION
传递一个或两个整型参数。如果您传递一个参数,它仅表示次版本。这意味着主版本是不指定的。如果传递两个,第一个参数是主版本,第二个参数是次版本。
此标记本身不由元对象系统使用。目前,这仅由QtQml模块使用。
有关更通用的字符串标记,请参阅QMetaMethod::tag()
Q_SET_OBJECT_NAME(Object)
此宏将Object的objectName设置为"Object"。
无论Object是指针还是非指针,宏都会自己判断。
另请参阅QObject::objectName。
Q_SIGNAL
这是一个额外的宏,允许您将单个函数标记为信号。它非常有用,特别是在您使用第三方源代码解析器时,该解析器不理解signals
或Q_SIGNALS
组。
当您希望与第三方信号/槽机制一起使用Qt信号和槽时,请使用此宏替换类声明中的signals
关键字。
通常情况下,此宏在指定了 no_keywords
的 .pro
文件中的 CONFIG
变量时使用,但如果未指定 no_keywords
也可以使用。
Q_SIGNALS
当您希望与第三方信号/槽机制一起使用Qt信号和槽时,请使用此宏替换类声明中的signals
关键字。
通常情况下,此宏在指定了 no_keywords
的 .pro
文件中的 CONFIG
变量时使用,但如果未指定 no_keywords
也可以使用。
Q_SLOT
这是一个额外的宏,允许您将单个函数标记为槽。它非常有用,特别是在您使用第三方源代码解析器时,该解析器不理解slots
或Q_SLOTS
组。
当您希望与第三方信号/槽机制一起使用Qt信号和槽时,请使用此宏替换类声明中的slots
关键字。
通常情况下,此宏在指定了 no_keywords
的 .pro
文件中的 CONFIG
变量时使用,但如果未指定 no_keywords
也可以使用。
Q_SLOTS
当您希望与第三方信号/槽机制一起使用Qt信号和槽时,请使用此宏替换类声明中的slots
关键字。
通常情况下,此宏在指定了 no_keywords
的 .pro
文件中的 CONFIG
变量时使用,但如果未指定 no_keywords
也可以使用。
© 2024 The Qt Company Ltd. 本文件中包含的文档贡献均属各自所有者的版权。本文件提供的文档是根据由自由软件基金会发布的GNU自由文档许可证版本1.3的条款授权的。Qt及其相关徽标是芬兰及/或全球其他国家的The Qt Company Ltd.的商标。所有其他商标均为各自所有者的财产。