Qt的精髓2

我觉得可以从基础模块开始看,首先核心就是QtCore:

1. 命名

如果说Qt最让人影响深刻的,就是命名了,清晰简洁,统一规范,老实说做到这个真的太不容易了。

2. 生命期管理

Qt是C++写的,C++程序对象和资源的生命期管理可是个麻烦事

 

 

 Qt主要是用推荐对象树,我还是很喜欢这个方法的,尤其Gui程序中十分好用。同时用了COW,弱对象指针等。

3. 元对象系统

 元对象系统的核心是MOC,元对象编译器,它对C++本身实现了扩展

  • MOC

    Qt的元对象系统实现了对类型和方法的反射,对注册过的对象实现了信号槽,INVOKABLE 方法,动态属性系统等。这也是能够用XML或QML来写Gui界面的基础。

    基本方法是对Q_OBJECT 宏标记的类,编译时用MOC扫描生成代码文件 ,里面实现反射的方法的表。 编译Qt程序看看moc_xxx.cpp文件就可以看到它生成的代码。

    这一块其实我们自己也可以实现。比如自己插入一个Map<name, method>保存对象的成员函数表,Map<name, property>保存属性, 然后再通过一些宏,来实现将属性和方法保存到Map里。

  • signal slot

    Qt发明用来做对象间通信的方法,在C#里叫Event Delegate。

    Qt实现signal slot也是基于其元对象系统,MOC生成代码文件,signal实现成函数。

    signal slot可以看做观察者模式的一种具体实现,相对于普通的观察者模式,抽象要高级一点,更加低耦合,不用保存对方指针,Qt还帮我们管理好了多连接,同时实现了自动断开连接,这样也避免里野指针问题。

    Qt自己的signal slot相比于boost或其它的实现,跟自己的框架结合更紧密,可以有QueueConnection来实现跨线程(同线程也可以异步,默认Auto Connection会自动判断线程)的异步连接。

    注意的是signal slot实现的是对象间通信,如果两个对象在逻辑上关系非常远,可以使用其他的消息订阅机制。

    signal slot的实现本身也不复杂,借助C++11。

  • Q_INVOKABLE 成员方法

    这个跟slot在元对象上存储的信息略有不同,在遍历一个对象的反射方法时,可以区分方法时slot方法还是Q_INVOKABLE方法。

    使用MetaMethod可以对一个对象方法的作异步调用(同/夸线程),同时Qt会处理好对象已经析构的问题。

    另外MetaMethod也可以实现反射调用,

 

QEventLoop loop;
loop.exec();

 

Qt封装不同平台自己的native事件处理,同时自己拥有一套QEvent事件心态,在loop.exec()处理线程中的各种事件。这一点各类Gui库/框架大同小异。

5. QThread

Qt的QThread应该和QEventloop结合起来看。

QThread是对不同系统线程的封装,默认有一个自身的eventloop再跑(见QThread::exec())。

Qt里QObject类型的对象都是属于某一个QThread的,前面说过signal slot连接跨线程默认是异步连接,这里Qt会判断signal所在的对象和slot所在的对象属于哪一个线程。

QObject在创建时所在的线程便是它所属于的线程,但是它可以被移动到其它线程(moveToThread)。

对于主线程,这是Qt在初始化时会生成一个线程对象作为主线程的代理对象。

注意,有些童鞋对Qt的线程使用有个典型错误,https://www.qt.io/blog/2010/06/17/youre-doing-it-wrong;

6. Qt的几个主要Gui框架

 

  • QWidget
  • Graphics View
  • Qt Quick (Qt Qml)

 

原文转载:https://www.zhihu.com/question/27040542/answer/220401994

posted on 2022-10-09 14:19  斗战胜佛美猴王  阅读(79)  评论(0编辑  收藏  举报