【QT】QObject简介

来源:互联网 发布:阿里云服务器屏蔽ip 编辑:程序博客网 时间:2024/06/06 13:25

1、简介

QObject类是所有Qt对象的基类,是Qt对象模型的核心,这个模型的主要特征为信号与槽,信号与槽是一个非常重要的机制,用于对象间的通信。连接信号与槽使用connect()函数,断开连接使用disconnect()函数,blockSignals()函数可以临时屏蔽信号,避免循环不断的通知,另外,protected级别的connectNotify()disconnectNotify()函数还可用于跟踪信号与槽的连接关系。信号与槽的更过介绍可参照Qt文档Signals & Slots

QObject对象是一种对象树的形式,当创建一个QObject对象并指定另外一个对象为parent时,这个对象将自动把自己添加到parent的children()列表,这样,parent拥有这个对象的所有权,parent销毁时自动销毁children,可以通过名字(objectName)查找parent拥有的children,使用findChild()findChildren()函数。QObject对象树的更多介绍可参照Qt文档Object Trees & Ownership

每个对象都有一个objectName()函数,类名可以通过metaObject()函数获得(QMetaObject::className()),在QObject类的树状继承结构中,查看一个对象的类是否继承自另一个类,使用inherits()函数。

一个对象销毁时,发送destroyed()信号,可以捕获这个信号以避免对这个对象的无效引用。

QObject对象可以通过event()函数接收事件,还可以过滤其它对象的事件(相关函数为installEventFilter()eventFilter()),重写childEvent()函数还可以处理children的事件。

在Qt中QObject还提供了基本的timer,timer的高级功能可参照QTimer类。

Q_OBJECT是一个很重要的宏,QObject对象实现了信号、槽、属性时,这个宏是必需的,元对象编译器moc(Meta Object Compiler)需要用到这个宏,建议QObject的所有子类不管有没有用到信号、槽、属性都使用这个宏,否则有可能出现诡异的事情。moc相关说明可参照Qt文档Using the Meta-Object Compiler (moc)

所有的Qt Widget都继承自QObject类,判断一个QObject对象是否为Widget可以使用isWidgetType()函数进行判断,这个函数必其它方法更快,如qobject_cast<QWidget *>(obj)obj->inherits("QWidget")

Object的某些函数,如children(),返回类型为QObjectList,这个是用typedef定义的QList<QObject*>

2、线程相关性

QObject实例有线程相关性,或者说只存在于特定线程,当一个对象收到queued signal或者posted event时,其slot或者event handler将在这个对象所在的线程运行。如果一个QObject对象没有线程相关性,也就是说thread()函数返回NULL,或者这个对象所在的线程没有running event loop,这个对象是收不到queued signal和posted event的。QObject对象默认存在于创建时所在的线程,线程相关性通过thread()函数获得,转线程使用moveToThread()函数。所有的QObject对象与其parent都必须在同一个线程,两个对象不在同一个线程时setParent()函数将失败,一个对象转线程成功后其children也会转到同一个线程,使用moveToThread()函数转线程时相应的对象不能有parent,如果在QThread::run()函数中创建了QObject对象,这些对象不能作为QThread对象的children,因为QThread不在调用QThread::run()函数所在的线程。另外,QObject的成员变量默认也不是其children,父子关系只能是在构造函数中通过参数传入parent或者调用setParent()函数,如果没有父子关系,调用moveToThread()函数时成员变量还保留在原有的线程。signal与event的更多说明可参照Qt文档Qt NamespaceThe Event System

3、无拷贝构造和赋值操作符

QObject专门设计为没有拷贝构造函数和赋值操作符,通过Q_DISABLE_COPY()宏实现,其实就是在private部分声明拷贝构造函数和赋值操作符而没有实现它们。在QObject的所有子类中都使用了这个宏,这样做的目的是在QObject Model中,QObject作为一种id而非value,value是可以拷贝或赋值的,但id只能克隆,克隆意味着创建一个新的id,而不是精确地拷贝原来的那一个,克隆比拷贝构造和赋值操作要复杂的多,既然禁止拷贝构造和赋值操作这种方式获取value,结果也就是只能通过指针来存储访问了。关于QObject Model的介绍可参照Qt文档QObject Model

4、自动连接

Qt的元对象系统提供了在QObject子类与其children之间自动连接信号与槽的机制,只要QObject对象设置了适当的objectName,并且slot的名字命名规范,就可以在运行时通过QMetaObject::connectSlotByName()函数完成连接。uic(User Interface Compiler)工具可以自动生成代码,在Qt Designer创建的Form中的Widget之间,以invoke某些函数用于自动连接。更多关于Qt Designer的自动连接可参照Qt文档Using a Desianger UI File in Your Application

5、动态属性

从Qt4.2开始,在运行时可以给一个QObject实例动态地添加或移除属性,动态属性是不需要在编译时声明的,与静态属性有同样的优势,使用相同的API进行读写property()setProperty()。从Qt4.3开始,Qt Designer也支持动态属性了,包括静态的Qt Widget和用户自定义的Form。

6、I18N

I18N即Internationalization,在I与N之间还有18个英文字母,是一种简写,国际化的意思。所有的QObject子类都支持Qt的翻译功能,用于翻译一个应用程序的用户接口(API)为不同的语言。为了使得用户可见的文本为可翻译的,必须使用tr()函数进行包装转换。详细用法可参照Qt文档Writing Source Code for Translation

原创粉丝点击