QObject【详细描述】

QObject 是 Qt 的核心,核心特征是强大的无缝对象通信机制 signals and slots(信号与槽)。

用户可以使用  connect() 将信号连接到槽,也可以使用disconnect() 断开连接。为避免无止境的通知循环,还可以使用 blockSignals()暂时阻止信号。受保护函数connectNotify()和 disconnectNotify() 可以跟踪连接。


QObjects 在 object trees (对象树)中组织自己。当创建以另一个对象作为父对象的 QObject 时,该对象将自动将自身添加到父对象的 children() 列表中。父级获得对象的所有权。也就是说,它将自动删除其析构函数中的子级。用户可以按名称查找对象,也可以选择使用  findChild()或findChildren()


每个对象都有一个 objectName(),它的类名可以通过相应的 metaObject() 找到(参见QMetaObject::className())。您可以使用 inherits() 函数确定对象的类是否继承 QObject 继承层次结构中的另一个类。


当对象被删除时,它会发出 destroyed() 信号,可以捕获此信号以避免对 QObjects 的悬空引用。


QObjects 可以通过 event() 接收事件,并过滤其他对象的事件(参阅 installEventFilter() and eventFilter())。可以重新实现 childEvent() 以捕获子事件。


QObject 还在 Qt 中提供了基本的定时器QTimer 支持。


 注意 

对于实现信号、槽或属性的任何对象, Q_OBJECT 宏都是必需的。您需要在源文件上运行 Meta Object Compiler。强烈建议在 QObject 的所有子类中使用此宏,无论它们是否实际使用信号、插槽和属性,因为如果不这样做可能会导致某些函数表现出奇怪行为。


所有 Qt 控件都继承了 QObject。isWidgetType() 函数返回对象是否实际上是控件。它比qobject_cast<QWidget *>(obj) 或 obj->inherits("QWidget") 快得多。

某些 QObject 函数(例如 children())返回 QObjectList,这 QList<QObject *>的类型定义 。


 线程亲和性 Thread Affinity 

  线程亲和性  能够强制使你的应用线程运行在特定的一个或多个cpu上。通过这种方式,可以消除操作系统进行调度过程导致线程迁移所造成的影响。

QObject 实例被具有线程亲和性,当 QObject 收到一个 queued signal 或一个posted event,槽或事件处理程序将在对象所在的线程中运行。

注意: 如果 QObject 没有线程亲和性(即,如果 thread()  返回零),或者如果它位于没有正在运行的事件循环的线程中,则它无法接收排队的信号或已发布的事件。

默认情况下,QObject 位于创建它的线程中。可以使用thread()  查询对象的线程亲和性,并使用 moveToThread() 更改对象的线程亲和性。

  所有 QObject 必须与其父级位于同一线程中。因此:

  • setParent()  如果涉及的两个 QObject 位于不同的线程中,则将失败。
  • 当一个 QObject 移动到另一个线程时,它的所有子线程也将自动移动。
  • 如果 QObject 有父级,则 moveToThread()  将失败。
  • 如果 QObject 是在QThread::run()中创建的,则它们不能成为 QThread 对象的子对象,因为QThread 不存在于调用  QThread::run() 的线程中。

 注意 

QObject 的成员变量不会自动成为其子变量。父子关系必须通过传递指向子项的指针或调用  constructor来设置。如果没有此步骤,则在调用  setParent() 时,对象的成员变量将保留在旧线程中。


  无复制构造函数或赋值运算符  

QObject 既没有复制构造函数,也没有赋值运算符,这是设计使然。实际上,它们是声明的,在宏 Q_DISABLE_COPY() 的部分中。事实上,所有从QObject派生的Qt类(直接或间接)都使用这个宏来声明它们的复制构造函数和赋值运算符是私有的。

参见: Identity vs Value 和 Object Model 

因此您应该使用指向 QObject(或指向 QObject 子类)的指针,否则您可能试图将 QObject 子类用作值。例如,如果没有复制构造函数,您不能使用 QObject 的子类作为要存储在其中一个容器类中的值。您必须存储指针。


 自动连接 

Qt的元对象系统提供了一种机制,可以在QObject子类及其子类之间自动连接信号和插槽。只要使用合适的对象名称定义对象,并且槽遵循简单的命名约定,就可以在运行时由 QMetaObject::connectSlotsByName() 函数执行此连接。

User Interface Compiler (uic ) 生成调用此函数的代码,以启用在使用Qt Designer 创建的表单上的控件之间执行自动连接。有关使用Qt Designer自动连接的更多信息,请参阅Using a Designer UI File in Your Application s


 动态属性 

从Qt 4.2开始,动态属性可以在运行时添加到QObject实例中,也可以从QObject实例中删除动态属性。动态属性不需要在编译时声明,但它们提供了与静态属性相同的优点,并且使用相同的 API 进行操作 - 使用 property() 读取它们,使用 setProperty()  写入它们。

从Qt 4.3开始,动态属性由 Qt Designer支持,并且标准Qt控件和用户创建的form都可以被赋予动态属性。


 国际化 (I18n) 

所有QObject子类都支持Qt的翻译功能,从而可以将应用程序的用户界面翻译成不同的语言。

若要使用户可见的文本可翻译,必须将其包装在对  tr() 函数的调用中。 Writing Source Code for Translation 文档中对此进行了详细解释。

另请参见  QMetaObjectQPointerQObjectCleanupHandlerQ_DISABLE_COPY(), and Object Trees & Ownership.


 <<<返回根页面

  • 8
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值