大神总结的Qt开发经验,满满的都是干货

[复制链接]
大神总结的Qt开辟履历,满满的都是干货

首先声明,本文并非原创,纯属搬运,内容来自一位叫做飞扬芳华的大神的Gitee主页,重要是为了收藏下面介绍的100多个Qt开辟履历。我自己也从事了两年了Qt开辟,再转Qt开辟从前用的都是MFC,我仔细的看了一遍下面列出的各条履历,只恨看到的太晚了,由于许多都是自己踩过的坑。好比qss的ANSI编码、嵌套窗口中主窗口无法接收鼠标移动事件等,又好比我用qss设置窗口样式,但是项目每次重新构建以后,样式表就会不生效等问题,也花了自己不少时间去解决,所以在这里转发大神的履历,留作以后参考和逐条的研究,也分享给更多正在学习Qt大概正在利用Qt进行程序开辟的朋友们。

大神主页:https://gitee.com/feiyangqingyun/qtkaifajingyan?_from=gitee_search

大神总结的Qt开辟履历,满满的都是干货

1. 当编译发现大量错误的时间,从第一个看起,一个一个的解决,不要急着去看下一个错误,通常后面的错误都是由于前面的错误引起的,第一个解决后很可能都解决了。

2. 定时器是个好东西,学会好利用它,有时间用QTimer::singleShot可以解决意想不到的问题。

3. 打开creator,在构建套件的环境中增长MAKEFLAGS=-j8,可以不消每次设置多线程编译。珍爱时间和生命。新版的QtCreator已经默认就是j8。

4. 如果你想顺遂用QtCreator摆设安卓程序,首先你要在AndroidStudio 里面配置乐成,把坑全部趟平。

5. 许多时间找到Qt对应封装的方法后,记得多看看该函数的重载,多个参数的,你会发现不一样的世界,有时间会恍然大悟,原来Qt已经帮我们封装好了。

6. 可以在pro文件中写上标记版本号+ico图标(Qt5才支持)

VERSION  = 2020.10.25RC_ICONS = main0.ico

7. 管理员运行程序,限定在MSVC编译器

QMAKE_LFLAGS += /MANIFESTUAC:"level='requireAdministrator' uiAccess='false'" #以管理员运行QMAKE_LFLAGS += /SUBSYSTEM:WINDOWS,"5.01" #VS2013 在XP运行

8. 运行文件附带调试输出窗口

CONFIG += console pro

9. 绘制平铺配景QPainter::drawTiledPixmap,绘制圆角矩形QPainter::drawRoundedRect(),而不是QPainter::drawRoundRect();

10. 移除旧的样式

//移除原有样式style()->unpolish(ui->btn);//重新设置新的该控件的样式。style()->polish(ui->btn);

11. 获取类的属性

const QMetaObject *metaobject = object->metaObject();int count = metaobject->propertyCount();for (int i = 0; i < count; ++i) {    QMetaProperty metaproperty = metaobject->property(i);    const char *name = metaproperty.name();    QVariant value = object->property(name);    qDebug() << name << value;}

12. Qt内置图标封装在QStyle中,大概七十多个图标,可以直接拿来用。

SP_TitleBarMenuButton,SP_TitleBarMinButton,SP_TitleBarMaxButton,SP_TitleBarCloseButton,SP_MessageBoxInformation,SP_MessageBoxWarning,SP_MessageBoxCritical,SP_MessageBoxQuestion,...

13. 根据操作系统位数判断加载

win32 {    contains(DEFINES, WIN64) { DESTDIR = $${PWD}/../../bin64    } else { DESTDIR = $${PWD}/../../bin32 }}

14. Qt5增强了许多安全性验证,如果出现setGeometry: Unable to set geometry,请将该控件的可见移到加入布局之后。

15. 可以将控件A添加到布局,然后控件B设置该布局,这种灵活性大大提高了控件的组合度,好比可以在文本框左侧右侧增长一个搜刮按钮,按钮设置图标即可。

QPushButton *btn = new QPushButton;btn->resize(30, ui->lineEdit->height());QHBoxLayout *layout = new QHBoxLayout(ui->lineEdit);layout->setMargin(0);layout->addStretch();layout->addWidget(btn);

16. 对QLCDNumber控件设置样式,必要将QLCDNumber的segmentstyle设置为flat。

17. 奇妙的利用findChildren可以查找该控件下的所有子控件。findChild为查找单个。

//查找指定类名objectName的控件QList widgets = parentWidget.findChildren("widgetname");//查找所有QPushButtonQList allPButtons = parentWidget.findChildren();//查找一级子控件,不然会不停遍历所有子控件QList childButtons = parentWidget.findChildren(QString(), Qt::FindDirectChildrenOnly);

18. 奇妙的利用inherits判断是否属于某种类。

QTimer *timer = new QTimer;         // QTimer inherits QObjecttimer->inherits("QTimer");          // returns truetimer->inherits("QObject");         // returns truetimer->inherits("QAbstractButton"); // returns false

19. 利用弱属性机制,可以存储临时的值用于通报判断。可以通过widget->dynamicPropertyNames()列出所有弱属性名称,然后通过widget->property("name")取出对应的弱属性的值。

20. 在开辟时, 无论是出于维护的便捷性, 还是节流内存资源的考虑, 都应该有一个 qss 文件来存放所有的样式表, 而不应该将 setStyleSheet 写的随处都是。如果是初学阶段大概测试阶段可以直接UI上右键设置样式表,正式项目还是建议同一到一个qss样式表文件比力好,同一管理。

