C++ 到 Qt
Qt 是 C++ 的庫,Qt在ansi C++ 的基礎上進行了一點擴展。
但國內似乎比較浮躁,學Qt的很多連基本的C++如何編譯似乎都不太清楚。本文舍棄IDE或qmake、cmake等工具的束縛,嘗試通過幾個例子,一步一步從標準 C++ 的編譯過渡到 Qt 的編譯。
本文涉及的都是最基本的東西,或許可以說,只要你用C++ Qt,不管是通過哪種工具(qmake、cmake、boost.build、qtcreator、vs2008、Eclipse、...),本文的內容都是需要理解的(盡管真正寫程序時,我們都不會直接用C++編譯器來編譯Qt程序)。
如果你對命令行比較恐懼.
例子一:簡單的控制臺程序
一個很簡單的例子,沒用到Qt擴展:(也就是說,這是一個普通的C++程序)
#include <QtCore/QCoreApplication>#include <QtCore/QDebug>int main(int argc, char** argv){ QCoreApplication app(argc, argv); qDebug()<<"hello qt!"; app.exec();}[喝小酒的網摘]http://blog.hehehehehe.cn/a/4033.htm
我們都知道,編譯一個C++的程序,無非是 編譯預處理,編譯、鏈接
編譯預處理器:頭文件路徑 和 必要的宏
編譯器:一些編譯參數
鏈接器:一些鏈接參數 和 要鏈接的庫
g++
簡單一行命令,即可生成 main.exe (linux下,則生成可執行程序 main)
g++ main.cpp -DQT_CORE_LIB -Ie:Qt4.7.0include -o main -Le:Qt4.7.0lib -lQtCore4
單行命令,很簡單:
-I 指定頭文件路徑
-L 指定庫文件路徑
-l 指定需要鏈接的庫
-D 定義必要的宏(其實對這個小程序,這個宏也沒必要用)
-o 指定生成的可執行文件名
cl
簡單一行命令,即可生成 main.exe
cl main.cpp -ID:/Qt/4.7.0/include -DQT_CORE_LIB -Femain -link -LIBPATH:D:/Qt/4.7.0/lib QtCore4.lib
依然很簡單
-I 頭文件路徑
-D 定義必要的宏
-Fe 指定可執行程序文件名
-link 后面是鏈接器參數
-LIBPATH 庫文件路徑
例子二:簡單的GUI程序
這次稍微復雜一點,不是單一的控制臺程序,而是一個簡單的GUI程序
main.cpp
#include <QtGui/QApplication>#include "widget.h"int main(int argc, char** argv){ QApplication app(argc, argv); Widget w; w.show(); return app.exec();}
widget.h
#include <QtGui/QWidget>class Widget : public QWidget{public: Widget(QWidget * parent=NULL);};
widget.cpp
#include "widget.h"Widget::Widget(QWidget * parent) :QWidget(parent){}
同樣,這個程序未使用Qt的擴展,直接用C++的編譯器編譯:
g++
g++ main.cpp widget.cpp -DQT_CORE_LIB -DQT_GUI_LIB -Ie:Qt4.7.0-beta2include -o main -Le:Qt4.7.0-beta2lib -lQtCore4 -lQtGui4
因為我們使用了QtGui模塊,所以和前面相比:
增加了 -DQT_GUI_LIB 和 -lQtGui4
多了一個文件 widget.cpp
注意: Windows下
如果在非windows平臺下,這條命令就可以了。但windows下,你知道的:分console和windows兩個鏈接子系統,而且入口函數分 main 和 WinMain 。
這條命令,編譯出的 main.exe 會彈出控制臺。要想不要控制臺,則使用下面的命令:
g++ main.cpp widget.cpp -DQT_CORE_LIB -DQT_GUI_LIB -DQT_NEEDS_QMAIN -Ie:Qt4.7.0-beta2include -o main -Le:Qt4.7.0-beta2lib -lQtCore4 -lQtGui4 -lqtmain -Wl,-subsystem,windows
多了兩個選項:
qtmain 該庫中一個WinMain 函數,它會調用我們的代碼的main函數。即對編譯器來說:入口函數的名字變了
-Wl,-subsystem,windows 你知道的,鏈接windows子系統
對與MinGW來說,此處多了一個宏 QT_NEEDS_QMAIN,這個東西很有意思。在Qt Windows下鏈接子系統與入口函數(終結版) 中我們詳細提到了這個。(在此處,不過你可以忽略它,不會出錯,而且也不會有可感覺到的差異)
cl
同windows下的g++基本一樣,帶控制臺:
cl main.cpp widget.cpp -ID:/Qt/4.7.0/include -DQT_CORE_LIB -DQT_GUI_LIB -Femain -link -LIBPATH:D:/Qt/4.7.0/lib QtCore4.lib QtGui4.lib
不帶控制臺:
cl main.cpp widget.cpp -ID:/Qt/4.7.0/include -DQT_CORE_LIB -DQT_GUI_LIB -Femain /MD -link -LIBPATH:D:/Qt/4.7.0/lib -subsystem:windows qtmain.lib QtCore4.lib QtGui4.lib
分析同上:指定鏈接子系統,啟用WinMain入口函數
多文件的程序如何管理
直接調用編譯器有什么壞處呢?
參數多啊,每次手動輸入,難免出錯。(例子中我們用的參數已經盡可能少了,可能都還是讓你眼暈了)。
其次呢,很重要的一點,每次只要一個文件修改,所有東西都要重新編譯。
改變這種狀況的辦法,傳統的就是寫 Makefile,然后編譯時只需要輸入 make 就行了,他會判斷哪些文件被改動需要重新編譯。
另外就是VS等一些IDE自己提供的功能。下面簡單看一下本例子對應makefile文件:
mingw32-make的Makefile文件
CPPFLAGS = -DQT_CORE_LIB -DQT_GUI_LIB -Ie:Qt4.7.0include
LDFLAGS = -Le:Qt4.7.0lib -lQtCore4 -lQtGui4 -lqtmain -Wl,-subsystem,windows
objects = main.o widget.o
dest = main
$(dest) : $(objects)
g++ -o $@ $(objects) $(LDFLAGS)
nmake的Makefile文件
CPPFLAGS = -ID:/Qt/4.7.0/include -DQT_CORE_LIB -DQT_GUI_LIB -MD
LDFLAGS = -LIBPATH:D:/Qt/4.7.0/lib -subsystem:windows qtmain.lib QtCore4.lib QtGui4.lib
objects = main.obj widget.obj
dest = main.exe
$(dest) : $(objects)
link $(objects) $(LDFLAGS)
對此不做介紹,因為Makefile編寫也是一門學問。相當難寫,所有才有qmake、cmake這些工具來幫我們生成Makefile文件
例子三:引入moc
Qt 對 C++ 的擴展主要是3個方面:
元對象系統,包含Q_OBJECT宏的文件(.h, .cpp等)需要 moc 預處理
資源系統,.qrc 文件 需要 rcc 進行預處理
界面系統,.ui 文件 需要 uic 進行預處理
<p post-footer"="" style="margin-top: 0px; margin-bottom: 6px; padding: 0px; text-indent: 2em; line-height: normal;">
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。