<<<<<<< HEAD
介绍…
下载地址:https://download.qt.io/archive/qt/
QT三大核心机制
信号槽,原对象系统以及事件模型。
重载函数
connect(this, QOverload<>::of(&classname::signal), this, QOverload<>::of(&classname::slot))
信号-槽:
QueuedConntection,DirectionConnection, autoConnection, uniqueConnection, blockingQueue
元对象系统:
QObject, Q_OBJECT, moc元对象编译器。
事件模型:
事件的创建:鼠标事件,键盘事件,窗口调整事件,模拟事件;
事件的交付:QObject::event()交付事件;
事件循环模型:QCoreApplication::exec()启动,exit()结束;
QEventLoop
信号-槽
signal没有public,private以及protected之分,slot有。
要使用signal-slot的先决条件是继承QObject类,并在类声明中添加Q_OBJECT宏。
声明与实现
信号和槽的本质都是函数。
信号只有声明,不需要实现,moc编译器会自动生成实现。
触发信号时,不写emit关键字,直接调用信号函数,也是没有问题的。因为emit是个空的宏:
1 |
Q_OBJECT宏
Q_OBJECT宏的展开如下:
1 | public: \ |
声明了一个只读的静态成员变量staticMetaObject,以及3个public的成员函数。以及private的静态成员函数qt_static_metacall。
这些成员变量和函数的实现在moc生成的moc_***.cpp文件中。
staticMetaObject是一个结构体,用来存储类的信号,槽等元信息,并把qt_static_metacall静态函数作为指针存储起来。
qt_static_metacall函数提供了两种”元调用的实现”:
- 如果是InvokeMetaMethod类型的调用,则直接把参数中的QObject对象,转换成类然后调用对应函数。
- 如果是IndexOfMethod类型的调用,即获取元函数的索引号,计算调用函数的偏移并返回。
信号的触发
信号的实现,直接调用QMetaObject::activate函数,第三个参数表示函数的索引号。
QMetaObject::active函数的实现在QObject.cpp文件中,不同版本的实现,差异比较大,大致流程:
- 先找出与当前信号连接的所有的对象-槽函数,逐个处理:
处理方式分为三种:receiverInSameThread表示当前线程id和接受信号的对象所在线程id是否相等。1
2
3
4
5
6
7
8if ((c->connectionType == Qt::AutoConnection && !receiverInSameThread) || (c->connectioinType == Qt::QueuecConnection)) {
// 队列处理
} else if (c->connectionType == Qt::BlockingQueuedConnection) {
// 阻塞处理
// 如果同线程,打印潜在的死锁
} else {
// 直接调用槽函数或会掉函数
}
- 如果信号-槽的连接方式为QueuedConnection,不论是否在同一个线程,按队列处理。
- 如果信号-槽的连接方式为Auto,且不在同一个线程,按队列处理。
- 如果信号-槽的连接方式BlockingQueuedConnection,按阻塞处理。同一个线程,不要按阻塞处理,直接调用。如果走阻塞队列,则多了加锁的过程。如果槽中又发了同样的信号,就会出现死锁:加锁之后还未解锁,又来申请加锁。
队列处理,就是把槽函数的调用,转成QMetaCallEvent事件,通过QCoreApplication::postEvent放进事件循环。
槽和moc生成
slot函数我们自己实现了,moc不会做额外的处理,所以自动生成的moc_***.cpp文件中,只有Q_OBJECT宏的展开。
QT UI缩放
调用qputenv,如下:
1 | qputenv("QT_SCALE_FACTOR", "0.6"); |
QT 关闭控制台
在CMakeLists.txt的工程下,添加WIN32
选项,编译64位程序,也是用改项
1 | add_executable(${PROJECT_NAME} WIN32 |
QT 翻译
在CMakeLists.txt的工程下,添加以下,用于build ts文件:
1 | find_package(Qt5 COMPONENTS Core Quick Widgets LinguistTools Concurrent REQUIRED) |
更新翻译时使用:
1 | lupdate ./ -ts language/en.ts -no-obsolete |
./表示源码搜索目录,默认递归搜索,-ts指定输出的ts翻译文件.
-no-obsolete 放弃无效翻译。
QT文件注释设置
Tools->Options->Text Editor->Snippets,选择Text或者其他,输入框中输入,添加一个fileheader,选中fileheader,最小边的输入框中根据需要添加:
1 | /**************************************************************************** |
QT CMakeLists.txt
Debug和Release模式选择拷贝dll
运行环境需要的dll和文件,可以在编译的时候使用cmake拷贝到exe相关的位置,在打包的时候直接打包整个Release文件夹即可,再CMakeLists.txt文件中添加:
1 | set(TARGET_NAME TestProject) |
QDesktopServices::openUrl中文路径
1 | QDesktopServices::openUrl(QUrl::fromLocalFile(save_file)); |
QPainter保存图像
利用QPixmap作为画板,并保存。
1 | QPainter painter; |