21. 如果出现Z-order assignment: is not a valid widget.错误提示,用记事本打开对应的ui文件,找到为空的地方,删除即可。

22. 善于利用QComboBox的addItem的第二个参数设置用户数据,可以实现许多结果,利用itemData取出来。

23. 如果用了webengine模块,发布程序的时间带上QtWebEngineProcess.exe+translations文件夹+resources文件夹。

24. 默认Qt是一个窗体一个句柄,如果要让每个控件都拥有独立的句柄,设置下 a.setAttribute(Qt::AA_NativeWindows);

25. Qt+Android防止程序被关闭。

#if defined(Q_OS_ANDROID)QAndroidService a(argc, argv);return a.exec()#elseQApplication a(argc, argv);return a.exec();#endif

26. 可以对团体的指示器设置样式,比方 *::down-arrow,*::menu-indicator{} *::up-arrow:disabled,*::up-arrow:off{}。

27. 可以执行位置设置配景图片。

QMainWindow > .QWidget {    background-color: gainsboro;    background-image: url(:/images/pagefold.png);    background-position: top right;    background-repeat: no-repeat}

28. 嵌入式linux运行Qt程序 Qt4写法:./HelloQt -qws & Qt5写法:./HelloQt --platform xcb

29. Qtcreator软件的配置文件存放在:C:UsersAdministratorAppDataRoamingQtProject,有时间如果发现出问题了,将这个文件夹删除后打开creator自动重新生成即可。

30. QMediaPlayer是个壳,依赖当地解码器,视频这块默认根本上就播放个MP4,如果要支持其他格式必要下载k-lite大概LAV Filters安装即可(WIN上,其他系统上自行搜刮)。如果必要做功能强劲的播放器,初学者建议用vlc、mpv,终极大法用ffmpeg。

31. 判断编译器范例、编译器版本、操作系统。

//GCC编译器#ifdef __GNUC__#if __GNUC__ >= 3 // GCC3.0以上//MSVC编译器#ifdef _MSC_VER#if _MSC_VER >=1000 // VC++4.0以上#if _MSC_VER >=1100 // VC++5.0以上#if _MSC_VER >=1200 // VC++6.0以上#if _MSC_VER >=1300 // VC2003以上#if _MSC_VER >=1400 // VC2005以上#if _MSC_VER >=1500 // VC2008以上#if _MSC_VER >=1600 // VC2010以上#if _MSC_VER >=1700 // VC2012以上#if _MSC_VER >=1800 // VC2013以上#if _MSC_VER >=1900 // VC2015以上//Borland C++#ifdef __BORLANDC__//Cygwin#ifdef __CGWIN__#ifdef __CYGWIN32__//mingw#ifdef __MINGW32__//windows#ifdef _WIN32    //32bit#ifdef _WIN64    //64bit#ifdef _WINDOWS     //图形界面程序#ifdef _CONSOLE     //控制台程序//Windows(95/98/Me/NT/2000/XP/Vista)和Windows CE都定义了#if (WINVER >= 0x030a)     // Windows 3.1以上#if (WINVER >= 0x0400)     // Windows 95/NT4.0以上#if (WINVER >= 0x0410)     // Windows 98以上#if (WINVER >= 0x0500)     // Windows Me/2000以上#if (WINVER >= 0x0501)     // Windows XP以上#if (WINVER >= 0x0600)     // Windows Vista以上//_WIN32_WINNT 内核版本#if (_WIN32_WINNT >= 0x0500) // Windows 2000以上#if (_WIN32_WINNT >= 0x0501) // Windows XP以上#if (_WIN32_WINNT >= 0x0600) // Windows Vista以上

32. 在pro中判断Qt版本及构建套件位数

#打印版本信息message(qt version: $$QT_VERSION)#判断当前qt版本号QT_VERSION = $$[QT_VERSION]QT_VERSION = $$split(QT_VERSION, ".")QT_VER_MAJ = $$member(QT_VERSION, 0)QT_VER_MIN = $$member(QT_VERSION, 1)#下面是表示 Qt5.5greaterThan(QT_VER_MAJ, 4) {greaterThan(QT_VER_MIN, 4) {#自己根据必要做一些处置惩罚}}#QT_ARCH是Qt5新增的,在Qt4上没结果#打印当前Qt构建套件的信息message($$QT_ARCH)#表示arm平台构建套件contains(QT_ARCH, arm) {}#表示32位的构建套件contains(QT_ARCH, i386) {}#表示64位的构建套件contains(QT_ARCH, x86_64) {}

33. Qt最小化后规复界面假死冻结,加上代码

void showEvent(QShowEvent *e){    setAttribute(Qt::WA_Mapped);    QWidget::showEvent(e);}

34. 获取标题栏高度:style()->pixelMetric(QStyle::PM_TitleBarHeight); PM_TitleBarHeight点进去你会发现新大陆。

35. 设置高分屏属性以便支持2K4K等高分辨率,尤其是手机app。必须写在main函数的QApplication a(argc, argv);的前面。

#if (QT_VERSION > QT_VERSION_CHECK(5,6,0))    QGuiApplication::setAttribute(Qt::AA_EnableHighDpiScaling);#endif

36. 如果运行程序出现 Fault tolerant heap shim applied to current process. This is usually due to previous crashes. 错误。

办法:打开注册表,找到HKEY_LOCAL_MACHINESoftwareMicrosoftWindows NTCurrentVersionAppCompatFlagsLayers,选中Layers键值,从右侧列表中删除自己的谁人程序路径即可。

