- 1.Qt簡介
- 2.Qt 編程關鍵技術
- 2.1 信號與槽
- 2.2 Qt事件處理
- 3.Qt開發與實例分析
- 3.1 開發環境
- 3.2 系統實現基本框架
- 3.3 數據庫管理
- 3.5 對Excel進行操作
- 4.系統的打包和測試
- 4.1 Mac系統上打包Qt
- 4.2 Windows系統上打包Qt。
- 4.3 發布軟件測試
- 5.Qt開發常見問題
- 5.1 ui文件轉換為頭文件問題
- 5.2 Mac打包時出現不包含“libmysqlclient.18.dylib”問題
- 5.3 添加應用圖標
- 6.參考文獻
1. Qt簡介
Qt是1991年奇趣科技 開發的一個跨平台的C++圖形用戶界面應用程序框架。它提供給應用程序開發者建立藝術級的圖形用戶界面所需的所有功能。Qt很容易擴展,並且允許真正地組 件編程。基本上,Qt 同 X Window 上的 Motif,Openwin,GTK 等圖形界 面庫和 Windows 平台上的 MFC,OWL,VCL,ATL 是同類型的東西。
2008年,奇趣科技被諾基亞公司收購,QT也因此成為諾基亞旗下的編程語言工具。 2012年,Qt被Digia收購。2014年4月,跨平台集成開發環境Qt Creator 3.1.0正式發布,實現了對於iOS的完全支持,新增WinRT、Beautifier等插件,廢棄了無Python接口的GDB調試支持,集成了基於 Clang的C/C++代碼模塊,並對Android支持做出了調整,至此實現了全面支持iOS、Android、WP。(百度百科)
Qt作為高質量的跨平台框架,具有支持平台廣泛、功能完整、開源、執行效率高、界面開發簡單、開發工具完備等特性。下表是Qt與目前較為流行的跨平台解決方案Java和Xamarin比較結果。
Qt | Java | Xamarin | |
---|---|---|---|
桌面平台 | Windows Mac Linux Solaris |
Windows Mac Linux Solaris |
Windows Mac Linux |
移動平台 | Android iOS Window Phone |
Android |
Android iOS Window Phone |
開發語言 | C++ |
Java |
C# |
是否開源 | 有基於LGPL開源版本和商業版本 | OpenJDK 開源 |
有商業版本和基於Mono 框架為開源 |
開發工具 | Qt Creator Qt Designer |
Eclipse NetBeans |
Monodevelop Virtual Studio |
功能 | 十分完整 | 十分完整 | 不十分完整 |
開發難度 | 簡單 | 較復雜 | 較簡單 |
成熟度 | 十分成熟 | 十分成熟 | 不十分成熟 |
版本 | 5..5 | 8.60 | 5.7 |
效率 | 高 | 較差 | 一般 |
依托公司 | Digia.com(之前為Nokia) | Oracle.com(之前是SUN) | Xamarin.com |
Qt 不但擁有了完善的C++圖形庫,而且近年來的版本逐漸集成了數據庫、OpenGL庫、多媒體庫、網絡、腳本庫、XML庫、WebKit庫等組件,其核心庫 也加入了進程間通信、多線程等模塊,極大的豐富了Qt開發大規模復雜跨平台應用程序的能力.Qt的開發工具Qt Creator(IDE)、GUI Designer(界面設計)、Build Tools(編譯)、Help System(幫助系統)I18n Tools(多語言工具)等,也極大簡化了開發應用的難度。下圖為Qt的技術堆棧
2. Qt 編程關鍵技術
2.1 信號與槽
信 號和槽機制是QT的核心機制,是一種高級接口,應用於對象之間的通信。信號和槽是QT自行定義的一種通信機制,它獨立於標准的C/C++語言,因此要正確 的處理信號和槽,必須借助一個稱為 moc(Meta Object Compiler)的Qt工具,該工具是一個C++預處理程序,它為高層次的事件處理自動生成所需要的附加代碼。
所有從QObject或 其子類(例如QWidget)派生的類都能夠包含信號和槽。當對象改變其狀態時,信號就由該對象發射(emit)出去,這就是對象所要做的全部事情,它不 知道另一端是誰在接收這個信號。槽用於接收信號,但它們是普通的對象成員函數。一個槽並不知道是否有任何信號與自己相連接。對象甚至並不了解具體的通信機 制。
信號與槽連接是任意個的,甚至信號與信號也可以連接的,這時無論第一個信號什么時候發射系統都將立刻發射第二個信號。總之,信號與槽構造了一個強大的部件編程機制。
2.2 Qt事件處理
Qt可以說是是以事件驅動的UI工具集,信號與槽在多線程的實現也依賴於Qt的事件處理機制。在Qt中,事件被封裝成一個個對象,所有的事件均繼承自抽象類QEvent。Qt中事件的產生、分發、接受和處理:
-
事件的產生如按鍵,點擊鼠標等等動作所產生的keyPressEvent, keyReleaseEvent,mousePressEvent,mouseReleaseEvent等事件(分別被封裝成QMouseEvent和 QKeyEvent中),這些事件來自於底層的操作系統,它們以異步的形式通知Qt事件處理系統。
-
事件的接受和處理使用QObject。事件處理機制是QObject三大職責(內存管理、內省與事件處理制)之一。任何一個想要接受並處理事件的對象均須繼承自QObject,可以選擇重載QObject::event()函數或事件的處理權轉給父類。
-
事件的分發:對於non-GUI的Qt程序,是由QCoreApplication負責將QEvent分發給QObject的子類-Receiver。對於Qt GUI程序,由QApplication來負責。
3. Qt開發與實例分析
下面通過一個指標計算的程序分析Qt開發完整過程。該系統需求:
- 從數據庫中讀取計算指標參數。(數據庫操作組件)
- 計算所的指標需要用溫度計的形式展示,並截圖以便在文檔中使用。
*能夠將計算數據通過Excel導入到數據庫中,並能夠將計算結果導出到Excel中。 - 需要有Windows和Mac兩個版本且功能和界面布局要基本相同。(跨平台)
3.1 開發環境
下表為使用的開發環境,基本為開源軟件
系統平台 | Mac OSX 10.11 |
---|---|
SDK | Qt 5.5 |
開發工具 | Qt Creator Qt Designer |
開發語言 | C++ SQL |
數據庫 | SQLite 3 |
測試平台 | Mac OSX Window XP Window 7 |
其他開源軟件 | FireFox SQLite Manager Inno Setup Compiler VirtualBox yEd QtXlsx |
3.2 系統實現基本框架
該系統綜合使用了Qt的數據庫模塊、GUI模塊和第三方的QtXlsx模塊,使用VirtualBox完成系統打包和測試,使用Inno setup對Windows程序進行封裝,使用SQLite Manager管理SQLite數據庫。下圖為系統實現基本框架。
3.3 數據庫管理
Qt 對數據的支持相當完善,Oracle、SQL Server、DB2、 SyBase、 MySQL、 PostgreSQL、 SQLite3 都可以完美的支持。由於需求要使用本地數據庫並盡可能的小巧靈活,選擇SQLite3作為數據庫,通過FireFox 插件SQLite Manager進行管理,圖4為SQLite Manager 管理界面。Qt使用QsqlDatabase類來管理數據,該類中包括所有數據庫的管理行為,如addDatabase為添加數據庫驅動,下面為連接 SQLite3示例代碼。
QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");
if (!QSqlDatabase::drivers().contains("QSQLITE"))
QMessageBox::critical(0, QObject::tr("Unable to load database"), QObject::tr("This demo needs the SQLITE driver"));
db.setDatabaseName (dbName);
if (!db.open()) {
QMessageBox::critical (0,QObject::tr ("DataBase Error"),db.lastError ().text ());
return false;
}
數據庫連接代碼
對於已經連接上的數據庫可以使用兩種方法來進行操作:
- 1.使用QSqlQuerry,該方法可以直接執行SQL語句,使用與對數據庫的批量處理。如:
“query.exec ("DROP VIEW IF EXISTS 'data_x300';");”
- 2.使用QSqlTable,將數據庫中的表轉換為Qt中的Table,然后進行數據庫增添刪改等事務性操作,簡單而且安全,推薦使用這種方法操作代碼。下面為使用QSqlTable代碼
if((model->insertRow (row))&&
(model->setData(model->index(row,0),id))&&
(model->setData(model->index(row,1),name))&&
(model->setData(model->index(row,2),newPasswd))&&
(model->setData(model->index(row,3),hint))&&
(model->submitAll()))
QMessageBox::warning (this, "Correct","用戶添加成功!");
else
QMessageBox::warning (this, "Error","密碼添加失敗!");
Qt使用Qt Designer Form,該方法直觀且功能強大。首先使用Qt Designer建立並繪制以xxx.ui為后綴的文件,然后在編譯時會將其轉換為ui_xxx.h頭文件,再進行統一的編譯。圖6為Qt Designer界面。在Qt5加入了對基於JS的QML進行界面的支持,QML覺Qt Designer Form有更強的控制能力和美化能力,而且使用目前流行的JS語言,相信必將成為未來發展趨勢。
該系統中還要求用溫度計顯示計算結果,因此單單是界面繪制工具並不能滿足要求。需要先找到溫度計的樣本圖,使用繪圖工具進行修改,最后使用Style Sheet腳本對控件進行美化處理。下圖為StyleSheet處理腳本和效果。
該系統需要對結果截屏,Qt中截屏又兩種方式,一種方式是在整個屏幕中,根據相對位置進行截屏(pixmap.grabWindow());另外一種是在Qt中的一個窗口中(pixmap.grabWidget()),根據相對位置進行截屏。下面為截屏代碼:
int grapX= year_lineEdit->geometry ().x ();
int grapY = year_lineEdit->geometry ().y ();
pix = pixmap.grabWidget (this, grapX-2 ,grapY -2, this->width ()-grapX, this->height ()-grapY -140);
3.5 對Excel進行操作
該系統將需用Excel將計算數據導入到數據庫中,並將計算結果導出到Excel中。但在Qt中並沒有對Office進行處理的組件,因此需要第三 方組件進行支援。我們使用開源的Qt模塊QtXlsx該模塊可以對Excel進行操作,功能十分強大。(Qt更多開源模塊可以在 http://inqlude.org 上找到。)使用方法如下:
- 1.首先在網站上下載QtXlsx模塊項目,安裝Perl5,使用Qt Creator打開並編譯;
- 2.然后再命令行中使用“qmake; make; make install”來安裝庫
- 3.在pro文件中加入xlsx模塊,在頭文件中加入"xlsxdocument.h"頭文件
即可以使用QtXlsx庫進行Excel操作了,下面為QtXlsx操作代碼:
QString fileName = path + "/index.xlsx";
QXlsx::Document *xlsx = new QXlsx::Document(fileName);
int rowC = (model->rowCount ());
int columnC = (model->columnCount ());
for (int i = 0; i < columnC; ++i) {
xlsx->write (1,i+1,model->headerData (i,Qt::Horizontal).toString ());
}
for (int i = 0; i < rowC; ++i) {
for (int j = 0; j < columnC; ++j) {
xlsx->write ((i+2),(j+1), model->record (i).value (j).toString ());
}
}
if (!fileName.isEmpty()) {
if(xlsx->save())
QMessageBox::warning (this,"Correct","數據導出成功");
else
QMessageBox::warning (this,"Error","數據導出失敗");
}
4. 系統的打包和測試
4.1 Mac系統上打包Qt
需要使用otool和macdeployqt兩個工具,otool用於定位適用的動態鏈接庫文件,macdeployqt用於對生成的Release版本的程序進行打包。
具體步驟如下:
-
1.用Qt Creator編譯生成Release版本程序,並測試通過;
-
2.進入build-q***-Qt_5_2_1_clang_64-Release文件夾;
-
3.在命令行下使用“otool –L”命令查看適用的動態鏈接庫文件,如圖所示。如缺少文件,添加到環境變量中;
otool輸出結果
- 4.在命令行下使用macdeployqt進行打包。下圖為打包后應用結構
打包應用結構
- 5.生成的App文件再使用Disk Utility程序封裝,就可以發布了;
4.2 Windows系統上打包Qt。
使用windeployqt工具生成需要打包的文件夾時,會漏掉一些文件,因此需要手動添加一些動態鏈接庫。具體步驟如下:
-1.用VirtualBox 建立Windows 7虛擬機,安裝Qt開發完整的平台;
-
2.將QtXlsx源程序拷貝到虛擬機中,安裝Perl5,編譯安裝該模塊;
-
3.將待打包應用程序源代碼拷貝到虛擬機中,編譯成Realse版本應用;
-
4.將應用拷到一個獨立文件夾中用windeployqt,生成需要的動態鏈接庫文件;
-
5.將其他需要的動態鏈接庫文件從Qt安裝目錄中拷貝到該目錄中;
動態鏈接文件圖
- 6.使用inno setup工具對該目錄進行封裝即可發布了。
Inno Setup
4.3 發布軟件測試
測試采用白盒測試,在Virtual Box分別建立全新的Mac OSX,Windows XP和Windows 7
操作系統虛擬機,將打包程序分別拷貝到相應的系統平台中。分別安裝並測試系統功能是否符合要求。如果不符合,需要重新編程、編譯、打包和測試,直到滿意為止。
5. Qt開發常見問題
5.1 ui文件轉換為頭文件問題
有時Qt Creator編譯時會出現一些問題,提示缺少ui_.h頭文件。這是Qt系統出現了問題,解決方法是手動將ui文件轉換為相應的頭文件。如對.ui文件,使用:
$ uic ***.ui -o ui_***.h
將其手動的轉換為相應的頭文件就可以編譯了。
5.2 Mac打包時出現不包含“libmysqlclient.18.dylib”問題
在Mac系統中打包可能出現缺少“libmysqlclient.18.dylib”文件問題,這是因為系統沒有安裝MySQL。解決方法是先安 裝,macport,然后使用macport安裝MySQL。由於默認libmysqlclient.18.dylib文件位置不在搜索目錄中,還需要將 其拷貝到相應的目錄中。
5.3 添加應用圖標
對於Windows應用,需要建立一個rc文件說明ico圖標文件,在pro文件中添加rc文件。表 為一個示例:
#Myapp.rc:
IDI_ICON1 ICON DISCARDABLE "myappico.ico"
Myapp.pro:
RC_FILE = myapp.rc
對於Mac應用,需要生成圖片轉成為icns文件,然后在pro文件中添加icns文件:
ICON = myapp.icns
6.參考文獻
[1] Qt . [EB/OL].http://qt-project.org/
[2] Qt wiki. [EB/OL].http://zh.wikipedia.org/zh-cn/qt
[3] SQLite. [EB/OL].http://sqlite.org/
[4] SQLite Manager . [EB/OL].https://addons.mozilla.org/zh-CN/firefox/addon/sqlite-manager/
[5] GIMP. [EB/OL].http://www.gimp.org/
[6] Inno setup tools. [EB/OL]. http://www.jrsoftware.org/isinfo.php
[7] Virtual Box. [EB/OL]. https://www.virtualbox.org/
[8] OpenOffice. [EB/OL]. http://www.openoffice.org/zh-cn/
[9] yEd. [EB/OL]. http://www.yworks.com/en/products_yed_about.html
[10] QtXlsx. [EB/OL]. http://qtxlsx.debao.me/
[11] Java. [EB/OL]. http://www.java.com/zh_CN/
[12] Xamarin. [EB/OL]. http://xamarin.com/
[13] Mono. [EB/OL]. http://www.mono-project.com/Main_Page
[14] Java. [EB/OL]. http://openjdk.java.net/
[15]Qt 幫助. [EB/OL]. http://qt-project.org/doc/
本文原創,轉載請注 獅子座流星