Qt QObject 函数

QObject 函数

成员函数文档

QObject::QObject(QObject *parent = nullptr)
  • 用父对象构造一个对象。
  • 对象的父对象可以看作是对象的所有者。
    • 例如,一个对话框(dialog box)是它包含的OK和Cancel按钮的父元素。
  • 父对象的析构函数销毁所有子对象。
  • 将parent设置为nullptr将构造一个没有父对象的对象。
    • 如果对象是一个小部件,它将成为一个顶级窗口。
  • 注意:这个函数可以通过元对象系统和QML调用。参考 Q_INVOKABLE.。
  • 可参考:parent(), findChild(), 和findChildren().

 

[slot] void QObject::deleteLater()
  • 计划删除此对象。
  • 当控件返回到事件循环时,该对象将被删除。
    • 如果该函数被调用时事件循环没有运行(例如在 QCoreApplication::exec()之前对一个对象调用deleteater()),该对象将在事件循环启动后被删除。
    • 如果在主事件循环停止后调用deleteLater(),对象将不会被删除。
    • 从Qt 4.8开始,如果deleteLater()被一个没有运行事件循环的线程中的对象调用,该对象将在线程结束时被销毁。
  • 请注意,进入和离开一个新的事件循环(例如,通过打开一个模态对话框)将不会执行延迟删除;对于要删除的对象,控件必须返回到调用deleteater()的事件循环中。
    • 这不适用于在之前嵌套事件循环仍在运行时删除的对象:  Qt事件循环将在新的嵌套事件循环开始时删除这些对象。
  • 注意: 多次调用这个函数是安全的;当传递第一个延迟删除事件时,对象的任何挂起事件都将从事件队列中删除。
  • 注意:这个函数是线程安全的。
  • 参考: destroyed() 和 QPointer.

 

[signal] void QObject::destroyed(QObject *obj = nullptr)
  • 该信号在对象obj被销毁之前立即发出,在 QPointer的任何实例被通知之后,不能被阻塞。
  • 所有对象的子对象在这个信号发出后立即销毁。

 

[signal]void QObject::objectNameChanged(const QString &objectName)
  • 该信号在对象的名称被更改后发出。
    • 新的对象名作为objectName传递。
  • 注意:这是一个私有信号。它可以用于信号连接,但不能由用户发出。
  • 注意:属性 objectName 的通知信号。
  • 参考:QObject::objectName

 

[virtual] QObject::~QObject()
  • 销毁该对象,删除其所有子对象。
  • 所有进出该对象的信号将自动断开连接,对象的任何挂起的已发布事件将从事件队列中删除。
    • 但是,通常使用deleteLater()比直接删除QObject子类更安全。
  • 警告: 删除所有子对象。如果这些对象中的任何一个在堆栈上或全局上,您的程序迟早会崩溃。
    • 我们不建议从父对象外部持有指向子对象的指针。如果您仍然这样做,则 destroyed()  信号给您提供了一个检测对象何时被销毁的机会。
  • 警告: 在等待交付挂起事件时,删除QObject可能会导致崩溃。
    • 如果QObject存在于与当前正在执行的线程不同的线程中,则不能直接删除它。而是使用 deleteLater(),这将导致事件循环在所有挂起的事件都交付给该对象之后删除该对象。

 

bool QObject::blockSignals(bool block)
  • 如果block为true,则该对象发出的信号将被阻塞(即,发出一个信号将不会调用任何连接到它的对象)。如果block为false,则不会发生阻塞。
  • 返回值是 signalsBlocked()的前一个值。
  • 注意,即使这个对象的信号被阻塞, destroyed()信号也会被发出。
  • 阻塞时发出的信号不会被缓冲。
  • 参考:signalsBlocked() 和 QSignalBlocker.

 