37. Qt内置了QFormLayout表单布局用于自动生成标签+输入框的组合的表单界面。

38. qml播放视频在linux必要安装 sudo apt-get install libpulse-dev。

39. 可以直接继承QSqlQueryModel实现自定义的QueryModel,好比某一列字体颜色,占位符,其他样式等,重写QVariant CustomSqlModel::data(const QModelIndex &index, int role) const。

40. Qt5以后提供了类QScroller直接将控件滚动。

//禁用横向滚动条ui->listWidget->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);//禁用纵向滚动条ui->listWidget->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);//设置横向按照像素值为单位滚动ui->listWidget->setHorizontalScrollMode(QListWidget::ScrollPerPixel);//设置纵向按照像素值为单位滚动ui->listWidget->setVerticalScrollMode(QListWidget::ScrollPerPixel);//设置滚动对象以及滚动方式为鼠标左键拉动滚动QScroller::grabGesture(ui->listWidget, QScroller::LeftMouseButtonGesture);//另有个QScrollerProperties可以设置滚动的一些参数

41. 如果利用sqlite数据库不想产生数据库文件,可以创建内存数据库。

QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");db.setDatabaseName(":memory:");

42. 清空数据表并重置自增ID,sql = truncate table table_name。

43. Qtchart模块从Qt5.7开始自带,最低编译要求Qt5.4。在安装的时间记得勾选,默认不勾选。利用该模块必要引入定名空间。

#include QT_CHARTS_USE_NAMESPACEclass CustomChart : public QChartView

44. QPushButton左对齐笔墨,必要设置样式表QPushButton{text-align:left;}

45. QLabel有三种设置文本的方法,把握好Qt的属性系统,闻一知十,可以做出许多结果。

ui->label->setStyleSheet("qproperty-text:hello;");ui->label->setProperty("text", "hello");ui->label->setText("hello");

46. 奇妙的用QEventLoop开启事件循环,可以使得许多同步获取返回结果而不壅闭界面。QEventLoop内部新建了线程执行。

QEventLoop loop;connect(reply, SIGNAL(finished()), &loop, SLOT(quit()));loop.exec();

47. 多种预定义变量 #if (defined webkit) || (defined webengine),去掉生成空的debug和release目录 CONFIG -= debug_and_release。

48. 新版的Qtcreator增强了语法检查,会弹出许多警告提示等,可以在插件列表中关闭clang打头的几个即可,Help》About Plugins。也可以设置代码检查级别,Tools》Options 》C++ 》Code Model。

49. QSqlTableModel的rowCount方法,默认最大返回256,如果超过256,可以将表格拉到底部,会自动加载剩余的,每次最大加载256条数据,如果必要打印大概导出数据,记得最好接纳sql语句去查询,而不是利用QSqlTableModel的rowCount方法。不然永久最大只会导出256条数据。

如果数据量很小,也可以接纳如下方法:

//主动加载所有数据,不然获取到的行数<=256while(model->canFetchMore()) {    model->fetchMore();}

50. 如果必要指定无边框窗体,但是又必要保存操作系统的边框特性,可以自由拉伸边框,可以利用

 setWindowFlags(Qt::CustomizeWindowHint);

51. 在某些http post数据的时间,如果接纳的是&字符串连接的数据发送,中文解析乱码的话,必要将中文进行URL转码。

QString content = "测试中文";QString note = content.toUtf8().toPercentEncoding();

52. Qt默认不支持大资源文件,好比添加了字体文件,必要pro文件开启。

CONFIG += resources_big

53. Qt中继承QWidget之后,样式表不起作用,解决办法有三个。猛烈保举方法一。

- 方法一:设置属性 this->setAttribute(Qt::WA_StyledBackground, true);

- 方法二:改成继承QFrame,由于QFrame自带paintEvent函数已做了实现,在利用样式表时会进行解析和绘制。

- 方法三:重新实现QWidget的paintEvent函数时,利用QStylePainter绘制。

void Widget::paintEvent(QPaintEvent *){    QStyleOption option;    option.initFrom(this);    QPainter painter(this);    style()->drawPrimitive(QStyle::PE_Widget, &option, &painter, this);}

54. 有时间在界面上加了弹簧,必要动态改变弹簧对应的拉伸策略,对应方法为changeSize,许多人会选择利用set开头去找,找不到的。

55. 在利用QFile的过程中,不建议频繁的打开文件写入然后再关闭文件,好比间隔5ms输出日记,IO性能瓶颈很大,这种情况建议先打开文件不要关闭,等待符合的机遇好比析构函数中大概日期变了必要重新变更日记文件的时间关闭文件。不然短时间内大量的打开关闭文件会很卡,文件越大越卡。

56. 在许多网络应用程序,必要自定义心跳包来保持连接,不然断电大概非法关闭程序,对方辨认不到,必要进行超时检测,但是有些程序没有提供心跳协议,此时必要启用系统层的保活程序,此方法适用于TCP连接。

int fd = tcpSocket->socketDescriptor();int keepAlive = 1;      //开启keepalive属性,缺省值:0(关闭)int keepIdle = 5;       //如果在5秒内没有任何数据交互,则进行探测,缺省值:7200(s)int keepInterval = 2;   //探测时发探测包的时间间隔为2秒,缺省值:75(s)int keepCount = 2;      //探测重试的次数,全部超时则认定连接失效,缺省值:9(次)setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, (void *)&keepAlive, sizeof(keepAlive));setsockopt(fd, SOL_TCP, TCP_KEEPIDLE, (void *)&keepIdle, sizeof(keepIdle));setsockopt(fd, SOL_TCP, TCP_KEEPINTVL, (void *)&keepInterval, sizeof(keepInterval));setsockopt(fd, SOL_TCP, TCP_KEEPCNT, (void *)&keepCount, sizeof(keepCount));

