QT之QObject简单介绍
QObject简单介绍
QObject是QT框架的核心,在该对象内可以使用QT框架的信号和槽机制。
一个QObject对象创建在另一个QObject类(该类可以称作父类)中,该对象将自动将其自身添加到父对象的孩子列表中。父类拥有对所有子QObject对象的控制权,可以自动在析构函数中删除所有的子对象。
需要使用信号和槽机制的QObject对象,必须在声明类中加入Q_OBJECT宏,该机制依赖于元对象编译器(MOC)。不管有没有用到信号和槽机制,最好都加上该宏,避免出现一些奇怪的问题。
线程关联性
QObject实例对象具有线程的关联性,也就是该实例对象处于某一个线程中。当实例对象接收到排队的信号和发布的事件时,插槽或者事件处理程序将在该对象所在的线程中运行。
注意: 如果实例对象不处于某一个线程中或者处于在没有运行事件循环的线程中,该对象将无法接受排队的信号和事件。
默认情况下,QObject位于创建它的线程中。可以使用thread()函数查询当前所在的线程,还可以使用moveToThread()更改对象的线程关联。
注意:所有的QObject对象实例一定是与他们的父对象处在同一个线程中
-
如果两个QObjec实例对象处在不同的线程中,调用setParent()函数将父对象指定为另一方会发生错误。
-
当一个QObject实例对象被移动到另一个线程时,它的所有子线程也会被自动移动。
-
如果QObject实例对象已经处在一个父对象中,调用maveToThread()将发生失败。
-
如果QObject是在QThread::run()被创建,则该对象不能成为QThread实例对象的子对象,因为QThread实例对象并不处在调用QThread::run()的线程中。
资料:https://wiki.qt.io/QThreads_general_usag
https://wiki.qt.io/Threads_Events_QObjects
两种常用的信号和槽的连接方法
-
指定发送对象,接收对象,发送信号函数,接收信号处理的槽函数以及可选择连接类型。函数原型:
[static] QMetaObject::Connection QObject::connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type = Qt::AutoConnection)
其中连接类型说明如下:
枚举值 | 数值 | 说明 |
---|---|---|
Qt::AutoConnection | 0 | 默认值。如果接收对象和触发信号的对象处于同一线程中,则选择直连的方式;否则,使用队列进行连接。 |
Qt::DirectConnection | 1 | 发出信号后立即调用槽函数。该槽函数位于信号所处的线程中。 |
Qt::QueuedConnection | 2 | 当控制权返回到接收者线程的事件循环时,将调用该插槽。 该插槽在接收者的线程中执行。 |
Qt::BlockingQueuedConnection | 3 | 与Qt :: QueuedConnection相同,但是发送信号的线程被挂起,直到槽函数执行完成再恢复线程。 如果接收器位于发送信号的线程中,则不得使用此连接,否则应用程序将死锁。 |
Qt::UniqueConnection | 0x80 | 可以使用按位OR来与上述任何一种连接类型组合。 设置Qt :: UniqueConnection时,如果连接已经存在(即,如果相同信号已经连接到同一对对象的同一插槽),则QObject :: connect()将失败。 |
示例
QLabel *label = new QLabel; QScrollBar *scrollBar = new QScrollBar; QObject::connect(scrollBar,SIGNAL(valueChanged(int)),label,SLOT(setNum(int)));
-
指定发送对象,接收对象,信号函数成员,槽函数成员以及可选信号类型。函数原型:
[static] QMetaObject::Connection QObject::connect(const QObject *sender, PointerToMemberFunction signal, const QObject *receiver, PointerToMemberFunction method, Qt::ConnectionType type = Qt::AutoConnection)
示例
QLabel *label = new QLabel; QLineEdit *lineEdit = new QLineEdit; QObject::connect(lineEdit, &QLineEdit::textChanged, label, &QLabel::setText);