[virtual protected]  void QObject::childEvent(QChildEvent *event)
  • 可以在子类中重新实现此事件处理程序以接收子事件。事件通过事件参数 event 传递。
  • 当添加或删除子对象时,QEvent::ChildAdded 和QEvent::ChildRemoved事件被发送给对象。
    • 在这两种情况下,您只能依赖于子对象是QObject,或者如果 isWidgetType()返回true,则是QWidget.。(这是因为,在ChildAdded 情况下,子对象还没有完全构造,而在ChildRemoved情况下,它可能已经被销毁了)。
  • 子部件被抛光或被抛光的子部件被添加时,QEvent::ChildPolished 事件被发送给小部件。
    • 如果你收到一个子对象抛光事件,子对象的构造通常是完成的。但是,这并不能保证,而且在小部件构造函数的执行期间可能会交付多个polish事件。
  • 对于每个子部件,您将收到一个ChildAdded 事件、0个或多个ChildPolished事件和一个ChildRemoved 事件。
  • 如果一个子元素在添加后被立即删除,则ChildPolished事件将被省略。
    • 如果一个子节点在构造和销毁过程中被抛光了多次,那么您可能会收到同一个子节点的多个子节点抛光事件,每次都使用不同的虚表。
  • 参考:event().

 

const QObjectList &QObject::children() const
  • 返回子对象列表, QObjectList类在<QObject>头文件中定义如下:
typedef QList<QObject*> QObjectList;
  • 添加的 first子元素是列表中的第一个对象,添加的 last 子元素是列表中的最后一个对象,也就是说,新的子元素会添加到列表的末尾。
  • 请注意,当raised 和lowered QWidget子组件时,列表顺序会发生变化。
    • 被 raised  的小部件将成为列表中的最后一个对象,而被lowered 的小部件将成为列表中的第一个对象。
  • 参考:findChild(), findChildren(), parent(), 和setParent()。

 

[static]QMetaObject::Connection QObject::connect(const QObject *sender, 
const char *signal,const QObject *receiver, const char *method, 
Qt::ConnectionType type = Qt::AutoConnection)
  • 创建从发送方对象中的信号到接收方对象中的方法的给定类型连接。
  • 返回连接的句柄,该句柄可用于稍后断开连接。
  • 当指定信号和方法时,必须使用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 类型,那么只有当它不是一个重复的连接时,才会建立连接。
    • 如果已经有一个副本(相同对象上相同槽位的相同信号),连接将失败,连接将返回一个无效的QMetaObject:: connection。
  • 注意: Qt::UniqueConnections不工作lambda,非成员函数和仿函数;它们只适用于连接到成员函数。
  • 选参数type描述要建立的连接类型。
    • 具体来说,它决定一个特定的信号是立即被交付到一个槽中,还是在以后排队交付。
    • 如果信号在队列中,参数必须是Qt元对象系统已知的类型,因为Qt需要复制参数来将它们存储在幕后的事件中。
    • 如果您尝试使用队列连接并获得错误消息:
QObject::connect: Cannot queue arguments of type 'MyType'
(Make sure 'MyType' is registered using qRegisterMetaType().)

 

[static] QMetaObject::Connection QObject::connect(const QObject *sender, 
const QMetaMethod &signal, const QObject *receiver, 
const QMetaMethod &method, Qt::ConnectionType type = Qt::AutoConnection)
  • 创建从发送方对象中的信号到接收方对象中的方法的给定类型连接。返回连接的句柄,该句柄可用于稍后断开连接。
  • 如果不能创建连接,连接句柄将无效,例如,参数无效。你可以通过将 QMetaObject::Connection 转换为bool类型来检查它是否有效。
  • 此函数的工作方式与 connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type) 相同,但它使用 QMetaMethod 来指定信号和方法。
  • 该函数是在Qt 4.8中引入的。