57. 如果程序打包好以后弹出提示 This application failed to start because it could not find or load the Qt platform plugin 一样平常都是由于platforms插件目录未打包大概打包错了的原因导致的。

58. 非常不建议tr中包含中文,只管现在的新版Qt支持中文到其他语言的翻译,但是很不规范,也不知道TMD是谁教的,tr的本意是包含英文,然后翻译到其他语言好比中文,现在大量的初学者滥用tr,如果没有翻译的需求,禁用tr,tr必要开销的,Qt默认会以为他必要翻译,会额外进行特殊处置惩罚。

59. 许多人Qt和Qt Creator傻傻分不清楚,经常问Qt什么版本结果发一个Qt Creator的版本过来,Qt Creator是利用Qt编写的集成开辟环境IDE,和宇宙第一的Visual Studio一样,他可以是msvc编译器的(WIN对应的Qt集成安装环境中自带的Qt Cerator是msvc的),也可以是mingw编译的,还可以是gcc的。如果是自定义控件插件,必要集成到Qt Creator中,必须保证该插件的动态库文件(dll大概so等文件)对应的编译器和Qt版本以及位数和Qt Creator的版本完全一致才行,否则根本不大可能集成进去。特殊注意的是Qt集成环境安装包中的Qt版本和Qt Creator版本未必完全一致,必须擦亮眼睛看清楚,有些是完全一致的。

60. 超过两处相同处置惩罚的代码,建议单独写成函数。代码尽量规范精简,好比 if(a == 123) 要写成 if (123 == a),值在前面,再好比 if (ok == true) 要写成 if (ok),if (ok == false) 要写成 if (!ok)等。

61. 许多人问Qt嵌入式平台用哪个好,这里同一答复(当前时间节点2018年):imx6+335x比力稳定,性能高就用RK3288 RK3399,自制的话就用全志H3,玩一玩可以用树莓派香橙派。

62. 对于大段的注释代码,建议用 #if 0 #endif 将代码块包含起来,而不是将该段代码选中然后全部 // ,下次要打开这段代码的话,又必要重新选中一次取消,如果接纳的是 #if 0则只要把0改成1即可,服从大大提升。

63. Qt打包发布,有许多办法,Qt5以后提供了打包工具windeployqt(linux上为linuxdeployqt,mac上为macdeployqt)可以很方便的将应用程序打包,利用下来发现也不是万能的,有时间会多打包一些没有依赖的文件,有时间又会忘记打包一些插件尤其是用了qml的情况下,而且不能辨认第三方库,好比程序依赖ffmpeg,则对应的库必要自行拷贝,终极大法就是将你的可执行文件复制到Qt安装目录下的bin目录,然后整个一起打包,挨个删除不大可能依赖的组件,直到删到正常运行为止。

64. Qt中的动画,底层用的是QElapsedTimer定时器来完成处置惩罚,好比产生一些指定规则算法的数据,然后对属性进行处置惩罚。

65. 在绘制无配景颜色只有边框颜色的圆形时间,可以用绘制360度的圆弧替代,结果完全一致。

QRect rect(-radius, -radius, radius * 2, radius * 2);//以下两种方法二选一,其实绘制360度的圆弧=绘制无配景的圆形painter->drawArc(rect, 0, 360 * 16);painter->drawEllipse(rect);

66. 不要把d指针看的很玄乎,其实就是在类的实现文件定义了一个私有类,用来存放局部变量,个人建议在做一些小项目时,没有太大必要引入这种机制,会降低代码可读性,增长复杂性,新手担当项目后会看的很懵逼。

67. 许多人在绘制的时间,设置画笔以为就只可以设置个单调的颜色,其实QPen还可以设置brush,这样灵活性就提高不知道多少倍,好比设置QPen的brush以后,可以利用各种渐变,好比绘制渐变颜色的进度条和笔墨等,而不再是单调的一种颜色。

68. 许多控件都带有viewport,好比QTextEdit/QTableWidget/QScrollArea,有时间对这些控件直接处置惩罚的时间发现不起作用,必要对其viewport()设置才行,好比设置滚动条区域配景透明,必要利用scrollArea->viewport()->setStyleSheet("background-color:transparent;");而不是scrollArea->setStyleSheet("QScrollArea{background-color:transparent;}");

69. 有时间设置了鼠标跟踪setMouseTracking为真,如果该窗体上面另有其他控件,当鼠标移到其他控件上面的时间,父类的鼠标移动事件MouseMove辨认不到了,此时必要用到HoverMove事件,必要先设置 setAttribute(Qt::WA_Hover, true);

70. Qt封装的QDateTime日期时间类非常强大,可以字符串和日期时间相互转换,也可以毫秒数和日期时间相互转换,还可以1970经过的秒数和日期时间相互转换等。

QDateTime dateTime;QString dateTime_str = dateTime.currentDateTime().toString("yyyy-MM-dd hh:mm:ss");//从字符串转换为毫秒(需完备的年代日时分秒)datetime.fromString("2011-09-10 12:07:50:541", "yyyy-MM-dd hh:mm:ss:zzz").toMSecsSinceEpoch();//从字符串转换为秒(需完备的年代日时分秒)datetime.fromString("2011-09-10 12:07:50:541", "yyyy-MM-dd hh:mm:ss:zzz").toTime_t();//从毫秒转换到年代日时分秒datetime.fromMSecsSinceEpoch(1315193829218).toString("yyyy-MM-dd hh:mm:ss:zzz");//从秒转换到年代日时分秒(如有zzz,则为000)datetime.fromTime_t(1315193829).toString("yyyy-MM-dd hh:mm:ss[:zzz]");

