一份硬核的QT开发经验及资料分享,长文收藏!

[复制链接]
5204|94
 楼主| micoccd 发表于 2022-6-14 15:13 | 显示全部楼层
QVideoWidget播放视频,可能会遇到画面闪烁的情况,播放视频的窗体需要设置个属性。
  1. QVideoWidget *videoWidget = new QVideoWidget;
  2. videoWidget->setAttribute(Qt::WA_OpaquePaintEvent);
 楼主| micoccd 发表于 2022-6-14 15:14 | 显示全部楼层
Qt bug成千上万,这个不用大惊小怪,也基本上遇不到,大部分都是特殊极端情况特定应用场景出现,甚至你会遇到有些是debug可以release报错,有些release可以debug却报错的情况,最神奇的还有先是debug报错,然后release正常,再返回去用debug又正常,需要用release激活一下!学习编程的路本来就是一条坑坑洼洼的路,不断填坑,尽量规避坑!很多时候很多看起来的坑其实是自己没有注意细节导致的。
 楼主| micoccd 发表于 2022-6-14 15:15 | 显示全部楼层
Qt试图中默认排序是按照字符串的ASCII排序的,如果是IP地址的话会出现192.168.1.117排在192.168.1.2前面的情况,如果要规避这种情况,一种做法是取末尾的地址转成整型再比较大小,缺点是跨网段就歇菜了,又会出现192.168.2.65出现在192.168.1.70前面,终极**是将IP地址转成整型再比较大小。
  1. QString QUIHelper::ipv4IntToString(quint32 ip)
  2. {
  3.     QString result = QString("%1.%2.%3.%4").arg((ip >> 24) & 0xFF).arg((ip >> 16) & 0xFF).arg((ip >> 8) & 0xFF).arg(ip & 0xFF);
  4.     return result;
  5. }

  6. quint32 QUIHelper::ipv4StringToInt(const QString &ip)
  7. {
  8.     int result = 0;
  9.     if (isIP(ip)) {
  10.         QStringList list = ip.split(".");
  11.         int ip0 = list.at(0).toInt();
  12.         int ip1 = list.at(1).toInt();
  13.         int ip2 = list.at(2).toInt();
  14.         int ip3 = list.at(3).toInt();
  15.         result = ip3 | ip2 << 8 | ip1 << 16 | ip0 << 24;
  16.     }
  17.     return result;
  18. }
 楼主| micoccd 发表于 2022-6-14 15:16 | 显示全部楼层
在主QWidget窗体如果直接qss设置背景图片的话,预览是可见的,运行并没有效果,你需要在这个主widget上再放个widget,在新的widget上设置qss图片就行,而如果是Dialog或者QMainWindow窗体是支持直接设置qss背景图的,预览和运行效果一致。

Qt提供了qDebug机制直接输出打印信息,这个大大弥补了QtCreator调试很**肋的缺点,而且无缝对接日志钩子,使得现场运行期间按照预定的打印信息输出到日志文件,有时候在开发阶段,又不想要看到一堆堆的打印信息,最笨的做法是一行行注释掉qdebug的地方,其实还可以直接pro中加上一行来禁用整个项目的qdebug输出。

  1. #禁用qdebug打印输出
  2. DEFINES     += QT_NO_DEBUG_OUTPUT

  3. #自定义define变量 可以在整个项目中使用
  4. #pro文件可以这样判断 contains(DEFINES, videovlc) {}
  5. #代码文件可以这样判断 #ifdef videovlc
  6. DEFINES     += videovlc1 videoffmpeg

  7. #关闭编译警告提示 眼不见为净
  8. CONFIG      += warn_off

  9. #指定编译生成的文件到temp目录 分门别类存储
  10. MOC_DIR     = temp/moc
  11. RCC_DIR     = temp/rcc
  12. UI_DIR      = temp/ui
  13. OBJECTS_DIR = temp/obj

  14. #指定编译生成的可执行文件到bin目录
  15. DESTDIR     = bin


 楼主| micoccd 发表于 2022-6-14 15:18 | 显示全部楼层
Qt对操作系统层的消息也做了很多的封装,可以直接拿到进行处理(如果需要拦截处理要用对应操作系统的API才行比如鼠标键盘钩子),比如系统休眠和唤醒做一些处理。
  1. //主窗体头文件
  2. protected:
  3.     bool nativeEvent(const QByteArray &eventType, void *message, long *result);
  4. #ifdef Q_OS_WIN
  5.     bool winEvent(MSG *message, long *result);
  6. #endif

  7. //主窗体实现函数
  8. #ifdef Q_OS_WIN
  9. #include "Windows.h"
  10. #endif

  11. bool frmMain::nativeEvent(const QByteArray &eventType, void *message, long *result)
  12. {
  13.     if (eventType == "windows_generic_MSG") {
  14. #ifdef Q_OS_WIN
  15.         MSG *msg = static_cast<MSG *>(message);
  16.         //qDebug() << TIMEMS << msg->message;
  17.         if (msg->wParam == PBT_APMSUSPEND && msg->message == WM_POWERBROADCAST) {
  18.             //系统休眠的时候自动最小化可以规避程序可能出现的问题
  19.             this->showMinimized();
  20.         } else if (msg->wParam == PBT_APMRESUMEAUTOMATIC) {
  21.             //休眠唤醒后自动打开
  22.             this->showNormal();
  23.         }
  24. #endif
  25.     } else if (eventType == "NSEvent") {
  26. #ifdef Q_OS_MACOS
  27. #endif
  28.     }
  29.     return false;
  30. }

  31. #ifdef Q_OS_WIN
  32. bool frmMain::winEvent(MSG *message, long *result)
  33. {
  34.     return nativeEvent("windows_generic_MSG", message, result);
  35. }
  36. #endif
 楼主| micoccd 发表于 2022-6-14 15:19 | 显示全部楼层