QMetaObject::Connection QObject::connect(const QObject *sender, const char *signal, 
const char *method, Qt::ConnectionType type = Qt::AutoConnection) const
  • 这个函数重载了connect()。
  • 将来自发送方对象的信号连接到该对象的方法。
  • 相当于connect(sender, signal, this, method, type)。
  • 你建立的每一个连接都会发出一个信号,所以重复的连接会发出两个信号。您可以使用disconnect()来断开连接。
  • 注意:这个函数是线程安全的。
  • 参考:disconnect().

 

[static] template <typename PointerToMemberFunction> QMetaObject::Connection QObject::connect(const 
QObject *sender, PointerToMemberFunction signal, const QObject *receiver, 
PointerToMemberFunction method, Qt::ConnectionType type = Qt::AutoConnection)
  • 这个函数重载了connect()。
  • 创建从发送方对象中的信号到接收方对象中的方法的给定类型连接。返回连接的句柄,该句柄可用于稍后断开连接。
  • 信号必须是在头文件中声明为信号的函数。槽函数可以是任何可以连接到信号的成员函数。
    • 如果信号的参数至少与槽的参数相同,且信号中相应参数的类型与槽的类型之间存在隐式转换,则可以将槽连接到给定的信号。
  • 示例:
QLabel *label = new QLabel;
QLineEdit *lineEdit = new QLineEdit;
QObject::connect(lineEdit, &QLineEdit::textChanged,
                 label,  &QLabel::setText);
  • 此示例确保标签始终显示当前行编辑文本。
  • 一个信号可以连接到多个插槽和信号。许多信号可以连接到一个槽。
  • 如果一个信号被连接到多个插槽,当信号被发射时,插槽将按照连接的顺序被激活
  • 确保使用Q_DECLARE_METATYPE声明参数类型
  • 重载函数可以通过 qOverload来解决
  • 注意:这个函数是线程安全的
  • 参考: Differences between String-Based and Functor-Based Connections.

 

[static] template <typename PointerToMemberFunction, typename Functor> QMetaObject::Connection 
QObject::connect(const QObject *sender, PointerToMemberFunction signal, Functor functor)
  • 这个函数重载了connect()。
  • 创建一个从sender对象中的signal到functor的连接,并返回该连接的句柄。
  • 信号必须是在头文件中声明为信号的函数。
    • 槽函数可以是任何函数或函数,可以连接到信号。
    • 如果一个函数可以连接到一个给定的信号,信号至少有与槽一样多的参数。
    • 如果一个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");
    });
  • 如果发送者被销毁,连接将自动断开。但是,您应该注意,当发出信号时,函数内使用的任何对象仍然是活动的。
  • 重载函数可以通过 qOverload 来解决。
  • 注意:这个函数是线程安全的

 

template <typename PointerToMemberFunction, typename Functor> QMetaObject::Connection 
QObject::connect(const QObject *sender, PointerToMemberFunction signal, 
const QObject *context, Functor functor, Qt::ConnectionType type = Qt::AutoConnection)
  • 这个函数重载了connect()。
  • 创建一个给定类型的连接,从sender对象中的signal到要放置在特定上下文事件循环中的functor,并返回该连接的句柄。
  • 注意:Qt::UniqueConnections不工作lambda,非成员函数和functors;它们只适用于连接到成员函数。
  • 信号必须是在头文件中声明为信号的函数。
    • 槽函数可以是任何函数或函数,可以连接到信号。
    • 如果一个函数可以连接到一个给定的信号,信号至少有与槽一样多的参数。
    • 如果一个functor可以连接到一个信号,它们有完全相同数量的参数。
    • 信号和槽中相应参数的类型之间必须存在隐式转换。
  • 例子:
void someFunction();
QPushButton *button = new QPushButton;
QObject::connect(button, &QPushButton::clicked, this, someFunction, Qt::QueuedConnection);
  • ambda表达式也可以使用:
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 来解决。
  • 注意:这个函数是线程安全的。
  • 该函数是在Qt 5.2中引入的。

 

[virtual protected] void QObject::connectNotify(const QMetaMethod &signal)
  • 这个虚函数在对象中有东西连接到信号时被调用。
  • 如果你想将信号与特定的信号进行比较,你可以使用 QMetaMethod::fromSignal() 如下所示:
if (signal == QMetaMethod::fromSignal(&MyObject::valueChanged)) {
    // signal is valueChanged
}
  • 警告: 此函数违反了面向对象的模块化原则。但是,当需要执行昂贵的初始化时,它可能很有用,仅当有东西连接到一个信号时。
  • 警告:此函数从执行连接的线程调用,该线程可能与该对象所在的线程不同。
  • 该函数是在Qt 5.0中引入的。

 

[virtual protected]void QObject::customEvent(QEvent *event)
  • 可以在子类中重新实现此事件处理程序以接收自定义事件。
  • 自定义事件是用户定义的事件,其类型值至少和QEvent::Type  enum的 QEvent::User 项一样大,通常是QEvent 的子类。
  • 事件通过event参数传递。
  • 参考:event() and QEvent.

 

[static] bool QObject::disconnect(const QObject *sender, const char *signal, 
const QObject *receiver, const char *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可以用作通配符,分别表示“任何信号”、“任何接收对象”或“接收对象中的任何插槽”。
  • 发送方可能永远不会是nullptr。(您不能在一次调用中断开来自多个对象的信号。)
  • 如果信号为nullptr,它将断开接收器和方法与任何信号的连接。如果不是,则只断开指定的信号。
  • 如果receiver为nullptr,它将断开任何连接到信号的连接。如果不是,接收器以外的对象插槽不会断开。
  • 如果方法为nullptr,它将断开任何连接到receiver的连接。
    • 如果不是,只有命名为方法的插槽将断开连接,所有其他插槽将保持独立。
    • 如果没有使用receiver,则该方法必须为nullptr,因此不能断开所有对象上特定命名的插槽的连接。
  • 注意:这个函数是线程安全的。

 

[static] bool QObject::disconnect(const QObject *sender, const QMetaMethod &signal, 
const QObject *receiver, const QMetaMethod &method)
  • 将对象发送方中的信号从对象接收方中的方法中断开。如果连接成功断开,返回true;否则返回false。
  • 这个函数提供了相同的方式,如disconnect(const QObject *sender, const char *signal, const QObject *receiver, const char *method),但使用 QMetaMethod表示要断开的信号和方法。
  • 另外,这个函数返回false,并且没有信号和插槽断开连接:
    • signal 不是发送方类或其父类之一的成员。
    • method 不是接收方类或其父类之一的成员。
    • signal 实例表示不是信号。
  • QMetaMethod()可以作为通配符使用,意思是“any signal”或“any slot in receiving object”。
    • 同样,nullptr也可以用于receiver,意思是“any receiving object”。在这种情况下,method也应该是QMetaMethod()。发送方参数不应该为nullptr。
  • 该函数是在Qt 4.8中引入的.

 

bool QObject::disconnect(const char *signal = nullptr, 
const QObject *receiver = nullptr, const char *method = nullptr) const
  • 这个函数重载了disconnect()。
  • 从接收器的方法断开信号。
  • 当涉及的任何一个对象被破坏时,信号槽连接被移除。
  • 注意:这个函数是线程安全的。

 

bool QObject::disconnect(const QObject *receiver, const char *method = nullptr) const
  • 这个函数重载了disconnect()。
  • 从接收者的方法中断开该对象中的所有信号。
  • 当涉及的任何一个对象被破坏时,信号槽连接被移除。

 

[static]bool QObject::disconnect(const QMetaObject::Connection &connection)
  • 断开连接。
  • 如果连接无效或已经断开,则不执行任何操作并返回false。

 

[static] template <typename PointerToMemberFunction> bool QObject::disconnect(const QObject *sender,
 PointerToMemberFunction signal, const QObject *receiver, PointerToMemberFunction method)
  • 这个函数重载了disconnect()。
  • 将对象发送方中的信号从对象接收方中的方法中断开。如果连接成功断开,返回true; 否则返回false。
  • 当涉及的任何一个对象被破坏时,信号槽连接被移除。
  • Disconnect()通常有三种使用方式,如下面的例子所示。
  • ①断开与对象信号相关的所有连接:
disconnect(myObject, nullptr, nullptr, nullptr);
  • ②断开连接到特定信号的所有设备
disconnect(myObject, &MyObject::mySignal(), nullptr, nullptr);
  • ③断开特定接收器的连接:
disconnect(myObject, nullptr, myReceiver, nullptr);
  • ④断开从一个特定信号到特定插槽的连接:
QObject::disconnect(lineEdit, &QLineEdit::textChanged,
                 label,  &QLabel::setText);
  • nullptr可以用作通配符,分别表示“any signal"”、“ny receiving object"”或“any slot in the receiving object”。
  • 发送方可能永远不会是nullptr。(您不能在一次调用中断开来自多个对象的信号。)
  • 如果信号为nullptr,它将断开接收器和方法与任何信号的连接。如果不是,则只断开指定的信号。
  • 如果receiver为nullptr,它将断开任何连接到信号的连接。如果不是,接收器以外的对象插槽不会断开。
  • 如果方法为nullptr,它将断开任何连接到receiver的连接。
    • 如果不是,只有命名为方法的插槽将断开连接,所有其他插槽将保持独立。如果没有使用receiver,则该方法必须为nullptr,因此不能断开所有对象上特定命名的插槽的连接。
  • 注意:不可能使用此重载断开连接到函数或lambda表达式的信号。这是因为不可能对它们进行比较。相反,使用接受 QMetaObject::Connection的重载
  • 注意:这个函数是线程安全的.

 

[virtual protected] void QObject::disconnectNotify(const QMetaMethod &signal)
  • 当从该对象中的信号断开连接时,将调用此虚函数。
  • 有关如何将信号与特定信号进行比较的示例,请参见 connectNotify()。
  • 如果从该对象断开所有信号(例如, disconnect()的信号参数为nullptr), disconnectNotify()只被调用一次,信号将是一个无效的 QMetaMethod (QMetaMethod::isValid() 返回false)。
  • 警告:此函数违反了面向对象的模块化原则。但是,它对于优化对昂贵资源的访问可能是有用的。
  • 警告:该函数从执行断开连接的线程调用,该线程可能与该对象所在的线程不同。
    • 这个函数也可以在QObject内部互斥锁上的情况下调用。
    • 因此,在你的重新实现中,它是不允许重新进入任何QObject函数的,如果你在你的重新实现中锁定了一个互斥锁,请确保你调用的QObject函数时,互斥锁不在其他地方,否则会导致死锁。
  • 该函数是在Qt 5.0中引入的。

 

void QObject::dumpObjectInfo() const
  • 将此对象的信号连接等信息转储到调试输出中。
  • 注意:在Qt 5.9之前,该函数不是const。
  • 参考:dumpObjectTree().

 

void QObject::dumpObjectTree() const
  • 将子树转储到调试输出。
  • 注意:在Qt 5.9之前,该函数不是const。

 

QList<QByteArray> QObject::dynamicPropertyNames() const
  • 返回使用 setProperty()动态添加到对象中的所有属性的名称。
  • 该函数是在Qt 4.2中引入的。

 

[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);
    }
};

 