71. 在我们利用QList、QStringList、QByteArray等链表大概数组的过程中,如果只必要取值,而不是赋值,猛烈建议利用 at() 取值而不是 [] 操作符,在官方书籍《C++ GUI Qt 4编程(第二版)》的书中有特殊的强调说明,此课本的原作者据说是Qt开辟的焦点人员编写的,所以还是比力权势巨子,至于利用 at() 与利用 [] 操作符速度服从的比力,网上也有网友做过此类对比。原文在书的212页,这样形貌的:Qt对所有的容器和许多其他类都利用隐含共享,隐含共享是Qt对不渴望修改的数据决不进行复制的保证,为了使隐含共享的作用发挥得最好,可以接纳两个新的编程习惯。第一种习惯是对于一个(非常量的)向量大概列表进行只读存取时,利用 at() 函数而不消 [] 操作符,由于Qt的容器类不能辨别 [] 操作符是否将出现在一个赋值的左边还是右边,他假设最坏的情况出现而且强制执行深层赋值,而 at() 函数则不被答应出现在一个赋值的左边。

72. 如果是dialog窗体,必要在exec以后还能让其他代码继续执行,请在dialog窗体exec前增长一行代码,否则会壅闭窗体消息。

QDialog dialog;dialog.setWindowModality(Qt::WindowModal);dialog.exec();

73. 安全的删除Qt的对象类,猛烈建议利用deleteLater而不是delete,由于deleteLater会选择在符合的机遇进行释放,而delete会立即释放,很可能会出错瓦解。如果要批量删除对象聚集,可以用qDeleteAll,好比 qDeleteAll(btns);

74. 在QTableView控件中,如果必要自定义的列按钮、复选框、下拉框等其他模式表现,可以接纳自定义委托QItemDelegate来实现,如果必要禁用某列,则在自定义委托的重载createEditor函数返回0即可。自定义委托对应的控件在进入编辑状态的时间出现,如果想不停出现,则必要重载paint函数用drawPrimitive大概drawControl来绘制。

75. 将 QApplication::style() 对应的drawPrimitive、drawControl、drawItemText、drawItemPixmap等几个方法用认识了,再团结QStyleOption属性,可以玩转各种自定义委托,还可以直接利用paint函数中的painter进行各种绘制,各种牛逼的表格、树状列表、下拉框等,绝对屌炸天。QApplication::style()->drawControl 的第4个参数如果不设置,则绘制出来的控件不会应用样式表。

76. 心中有坐标,万物皆painter,猛烈建议在学习自定义控件绘制的时间,将qpainter.h头文件中的函数全部看一遍、试一遍、理解一遍,这里边包含了所有Qt内置的绘制的接口,对应的参数都试一遍,你会发现许多新大陆,会大大激发你的绘制的爱好,如同神笔马良一样平常,策马崩腾遨游代码绘制的世界。

77. 在利用setItemWidget大概setCellWidget的过程中,有时间会发现设置的控件没有居中表现而是默认的左对齐,而且不会自动拉伸添补,对于追求完满的程序员来说,这个可不大好看,有个终极通用办法就是,将这个控件放到一个widget的布局中,然后将widget添加到item中,这样就完满解决了,而且这样可以组合多个控件产生复杂的控件。

//实例化进度条控件QProgressBar *progress = new QProgressBar;//增长widget+布局奇妙实现居中QWidget *widget = new QWidget;QHBoxLayout *layout = new QHBoxLayout;layout->setSpacing(0);layout->setMargin(0);layout->addWidget(progress);widget->setLayout(layout);ui->tableWidget->setCellWidget(0, 0, widget);

78. 许多时间必要在已知配景致的情况下,能够清晰的绘制笔墨,这个时间必要盘算对应的笔墨颜色。

//根据配景致自动盘算符合的远景致double gray = (0.299 * color.red() + 0.587 * color.green() + 0.114 * color.blue()) / 255;QColor textColor = gray > 0.5 ? Qt::black : Qt::white;

79. 对QTableView大概QTableWidget禁用列拖动。

#if (QT_VERSION <= QT_VERSION_CHECK(5,0,0))    ui->tableView->horizontalHeader()->setResizeMode(0, QHeaderView::Fixed);#else    ui->tableView->horizontalHeader()->setSectionResizeMode(0, QHeaderView::Fixed);#endif

80. 从Qt4转到Qt5,有些类的方法已经废弃大概过期了,如果想要在Qt5中启用Qt4的方法,好比QHeadVew的setMovable,可以在你的pro大概pri文件中加上一行即可:DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0

81. Qt中的QColor对颜色封装的很完满,支持各种转换,好比rgb、hsb、cmy、hsl,对应的是toRgb、toHsv、toCmyk、toHsl,还支持透明度设置,颜色值还能转成16进制格式表现。

QColor color(255, 0, 0, 100);qDebug() << color.name() << color.name(QColor::HexArgb);//输出 #ff0000 #64ff0000

82. QVariant范例非常的强大,可以说是万能的范例,在进行配置文件的存储的时间,经常会用到QVariant的转换,QVariant默认自带了toString、toFloat等各种转换,但是还是不敷,好比有时间必要从QVariant转到QColor,而却没有提供toColor的函数,这个时间就要用到万能办法。

