Qt4問題集錦

1、Qt程序發佈後加載的jpg、jpeg圖片不可見編程

問題的提出:ide

最近在客戶機器上部署安裝QT編寫的軟件,發現只要是jpg、jpeg格式的圖片都沒法顯示出來。最後發現必須按以下述步驟才能顯示jpg、jpeg格式的圖片:
一、 在你主啓動程序即exe同一目錄下新建一個目錄,目錄名必須和QT安裝目錄下的imageformats目錄同名。也即新建一個名爲imageformats的文件夾。
2 、找到QT安裝目錄下 C:\Qt\4.8.5\plugins\imageformats子目錄,將該子目錄下的qjpeg4.dll文件複製到步驟1中新建的imageformats目錄便可。
      此時再次啓動主程序,如今發現jpg、jpeg格式的圖片能夠顯示出來了。

說明:步驟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進行外部聲明便可。

相關文章
相關標籤/搜索