[virtual] 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()  ),以防止传播。
  • 警告: 如果你删除了这个函数中的receiver对象,请确保返回true。否则,Qt将把事件转发给被删除的对象,程序可能会崩溃。
  • 参考:installEventFilter().

 

template <typename T> T QObject::findChild(const QString &name = QString(), 
Qt::FindChildOptions options = Qt::FindChildrenRecursively) const
  • 返回该对象的子对象,该子对象可转换为类型T,称为name,如果没有该对象,则返回nullptr。
  • 省略name参数将导致匹配所有对象名称。
  • 搜索是递归执行的,除非选项指定了选项 FindDirectChildrenOnly
  • 如果有多个子匹配搜索,则返回最直接的祖先。
    • 如果有多个直接祖先,则不确定将返回哪一个。在这种情况下,应该使用 findChildren()。
  • 这个例子返回一个名为"button1"的parentWidget的子QPushButton,即使该按钮不是父元素的直接子元素:
QPushButton *button = parentWidget->findChild<QPushButton *>("button1");
  • 这个例子返回parentWidget的QListWidget子组件:
QListWidget *list = parentWidget->findChild<QListWidget *>();
  • 这个例子返回一个名为"button1"的parentWidget(它的直接父类)的子QPushButton:
QPushButton *button = parentWidget->findChild<QPushButton *>("button1", Qt::FindDirectChildrenOnly);
  • 这个例子返回一个QListWidget的子组件parentWidget,它的直接父组件:
QListWidget *list = parentWidget->findChild<QListWidget *>(QString(), Qt::FindDirectChildrenOnly);

 

template <typename T> QList<T> QObject::findChildren(const QString &name = QString(), 
Qt::FindChildOptions options = Qt::FindChildrenRecursively) const
  • 返回该对象的所有可转换为类型T的子对象,如果没有此类对象,则返回一个空列表。
    • 省略name参数将导致匹配所有对象名称。
    • 搜索是递归执行的,除非选项指定了选项FindDirectChildrenOnly。
  • 下面的例子展示了如何找到一个名为widgetname的指定parentWidget的子QWidgets列表:
QList<QWidget *> widgets = parentWidget.findChildren<QWidget *>("widgetname");
  • 这个例子返回parentWidget的所有子qpushbutton:
QList<QPushButton *> allPButtons = parentWidget.findChildren<QPushButton *>();
  • 这个例子返回parentWidget的所有直接子qpushbutton:
QList<QPushButton *> childButtons = parentWidget.findChildren<QPushButton *>(QString(), Qt::FindDirectChildrenOnly);

 

template <typename T> QList<T> QObject::findChildren(const QRegularExpression &re, 
Qt::FindChildOptions options = Qt::FindChildrenRecursively) const
  • 这个函数重载了findChildren()。
    • 返回可转换为类型T且名称匹配正则表达式re的子对象,如果没有此类对象,则返回空列表。
    • 搜索是递归执行的,除非选项指定了选项FindDirectChildrenOnly。
  • 该函数是在Qt 5.0中引入的

 

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() and qobject_cast().

 

void QObject::installEventFilter(QObject *filterObj)
  • 在此对象上安装事件筛选器filterObj。例如
monitoredObj->installEventFilter(filterObj);
  • 事件筛选器是一个接收  发送到该对象的所有事件的对象。
    • 筛选器可以停止事件或将其转发给此对象
    • 事件过滤器filterObj通过 eventFilter()函数接收事件。
    •  eventFilter()函数必须返回true如果事件应该被过滤(即停止);否则它必须返回false。
  • 如果在单个对象上安装了多个事件筛选器,那么最后安装的筛选器将首先激活。
  • 这是一个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(), and event().

 

[protected] bool QObject::isSignalConnected(const QMetaMethod &signal) const
  • 如果信号连接到至少一个接收器,则返回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);
}
  • 正如上面的代码片段所示,您可以使用此函数来避免发出无人监听的信号。
  • 警告:此函数违反了面向对象的模块化原则。但是,当需要执行昂贵的初始化时,它可能很有用,仅当有东西连接到一个信号时。
  • 函数是在Qt 5.0中引入的。

 

bool QObject::isWidgetType() const
  • 如果对象是widget,则返回true;否则返回false。
  • 调用这个函数等同于调用 inherits(“QWidget”),只是它要快得多。

 

bool QObject::isWindowType() const
  • 如果对象是window则返回true; 否则返回false。
  • 调用这个函数与调用inherits("QWindow")是等价的,只是它要快得多。

 