if (variant.typeName() == "QColor") {    QColor color = variant.value();    QFont font = variant.value();    QString nodeValue = color.name(QColor::HexArgb);}

83. Qt中的QString和const char *之间转换,最好用toStdString().c_str()而不是toLocal8Bit().constData(),好比在setProperty中如果用后者,字符串中文就会不精确,英文正常。

84. Qt的信号槽机制非常牛逼,也是Qt的独特的焦点功能之一,有时间我们在许多窗体中通报信号来实现更新大概处置惩罚,如果窗体层级比力多,好比窗体A的父类是窗体B,窗体B的父类是窗体C,窗体C有个子窗体D,如果窗体A一个信号要通报给窗体D,问题来了,必须先经过窗体B中转到窗体C再到窗体D才行,这样的话各种信号关联信号的connect会非常多而且管理起来比力乱,可以考虑增长一个全局的单例类AppEvent,公共的信号放这里,然后窗体A对应信号绑定到AppEvent,窗体D绑定AppEvent的信号到对应的槽函数即可,干净清爽整洁。

85. QTextEdit右键菜单默认英文的,如果想要中文表现,加载widgets.qm文件即可,一个Qt程序中可以安装多个翻译文件,不冲突。

86. Qt中有个全局的焦点切换信号focusChanged,可以用它做自定义的输入法。Qt4中默认会安装输入法上下文,好比在main函数打印a.inputContext会表现值,这个默认安装的输入法上下文,会拦截两个牛逼的信号QEvent::RequestSoftwareInputPanel和QEvent::CloseSoftwareInputPanel,以至于就算你安装了全局的事件过滤器依然辨认不到这两个信号,你只必要在main函数执行a.setInputContext(0)即可,意思是安装输入法上下文为空。

87. 在Qt5.10以后,表格控件QTableWidget大概QTableView的默认最小列宽改成了15,从前的版本是0,所以在新版的qt中,如果设置表格的列宽过小,不会应用,取的是最小的列宽。所以如果要设置更小的列宽必要重新设置ui->tableView->horizontalHeader()->setMinimumSectionSize(0);

88. Qt源码中内置了一些未公开的不能直接利用的黑科技,都藏在对应模块的private中,好比gui-private widgets-private等,好比zip文件解压类QZipReader、压缩类QZipWriter就在gui-private模块中,必要在pro中引入QT += gui-private才气利用。

#include "QtGui/private/qzipreader_p.h"#include "QtGui/private/qzipwriter_p.h"QZipReader reader(dirPath);QString path("");//解压文件夹到当前目录reader.etractAll(path);//文件夹名称QZipReader::FileInfo fileInfo = reader.entryInfoAt(0);//解压文件QFile file(filePath);file.open(QIODevice::WriteOnly);file.write(reader.fileData(QString::fromLocal8Bit("%1").arg(filePath)));file.close();reader.close();QZipWriter *writer = new QZipWriter(dirPath);//添加文件夹writer->addDirectory(unCompress);//添加文件QFile file(filePath);file.open(QIODevice::ReadOnly);writer->addFile(data, file.readAll());file.close();writer->close();

89. 理论上串口和网络收发数据都是默认异步的,操作系统自动调理,完全不会卡住界面,网上那些说收发数据卡住界面主线程的都是扯几把蛋,真正的耗时是在运算以及运算后的处置惩罚,而不是收发数据,在一些小数据量运算处置惩罚的项目中,一样平常不建议动用线程去处置惩罚,线程必要调理开销的,不要什么东西都往线程里边扔,线程不是万能的。只有当真正必要将一些很耗时的操作好比编码解码等,才必要移到线程处置惩罚。

90. 在构造函数中获取控件的宽高很可能是不精确的,必要在控件初次表现以后再获取才是精确的,控件是在初次表现以后才会设置好精确的宽高值,记住是在初次表现以后,而不是构造函数大概程序启动好以后,如果程序启动好以后有些容器控件好比QTabWidget中的没有表现的页面的控件,你去获取宽高很可能也是不精确的,万无一失的办法就是初次表现以后去获取。

91. 数据库处置惩罚一样平常建议在主线程,如果非要在其他线程,务必记得打开数据库也要在谁人线程,即在谁人线程利用数据库就在谁人线程打开,不能打开数据库在主线程,执行sql在子线程,很可能出问题。

92. 新版的QTcpServer类在64位版本的Qt下很可能不会进入incomingConnection函数,那是由于Qt5对应的incomingConnection函数参数变了,由之前的int改成了qintptr,改成qintptr有个好处,在32位上自动是quint32而在64位上自动是quint64,如果在Qt5中继续写的参数是int则在32位上没有问题在64位上才有问题,所以为了兼容Qt4和Qt5,必须按照不一样的参数写。

#if (QT_VERSION > QT_VERSION_CHECK(5,0,0))    void incomingConnection(qintptr handle);#else    void incomingConnection(int handle);#endif

93. Qt支持所有的界面控件好比QPushButton、QLineEdit自动关联 on_控件名_信号(参数) 信号槽,好比按钮的单击信号 on_pushButton_clicked(),然后直接实现槽函数即可。

94. QWebEngineView控件由于利用了opengl,在某些电脑上可能由于opengl的驱动过低会导致花屏大概各种奇奇怪怪的问题,好比showfullscreen的情况下鼠标右键失效,必要在main函数启用软件opengl渲染。

