1、Qt程序发布后加载的jpg、jpeg图片不可见编程
问题的提出:ide
说明:步骤2中红色路径我QT的安装路径,你的路径可能和我这不同,请自行更改。函数
2、运行Qt程序时碰到QWidget: Must construct a QApplication before a QPaintDeviceui
问题的提出:spa
以前编译Qwt源码生成qwtd.dll,qwt.dll,而后在工程.pro文件中使用时引入Qwt模块:debug
DEFINES += QT_DLL QWT_DLL
INCLUDEPATH += C:/QtSDK/Desktop/Qt/4.8.1/mingw/include/Qwt
LIBS += -L"C:/QtSDK/Desktop/Qt/4.8.1/mingw/lib" -lqwtd
LIBS += -L"C:/QtSDK/Desktop/Qt/4.8.1/mingw/lib" -lqwt
结果程序运行时,出现QWidget: Must construct a QApplication before a QPaintDevice
网上搜索的结果是Releases和DEBUG版本的库混在一块儿了,虽然他们是不一样的名字(Debug版本带个d),可是一直不明白。我生成release版后,直接运行.exe时发现提示缺乏qwtd.dll库,
此时才发现果真是库的问题,生成release版却调用了debug版的库qwtd.dll。
问题解决:将.pro文件中Qwt模块引入代码改成:unix
DEFINES += QT_DLL QWT_DLL
INCLUDEPATH += C:/QtSDK/Desktop/Qt/4.8.1/mingw/include/Qwt
CONFIG(debug,debug|release) {
unix|win32: LIBS += -L"C:/QtSDK/Desktop/Qt/4.8.1/mingw/lib" -lqwtd
} else {
unix|win32: LIBS += -L"C:/QtSDK/Desktop/Qt/4.8.1/mingw/lib" -lqwt
}
此时,编译成debug版则只会调用qwtd.dll,而生成release版则只会调用qwt.dll。指针
3、Qt编写上位机必定要初始化变量以及谨慎操做指针(尤为是QWidget控件指针)调试
背景:在编写QT上位机界面时,界面在运行的时候常常出现卡死或者直接挂掉的怪现象。code
正文:上位机有个函数为check_receive();该函数的做用为定时调用循环检测USB是否有数据。如有,则将信息打印到界面窗体上。界面上有两个QTableWidget窗体
"ui->can1tableWidget与ui->can2tableWidget",根据传上来的的数据某个字节信息为一、或2来打印到对应的窗体上。代码以下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
QTableWidget *canselWidget = NULL;
unsigned
int
CANSelCnt;
if
(CANData.CANSel == 1)
{
CANSelCnt = 第1个窗体显示的行数;
//伪代码
canselWidget = ui->can1tableWidget ;
}
else
if
(CANData.CANSel == 2)
{
CANSelCnt = 第2个窗体显示的行数;
//伪代码
canselWidget = ui->can2tableWidget ;
}
//接着即便用canselWidget来对界面进行操做。
|
接着,总会出现,QT上位机界面直接卡死甚至挂掉的问题。观察现象发现,APP在显示数据窗体时即疯狂地新增新的行数。再研究代码,而后将CANSelCnt打印出来,发现其值为一个很大的随机值。
解决方案:CANSelCnt 在定义的时候要初始化!!!
接着运行上位机发现,APP显示数据窗体再也不疯狂的新增行数了。可仍是出现挂掉的现象!!
进一步调试才发现如果CANData.CANSel的值不是为一、2那会出现什么状况! 就会对canselWideget这个NULL指针进行操做!更改代码以下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
switch
(CANData.CANSel)
{
case
1:
CANSelCnt = 第1个窗体显示的行数;
//伪代码
canselWidget = ui->can1tableWidget ;
break
;
case
2:
CANSelCnt = 第2个窗体显示的行数;
//伪代码
canselWidget = ui->can2tableWidget ;
break
;
default
:
// 防止后续代码对空指针进行操做,直接返回。
return
;
}
|
总结:
一、此处代码写的很是不当心,犯如此低级的错误却花费了1天多的时间(还觉得是下位机没配置好!)!下次必定要把握住程序运行的每一个通路,杜绝此现象再次发生。
二、因为以前一直在写下位机代码,因此不赋初值的习惯也带入到这里,出了此次惨痛教训!
(如下讨论仅针对下位机)在下位机,为什么会常常出现不赋初值的状况发生。(应该说是在声明的时候不会赋初值。)
首先,最重要的是,下位机保存全局变量的区域为掉电易失区域,因此获得的变量值会为默认"0"值,严谨的作法仍是会初始化全局变量。
其次,在多个".c"文件包含一个".h"文件的状况下,若在".h"文件中赋初值,则至关于在其内即声明又定义了,那么编译时,即会出现以下报错:keil *** ERROR L104: MULTIPLE PUBLIC DEFINITIONS (报错信息不完整,只挑了重点部分)。因此说有多个".c"文件须要包含该".h"文件时,不能进行变量的定义,只能进行声明!而后在"main函数"内对其进行初始化操做,不然会出现以上错误,即重复定义!
那么多个"c"文件包含一个".h"文件具体该如何操做呢?
我本身当时的错误想法既是:
在".h"文件内,声明全局变量、函数,譬如uchar aa;void sum(uchar aa); 而后多个".c"文件#include该".h"文件,结局很显然,重复定义错误跑不掉。
何不使用 #ifndef #define #endif ?结果证实并无什么卵用。
正确的作法是,
在".c"文件内声明全局变量、函数,譬如uchar aa;void sum(uchar aa);,并在".c"文件内实现该函数。
而后,在".h"文件,将变量aa,函数void sum(uchar aa);声明为extern,这样,其余".c"包含该".h"文件即不会提示重复定义,也能够调用其内部的函数。
其实这种作法其实至关于某个须要调用该".c"文件的其余"XXX.c"文件在其文件内 extern 该“.c"文件内实现的函数及定义的变量。如果多个文件须要使用使用,每一个".c"文件都需 extern 一样的变量和函数,显然在作重复工做,因而就将它放在一个".h"文件,多个".c"文件须要调用时直接包含该".h"文件就能够实现 extern 了。
总之,要养成良好的编程习惯,编写下位机时最好不要在.h文件去定义一个变量,更不能在.h文件去初始化变量。变量定义与初始化在.c文件进行,若多个外部.c文件须要调用,则在.h文件中添加extern进行外部声明便可。