void QObject::killTimer(int id)
  • 终止带有定时器标识符id的定时器。
  • 计时器标识符在计时器事件启动时由 startTimer() 返回。
  • 参考:timerEvent() and startTimer().

 

[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

 

void QObject::moveToThread(QThread *targetThread)
  • 更改此对象及其子对象的线程关联。如果对象有父对象,则不能移动该对象。事件处理将继续在targetThread中进行。
  • 要将对象移动到主线程,请使用 QApplication::instance() 来检索指向当前应用程序的指针,然后使用QApplication::thread()来检索应用程序所在的线程。例如:
myObject->moveToThread(QApplication::instance()->thread());
  • 如果targetThread为nullptr,则该对象及其子对象的所有事件处理将停止,因为它们不再与任何线程关联。
  • 注意:该对象的所有活动计时器将被重置。
    • 计时器首先在当前线程中停止,
    • 然后在targetThread中重新启动(以相同的间隔)。
    • 因此,在线程之间不断移动对象可能无限期地推迟计时器事件。
  • QEvent::ThreadChange 事件在线程关联被更改之前被发送到该对象。
    • 您可以处理此事件以执行任何特殊处理。
    • 注意,任何提交到该对象的新事件都将在targetThread中处理,前提是它不是nullptr: 当它是nullptr时,此对象及其子对象将不会发生任何事件处理,因为它们不再与任何线程关联。
  • 警告: 这个函数不是线程安全的;当前线程必须与当前线程关联相同。
    • 换句话说,这个函数只能将一个对象从当前线程“push”到另一个线程,它不能将一个对象从任意线程“pull”到当前线程
    • 但是,这个规则有一个例外: 没有线程关联的对象可以被“pulled”到当前线程。
  • 参考: thread().

 

QObject *QObject::parent() const

 

QVariant QObject::property(const char *name) const

 

[protected]int QObject::receivers(const char *signal) const
  • 返回连接到该信号的接收器的数量。
  • 由于插槽和信号都可以用作信号的接收器,并且可以多次建立相同的连接,接收器的数量与这个信号建立的连接数量相同。
  • 当调用这个函数时,你可以使用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(), and event().

 

[protected]QObject *QObject::sender() const
  • 如果在信号激活的槽中调用,则返回发送信号的对象的指针; 否则返回nullptr。该指针仅在从该对象的线程上下文调用该函数的槽执行期间有效。
  • 如果发送方被销毁,或者槽与发送方的信号断开连接,该函数返回的指针将失效。
  • 警告:此函数违反了面向对象的模块化原则。然而,当多个信号连接到单个槽时,访问发送方可能很有用。
  • 警告:如上所述,当从与该对象的线程不同的线程通过 Qt::DirectConnection 调用槽时,该函数的返回值是无效的。不要在这种情况下使用此函数。
  • 参考:senderSignalIndex().

 

[protected] int QObject::senderSignalIndex() const
  • 返回调用当前执行槽的信号的元方法索引,它是由 sender()返回的类的成员。如果在信号激活的槽外调用,则返回-1。
  • 对于带有默认参数的信号,该函数将始终返回带有所有参数的索引,而不管在connect()中使用了哪个参数。
    • 例如,被销毁的信号(QObject *obj = \nullptr)将有两个不同的索引(带参数和不带参数),但这个函数将始终返回带参数的索引。这不适用于重载具有不同参数的信号。
  • 警告:此函数违反了面向对象的模块化原则。然而,当多个信号连接到单个槽时,访问信号索引可能很有用。
  • 警告:当从与该对象的线程不同的线程通过 Qt::DirectConnection 调用槽时,该函数的返回值是无效的。不要在这种情况下使用此函数。
  • 该函数是在Qt 4.8中引入的。
  • 参考:sender(), QMetaObject::indexOfSignal(), 和QMetaObject::method().

 

void QObject::setParent(QObject *parent)
  • 使对象成为父对象的子对象。
  • 参考:parent() 和children().

 

bool QObject::setProperty(const char *name, const QVariant &value)
  • 将对象的name属性的值设置为value。
  • 如果在类中使用 Q_PROPERTY 定义了该属性,则成功返回true,否则返回false。
    • 如果该属性没有使用 Q_PROPERTY 定义,因此没有在元对象中列出,它将作为动态属性添加,并返回false
  • 所有可用属性的信息都是通过 metaObject() 和 dynamicPropertyNames()提供的。
  • 可以使用property()再次查询动态属性,并可以通过将属性值设置为无效的 QVariant 来删除动态属性。
  • 注意: 以“_q_”开头的动态属性是为内部目的保留的。

 

bool QObject::signalsBlocked() const
  • 如果信号被阻塞,返回true;否则返回false。
  • 默认情况下不阻塞信号。
  • 参考:blockSignals() 和 QSignalBlocker.

 

int QObject::startTimer(int interval, Qt::TimerType timerType = Qt::CoarseTimer)
  • 启动计时器并返回一个计时器标识符,如果不能启动计时器则返回零。
  • 计时器事件将每隔 interval  毫秒发生一次,直到调用 killTimer(()。
    • 如果interval为0,则计时器事件在每次没有更多窗口系统事件需要处理时发生一次。
  • 当计时器事件发生时,使用 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的准确性取决于底层操作系统和硬件。timerType参数允许您自定义计时器的准确性。
  • 有关不同定时器类型的信息,请参阅 Qt::TimerType
    • 大多数平台支持20毫秒的精度;一些提供更多。如果Qt不能交付请求数量的计时器事件,它将静默地丢弃一些。
  • QTimer类提供了具有单次计时器和计时器信号(而不是事件)的高级编程接口。
    • 还有一个QBasicTimer类,它比QTimer更轻量级,也比直接使用计时器id更简单。
  • 参考:timerEvent(), killTimer(), 和QTimer::singleShot().

 

int QObject::startTimer(std::chrono::milliseconds time, Qt::TimerType timerType = Qt::CoarseTimer)
  • 这是一个重载函数。
  • 启动计时器并返回一个计时器标识符,如果不能启动计时器则返回零。
  • 计时器事件将在每次间隔时间发生,直到killTimer()被调用。
  • 如果time等于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的准确性取决于底层操作系统和硬件。timerType参数允许您自定义计时器的准确性。
  • 有关不同定时器类型的信息,请参阅 Qt::TimerType
    • 大多数平台支持20毫秒的精度;一些提供更多。如果Qt不能交付请求数量的计时器事件,它将静默地丢弃一些。

 

QThread *QObject::thread() const

 

[virtual protected] void QObject::timerEvent(QTimerEvent *event)
  • 这个事件处理程序可以在子类中重新实现,以接收对象的计时器事件。
  • QTimer 提供了计时器功能的高级接口,以及关于计时器的更多一般信息。计时器事件在事件参数中传递。
  • 参考:startTimer(), killTimer(), 和event().

 

[static] QString QObject::tr(const char *sourceText, const char *disambiguation = nullptr, 
int n = -1)
  • 返回sourceText的翻译版本,可选择基于消除歧义字符串和值n的字符串包含复数; 否则,如果没有合适的翻译字符串,则返回 QString::fromUtf8(sourceText)。
  • 示例:
void MainWindow::createActions()
{
    QMenu *fileMenu = menuBar()->addMenu(tr("&File"));
    ...
  • 如果同一个sourceText在同一上下文中的不同角色中使用,则可以在消除歧义时传递一个附加的标识字符串(默认为nullptr)。
  • 在Qt 4.4及更早的版本中,这是将注释传递给翻译人员的首选方式。
  • 示例:
MyWindow::MyWindow()
{
    QLabel *senderLabel = new QLabel(tr("Name:"));
    QLabel *recipientLabel = new QLabel(tr("Name:", "recipient"));
    ...
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值