#if (QT_VERSION > QT_VERSION_CHECK(5,4,0))    //下面两种方法都可以,Qt默认接纳的是AA_UseDesktopOpenGL    QCoreApplication::setAttribute(Qt::AA_UseOpenGLES);    //QCoreApplication::setAttribute(Qt::AA_UseSoftwareOpenGL);#endif    QApplication a(argc, argv);

别的一个方法解决 全屏+QWebEngineView控件一起会产生右键菜单无法弹出的bug,必要上移一个像素

QRect rect = qApp->desktop()->geometry();rect.setY(-1);rect.setHeight(rect.height());this->setGeometry(rect);

95. QStyle内置了许多方法用处很大,好比精确获取滑动条鼠标按下处的值。

QStyle::sliderValueFromPosition(minimum(), maximum(), event->x(), width());

96. 用QFile读写文件的时间,保举用QTextStream文件流的方式来读写文件,速度快许多,根本上会有30%的提升,文件越大性能区别越大。

//从文件加载英文属性与中文属性对照表QFile fle(":/propertyname.txt");if (file.open(QFile::ReadOnly)) {    //QTextStream方法读取速度至少快30%#if 0    while(!file.atEnd()) {        QString line = file.readLine();        appendName(line);    }#else    QTextStream in(&file);    while (!in.atEnd()) {        QString line = in.readLine();        appendName(line);    }#endif    file.close();}

97. 用QFile.readAll()读取QSS文件默认是ANSI格式,不支持UTF8,如果在QtCreator中打开qss文件来编辑保存,这样很可能导致qss加载以后没有用果。