Qt的pro项目管理配置文件中也可添加各种编译前后的操作及配置,主要通过 QMAKE_POST_LINK和QMAKE_PRE_LINK,他们支持的函数以及写法,可以在QtCreator的帮助中搜索 qmake Function Reference 查看详情说明。
QMAKE_PRE_LINK    表示编译前执行内容
QMAKE_POST_LINK   表示编译后执行内容
  1. srcFile1 = $PWD/1.txt
  2. srcFile2 = $PWD/2.txt
  3. dstDir = $PWD/../bin
  4. #windows上需要转换路径斜杠 其他系统不需要
  5. srcFile1 = $replace(srcFile1, /, \\);
  6. srcFile2 = $replace(srcFile2, /, \\);
  7. dstDir = $replace(dstDir, /, \\);

  8. #编译前执行拷贝 多个拷贝可以通过 && 符号隔开
  9. QMAKE_PRE_LINK += copy /Y $srcFile1 $dstDir && copy /Y $srcFile2 $dstDir
  10. #编译后执行拷贝 多个拷贝可以通过 && 符号隔开
  11. QMAKE_POST_LINK += copy /Y $srcFile1 $dstDir && copy /Y $srcFile2 $dstDir
 楼主| micoccd 发表于 2022-6-14 15:19 | 显示全部楼层
三、其他经验
Qt界的中文乱码问题,版本众多导致的如何选择安装包问题,如何打包发布程序的问题,堪称Qt界的三座大山!

在Qt的学习过程中,学会查看对应类的头文件是一个好习惯,如果在该类的头文件没有找到对应的函数,可以去他的父类中找找,实在不行还有爷爷类,肯定能找到的。通过头文件你会发现很多函数接口其实Qt已经帮我们封装好了,有空还可以阅读下他的实现代码。

Qt安装目录下的Examples目录下的例子,看完学完,月薪20K起步;Qt常用类的头文件的函数看完学完使用一遍并加以融会贯通,月薪30K起步。

Qt在开发阶段不支持中文目录,切记,这是无数人可能犯的错误,在安装Qt集成开发环境以及编译器的时候,务必记得目录必须英文,否则很可能不正常,建议尽量用默认的安装位置。

如果出现崩溃和段错误,80%都是因为要么越界,要么未初始化,死扣这两点,80%的问题解决了。

Qt一共有几百个版本,关于如何选择Qt版本的问题,我一般保留四个版本,为了兼容Qt4用4.8.7,最后的支持XP的版本5.7.0,最新的长期支持版本比如5.12,最高的新版本比如5.15.2。强烈不建议使用4.7以前和5.0到5.3之间的版本,太多bug和坑,稳定性和兼容性相比于之后的版本相当差,能换就换,不能换睡服领导也要换。

Qt和msvc编译器常见搭配是Qt5.7+VS2013、Qt5.9+VS2015、Qt5.12+VS2017,按照这些搭配来,基本上常用的模块都会有,比如webengine模块,如果选用的Qt5.12+msvc2015,则很可能官方没有编译这个模块,只是编译了Qt5.12+msvc2017的。

新版本Qt安装包安装的时候需要填写注册信息,如果不想填写,先禁用网卡,在运行安装包,可以直接跳过这一步进行安装。

终极秘籍:如果遇到问题搜索Qt方面找不到答案,试着将关键字用JAVA C# android打头,你会发现别有一番天地,其他人很可能做过!

如果Qt能从下面几个方面努力,相信会更有发展前景。

QWidget支持CSS3,具有诸多的牛X的效果,目前支持的是CSS2。
QWidget支持GPU绘制,可选切换CPU或者GPU,大大提升绘制效率,利用现在强大的硬件。
Qml无缝支持js,可以利用现在各种js轮子,指数级提升qml的项目范围。
支持将程序转成web运行,比如转成cgi之类的程序,目前Qt for WebAssembly很**肋,功能极其有限,首次加载速度超慢,大部分Qt类还不支持。
最后一条:珍爱生命,远离编程。祝大家头发浓密,睡眠良好,情绪稳定,财富自由!
tpgf 发表于 2022-7-5 10:18 | 显示全部楼层
QT是什么的简称啊
heimaojingzhang 发表于 2022-7-5 10:25 | 显示全部楼层
请问什么是弱属性机制啊
keaibukelian 发表于 2022-7-5 10:56 | 显示全部楼层
qss 文件是自动创建的吗
labasi 发表于 2022-7-5 11:04 | 显示全部楼层
也是使用的C语言吗
paotangsan 发表于 2022-7-5 11:12 | 显示全部楼层
ui文件可以指定格式吗
zhczlzhang 发表于 2022-7-5 11:13 | 显示全部楼层
QT5还好,QT4有点不行了
renzheshengui 发表于 2022-7-5 11:21 | 显示全部楼层
这个是所见即所得吗
laserpic 发表于 2022-7-7 15:01 | 显示全部楼层
都是很实用的经验
您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 在线客服 返回列表 返回顶部
0