void frmMain::initStyle(){    //加载样式表    QString qss;    //QFile file(":/qss/psblack.css");    //QFile file(":/qss/flatwhite.css");    QFile file(":/qss/lightblue.css");    if (file.open(QFile::ReadOnly)) {#if 1        //用QTextStream读取样式文件不消区分文件编码 带bom也行        QStringList list;        QTextStream in(&file);        //in.stCodec("utf-8");        while (!in.atEnd()) {            QString line;            in >> line;            list << line;        }        qss = list.join("n");#else        //用readAll读取默认支持的是ANSI格式,如果不鉴戒用creator打开编辑过了很可能打不开        qss = QLatin1String(file.readAll());#endif        QString paletteColor = qss.mid(20, 7);        qApp->setPalette(QPalette(QColor(paletteColor)));        qApp->setStyleSheet(qss);        file.close();    }}

98. QString内置了许多转换函数,好比可以调用toDouble转为double数据,但是当你转完并打印的时间你会发现精确少了,只剩下三位了,其实原始数据还是完备的精确度的,只是打印的时间优化成了三位,如果要保证完备的精确度,可以调用 qSetRealNumberPrecision 函数设置精确度位数即可。

QString s1, s2;s1 = "666.5567124";s2.setNum(888.5632123, 'f', 7);qDebug() << qSetRealNumberPrecision(10) << s1.toDouble() << s2.toDouble();

99. 用QScriptValueIterator解析数据的时间,会发现总是会多一个节点内容,而且内容为空,如果必要跳过则增长一行代码。

while (it.hasNext()) {    it.next();        if (it.flags() & QScriptValue::SkipInEnumeration)             continue;         qDebug() << it.name();}

100. setPixmap是最糟糕的贴图方式,一样平常只用来简单的不是很频繁的贴图,频繁的建议painter绘制,默认双缓冲,在高级点用opengl绘制,利用GPU。

101. 如果必要在尺寸改变的时间不重绘窗体,则设置属性即可 this->setAttribute(Qt::WA_StaticContents, true); 这样可以避免可以避免对已经表现区域的重新绘制。

102. 默认程序中获取焦点以后会有虚边框,如果看着觉得碍眼不惬意可以去掉,设置样式即可:setStyleSheet("*{outline:0px;}");

103. Qt表格控件一些常用的设置封装,QTableWidget继承自QTableView,所以下面这个函数支持传入QTableWidget。

void QUIHelper::initTableView(QTableView *tableView, int rowHeight, bool headVisible, bool edit){    //奇数偶数行颜色交替    tableView->setAlternatingRowColors(false);    //垂直表头是否可见    tableView->verticalHeader()->setVisible(headVisible);    //选中一行表头是否加粗    tableView->horizontalHeader()->setHighlightSections(false);    //末了一行拉伸添补    tableView->horizontalHeader()->setStretchLastSection(true);    //行标题最小宽度尺寸    tableView->horizontalHeader()->setMinimumSectionSize(0);    //行标题最大高度    tableView->horizontalHeader()->setMaximumHeight(rowHeight);    //默认行高    tableView->verticalHeader()->setDefaultSectionSize(rowHeight);    //选中时一行团体选中    tableView->setSelectionBehavior(QAbstractItemView::SelectRows);    //只答应选择单个    tableView->setSelectionMode(QAbstractItemView::SingleSelection);    //表头不可单击#if (QT_VERSION > QT_VERSION_CHECK(5,0,0))    tableView->horizontalHeader()->setSectionsClickable(false);#else    tableView->horizontalHeader()->setClickable(false);#endif    //鼠标按下即进入编辑模式    if (edit) {        tableView->setEditTriggers(QAbstractItemView::CurrentChanged | QAbstractItemView::DoubleClicked);    } else {        tableView->setEditTriggers(QAbstractItemView::NoEditTriggers);    }}

104. 在一些大的项目中,可能嵌套了许多子项目,有时间会遇到子项目依赖其他子项目标时间,好比一部分子项目用来生成动态库,一部分子项目依赖这个动态库进行编译,此时就必要子项目按照顺序编译。

TEMPLATE = subdirs#设置ordered参数以后会依次编译 demo designer examplesCONFIG  += orderedSUBDIRS += demoSUBDIRS += designerSUBDIRS += examples

105. MSVC编译器的选择说明

- 如果是32位的Qt则编译器选择x86开头的

- 如果是64位的Qt则编译器选择amd64开头的

- 详细是看安装的Qt构建套件版本以及目标运行平台的系统位数和架构

- 一样平常现在的电脑默认以64位的居多,选择amd64即可

- 如果用户必要兼容32位的系统则建议选择32位的Qt,这样即可在32位也可以在64位系统运行

- 诸葛大佬增补:x86/x64都是编译环境和运行环境相同,没有或。带下划线的就是交叉编译,前面是编译环境,后面是运行环境。

| 名称 | 说明 |

| ------ | ------ |

|x86|32/64位系统上编译在32/64位系统上运行|

|x86_amd64|32/64位系统上编译在64位系统上运行|

|x86_arm|32/64位系统上编译在arm系统上运行|

|amd64|64位系统上编译在64位系统上运行|

|amd64_x86|64位系统上编译在32/64位系统上运行|

|amd64_arm|64位系统上编译在arm系统上运行|

106. 许多时间用QDialog的时间会发现壅闭了消息,而有的时间我们渴望是后台的一些消息继续运行不要制止,此时必要做个设置。

QDialog dialog;dialog.setWindowModality(Qt::WindowModal);

107. 许多初学者乃至几年工作履历的人,对多线程有很深的误解和滥用,尤其是在串口和网络通信这块,什么都往多线程里面丢,一旦遇到界面卡,就把数据收发啥的都搞到多线程里面去,殊不知绝大部分时间那根本没啥用,由于没找到出问题的根源。

- 如果你没有利用wait***函数的话,大部分的界面卡都出在数据处置惩罚和展示中,好比传过来的是一张图片的数据,你必要将这些数据转成图片,这个肯定是耗时的;

- 另有就是就收到的数据曲线绘制出来,如果过于频繁大概间隔过短,肯定会给UI造成很大的压力的,最好的办法是解决如何不要频繁绘制UI好比归并数据一起绘制等;

- 如果是由于绘制UI造成的卡,那多线程也是没啥用的,由于UI只能在主线程;

- 串口和网络的数据收发默认都是异步的,由操作系统调理的,如果数据处置惩罚复杂而且数据量大,你要做的是将数据处置惩罚放到多线程中;

- 如果没有严酷的数据同步需求,根本不必要调用wait***之类的函数来立即发送和接收数据,实际需求中大部分的应用场景其实异步收发数据就充足了;

- 有严酷数据同步需求的场景还是放到多线程会好一些,不然你wait***就卡在那里了;

- 多线程是必要占用系统资源的,理论上来说,如果线程数目超过了CPU的焦点数目,其实多线程调理可能耗费的时间更多,各位在利用过程中要衡量利弊;

108. 在嵌入式linux上,如果设置了无边框窗体,而该窗体中又有文本框之类的,发现没法产生焦点进行输入,此时必要主动激活窗体才行。

//这种方式设置的无边框窗体在嵌入式装备上无法产生焦点setWindowFlags(Qt::WindowStaysOnTopHint | Qt::FramelessWindowHint | Qt::X11BypassWindowManagerHint);//必要在show以后主动激活窗体w->show();w->activateWindow();

109. QString的replace函数会改变原字符串,切记,他在返回替换后的新字符串的同时也会改变原字符串,我的乖乖!

110. QGraphicsEffect类的相关结果很炫,可以实现许多结果好比透明、渐变、阴影等,但是该类很耗CPU,如果不是特殊必要一样平常不建议用,就算用也是要用在该部件后期不会发生频繁绘制的场景,不然会让你哭晕在厕所。

111. 在差别的平台上文件路径的斜杠也是不一样的,好比linux系同一样平常都是 / 斜杠,而在windows上都是 \ 两个反斜杠,Qt自己程序内部无论在win还是linux都支持 / 斜杠的路径,但是一些第三方库的话可能必要转换成对应系统的路径,这就必要用到斜杠转换,Qt当然内置类方法。

QString path = "C:/temp/test.txt";path = QDir::toNativeSeparators(path);//输出 C:\temp\test.txtQString path = "C:\temp\test.txt";path = QDir::toNativeSeparators(path);//输出 C:/temp/test.txt

112. 巧用QMetaObject::invokeMethod方法可以实现许多结果,包括同步和异步执行,好比有个应用场景是在回调中,必要异步调用一个public函数,如果直接调用的话会发现不乐成,此时必要利用 QMetaObject::invokeMethod(obj, "fun", Qt::QueuedConnection); 这种方式来就可以。invokeMethod函数有许多重载参数,可以传入返回值和执行方法的参数等。

113. Qt5中的信号是public的,可以在必要的地方直接emit即可,而在Qt4中信号是protected的,不能直接利用,必要定义一个public函数来emit。

114. Qt5.15版本开始官方不再提供安装包,只提供源码,可以自行编译大概在线安装,估计每次编译各种版本太麻烦,更多的是为了统计网络用户利用信息好比通过在线安装,后期可能会渐渐加大贸易化力度。

大神总结的Qt开辟履历,满满的都是干货


来源:https://www.toutiao.com/a6872379467587650061/
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则