Qt開發入門

Qt的初步研究

目錄

一、Qt基本情況的介紹... 3

1、歷史... 3

2、基本介紹... 3

二、Qt開發準備... 4

1、Qt的開發環境及搭建... 4

1.1、開發環境... 4

1.2、Qt Library + Qt Creator. 4

1.2.1、安裝包... 4

1.2.2、安裝... 5

1.2.3、配置... 6

1.2.4、新建項目... 13

1.2.5、編譯測試... 17

1.3、VS+Qt插件(還有問題沒解決)... 17

1.3.1、安裝包... 17

1.3.2、安裝... 18

1.3.3、配置... 18

1.3.4、新建項目... 22

1.3.5、編譯測試(編譯沒通過,可能配置不正確)... 24

1.4、小結... 26

2、系統庫的使用及程序發佈... 26

2.1、系統API的使用... 26

2.2、庫的添加... 27

2.2.1、只對本項目起作用的庫的添加... 27

2.2.2、公共庫的添加(測試沒通過)... 30

2.3、靜態編譯與動態編譯(靜態編譯沒實踐檢驗)... 31

3、靜態庫和動態庫... 31

3.1、靜態庫的創建和使用... 32

3.1.1、靜態庫的創建... 32

3.1.2、靜態庫的使用... 36

3.2、動態庫的創建和使用... 39

3.2.1、動態庫的創建... 39

3.2.2、動態庫的使用... 41

3.3、小結... 43

4、Qt程序的跨平臺移植... 44

4.1、Qt的跨平臺... 44

4.2、移植方法... 44

4.3、移植時應注意的問題... 44

5、版本不兼容常見問題... 45

三、Qt界面庫基本的開發過程,基本的控件... 45

1、      helloworld例子... 46

2、可視化編程介紹... 52

3、常用控件的常見接口... 54

1.1、Layouts和spacers. 54

1.2、label ----靜態文本框... 55

1.3、PushButton----按鈕... 55

1.4、CheckBox----複選框... 56

1.5、listWidget----列表... 56

1.6、tableWidget----表格... 57

1.7、treeWidget----樹... 57

1.8、progressBar----進度條... 58

1.9、comboBox----組合下拉框... 59

1.10 QmessageBox----消息提示盒... 59

1.11 QFileDialog----文件選擇框... 61

1.12 QSystemTrayIcon----托盤類... 63

1.13 QThread----線程類... 63

1.14 線程和信號-槽用法舉例... 64

四、QtWebkit的使用... 65

 

 

一、Qt基本情況的介紹

1、歷史

HaavardNord和Eirik Chambe-Eng於1991年開始開發"Qt",1994年3月4日創立公司,最早名爲Quasar Technologies,然後更名爲Troll Tech,然後再改爲Trolltech,中文名是“奇趣科技”,2008年6月17日被NOKIA公司收購,以增強該公司在跨平臺軟件研發方面的實力,更名Qt Software。

該工具包名爲Qt是因爲字母Q在Haavard的Emacs字體特別漂亮,而“t”代表“toolkit”,靈感來自Xt,X toolkit。

2009年5月11日,諾基亞Qt Software宣佈Qt源代碼管理系統面向公衆開放,Qt開發人員可通過爲Qt以及與 Qt相關的項目貢獻代碼、翻譯、示例以及其他內容,協助引導和塑造Qt未來的發展。爲了便於這些內容的管理,Qt Software啓用了基於Git和Gitorious開源項目的Web源代碼管理系統。

在推出開放式Qt代碼庫的同時,Qt Software在其網站發佈了其產品規劃(Roadmap)。其中概述了研發項目中的最新功能,展現了現階段對Qt 未來發展方向的觀點,以期鼓勵社區提供反饋和貢獻代碼,共同引導和塑造Qt的未來。 2012年8月9日,Digia宣佈已完成對諾基亞Qt業務及軟件技術的全面收購,並計劃將Qt應用到Android、iOS及Windows 8平臺上。

2、基本介紹

平臺的C++應用程序開發框架。廣泛用於開發GUI程序,這種情況下又被稱爲部件工具箱。也可用於開發非GUI程序,比如控制檯工具和服務器。Qt使用於OPIE、Skype、VLC mediaplayer、Adobe Photoshop Elements、VirtualBox 與 Mathematica以及被Autodesk、歐洲空間局、夢工廠、Google、HP、KDE、盧卡斯影業、西門子公司、富豪集團, 華特迪士尼動畫製作公司、三星集團、飛利浦、Panasonic所使用。

它是諾基亞(Nokia)的Qt Development Frameworks部門的產品。Qt使用標準的C++。通過語言綁定,其他的編程語言也可以使用Qt。

Qt是自由且開放源代碼的軟件,在GNU較寬鬆公共許可證條款下發布。所有版本都支持廣泛的編譯器,包括GCC的C++編譯器和Visual Studio。

 

維基百科:http://zh.wikipedia.org/zh-cn/Qt

淺析 Qt 界面庫:http://mobile.51cto.com/symbian-270393.htm

Qt官網:http://qt.digia.com/

http://download.qt-project.org/archive/

Qt 項目:http://qt-project.org

Qt開發者社區:http://qt.csdn.net/

二、Qt開發準備

本部分是基於Qt5.0,1進行研究的,期間會偶有提及Qt5.0.2的一些功能更新。

1、Qt的開發環境及搭建

1.1、開發環境

 (1)各平臺常用開發環境

1、windows: QtLibrary + Qt Creator

QtLibrary + VS200X(X = 5,8,10…)

2、linux:  Qt Library + Qt Creator

3、mac:    Qt Library + Qt Creator

 

(2) Qt Library是一個Qt庫,包含編譯器,各種鏈接庫。

(3) Qt Creator 是一款跨平臺的集成開發環境(Qt IDE),特別針對Qt開發者,是Qt SDK組成的一部分,可運行於Windows, Linux/X11 and Mac OS X等桌面操作系統,允許開發者爲多桌面環境及移動設備平臺創建應用程序。它包括一個可視化偵錯工具和整合的 GUI 版面和外形設計師。這個編輯器的功能包括語法高亮度顯示和自動完成。Qt Creator 在 Linux 上,使用 GCC 的 C++ 編譯器。在 Windows,默認安裝它可以使用 MinGW 或 MSVC。從源代碼編譯時,也可以使用 cdb。

 

Qt Library + VS200X對VS老用戶用起來更順手,Qt Library + Qt Creator更適合跨平臺開發,因爲Qt Creator就是一個跨平臺的開發工具。

 

1.2、Qt Library + QtCreator

1.2.1、安裝包

(1)常用系統對應的安裝包

集成包:(QtLibrary + Qt Creator)

·        Linux 32-bit:Qt 5.0.1 for Linux 32-bit (388 MB)   

·        Linux 64-bit:Qt 5.0.1 for Linux 64-bit (388 MB)

·        Mac 64-bit: Qt 5.0.1 for Mac (398 MB)

·        Mac 32-bit: Mac OS X 10.0以後的系統均爲64bit的,Qt 5.0.1沒有32bit

·        Win32:Qt 5.0.1 for Windows 32-bit (MinGW 4.7,823 MB)

·        Win32:Qt 5.0.1 for Windows 32-bit (VS 2010, 481MB)

Win64:5.0.2開始發佈64bit版本Qt 5.0.2 for Windows 64-bit (VS 2012, 500 MB)

 

以上是時至2013年4月2日最新的Qt安裝包,想了解最新安裝包信息請到http://qt-project.org/downloads 查看。

4月11日發佈了5.0.2版本,增加了兩個安裝包:

·        Qt5.0.2 for Windows 32-bit (VS 2010, OpenGL, 476 MB) 

·        Qt5.0.2 for Windows 64-bit (VS 2012, 500 MB) 

 

(2)關於安裝包的說明

1、選包建議

建議多少位的系統就安裝多少位的安裝包,要開發多少位的程序就在多少位的系統上開發,這也有利於程序的調試。Qt Creator的宗旨就是方便跨平臺和跨系統,所以程序從32位遷移到64位也應當不會很複雜,大概是源代碼的重新編譯吧。(詳細報告見《Qt安裝及編譯測試錯誤報告4_12.docx》)

2、win32下MinGW包和Msvc包的區別

MinGW(Minimalist GNU for Windows),又稱mingw32,是將GCC編譯器和GNUBinutils移植到Win32平臺下的產物,包括一系列頭文件(Win32API)、庫和可執行文件。另有mingw64系列工具,是用於產生64位Windows可執行文件的GNU交叉編譯器。對於C語言之外的語言,MinGW使用標準的GNU運行庫,如C++使用GNU libstdc++。但是MinGW使用Windows中的C運行庫。因此用MinGW開發的程序不需要額外的第三方DLL支持就可以直接在Windows下運行,而且也不一定必須遵從GPL許可證。這同時造成了MinGW開發的程序只能使用Win32API和跨平臺的第三方庫,而缺少POSIX支持,大多數GNU軟件無法在不修改源代碼的情況下用MinGW編譯。

Msvc:Microsoft Visual C++的簡稱。

MinGW安裝包自帶MinGW 32bit編譯器,對系統的依賴程度較低;Msvc包不帶編譯器,使用的是MSVC編譯器,要求系統安裝VS2010或以上版本,安裝包較小。所以這兩個安裝包使用的編譯器是不一樣的,也可能導致語法等存在一定的差異,暫無優劣之分,看個人情況而定。

1.2.2、安裝

(1)安裝步驟

1、運行安裝包。直接雙擊安裝包即可,在linux下雙擊安裝包有時可能沒響應,那是因爲安裝包沒運行權限,可以通過下面的方法獲取運行權限:

在終端輸入以下命令:(假設安裝包在桌面,XXX爲安裝包名稱)

cd Desktop       //進入文件目錄

chmod +x XXX.run    //修改權限,chmod是加權限命令,+ 表示增加權限,x 表示可執行

2、在彈出的安裝引導中選擇“next”,選擇安裝路徑後選“next”。

3、在“組件選擇”中可以選擇性安裝你需要的組件,選中組件時右邊會有說明,默認選項可以滿足正常開發需求,但爲了不時之需,可以全選。選好後點擊“next”。

4、在“許可協議”中主要說明一些協議,同意後選“next”,在新界面中選擇創建快捷鍵的位置,然後一直選“next”,直到完成。

 

(2)Qt Creator各包安裝情況:

32bit安裝裝包

64bit安裝包

VS200X插件

 

MinGW

MSVC

 

 

windows32

安裝成功

安裝成功

 新發布沒嘗試

安裝成功

windows64

暫無條件測試

暫無條件測試

暫無條件測試

暫無條件測試

linux32

安裝成功

沒嘗試

linux64

不成功

安裝成功

mac

安裝成功

1.2.3、配置

在一般情況下,Qt Creator會按默認配置好,但有時可能需要我們做一些手動配置,下面講解一下幾個常見配置(各平臺上Qt Creator的界面及用法是一樣的,此處以Qt Creator2.6.2(win32中文版)爲例進行說明):

(1)“Qt 版本”與“編譯器”的配置

兩者的添加方法基本相同,不同的是“Qt版本”添加的是“qmake.exe”的路徑,“編譯器”添加的是編譯器(gcc.exe,vcvarsall)路徑。下面以添加“編譯器”爲例:

1、在頂部菜單欄選擇“工具”->“選項”:

 

2、選擇“構建和運行”->“編譯器”,在右邊的“添加”中選擇要添加的編譯器類型;

3、通過編譯器路徑後面的“瀏覽”按鈕,找到“編譯器文件(如gcc.exe)”,打開;

4、在“手動設置”下面會看到新增的編譯器名稱(可自己命名),在編譯器路徑裏可以看到新增的編譯器所在路徑,點擊“應用”完成添加。

 

(2)調試器的配置

在linux和mac上,Qt Creator可以自動檢測到合適的調試器(應該是安裝包綁定的),但在windows上,Qt Creator默認是不適用調試器的,需要手動配置,而且mingw與msvc的調試器也似乎是不匹配的(測試結果:msvc用mingw調試器時斷點處沒停也查看不到值的變化; mingw用msvc調試器時運行得很慢很慢很慢),手動配置如下:

1、mingw-32bit

a、在調試器後面的“管理”選擇“編輯”

 

b、選擇“GDB”,點擊“瀏覽”

 

C、找到“gdb.exe”,文件路徑爲“…\MinQt5.0.1\Tools\MinGW\bin”

 

d、“確定”->“應用”。

 

2、msvc-32bit

a、  自身不帶有調試器,需要到網上下載:(windbg)

http://download.microsoft.com/download/A/6/A/A6AC035D-DA3F-4F0C-ADA4-37C8E5D34E3D/setup/WinSDKDebuggingTools/dbg_x86.msi 

 

b、  安裝“WinDbg”後,點擊“管理”->“自動檢測”即可,如無法檢測到,也可按mingw的步驟手動添加。

 

(3)“構建套件(Kit)”的配置

1、在頂部菜單欄選擇“工具”->“選項”:

 

2、選擇“構建和運行”->“構建套件(Kit)”,Qt Creator會自動檢測到安裝包自帶的默認套件

3、可以通過右邊的“添加”來創建自己想要的Kit。在“名稱”項命名,命名沒特殊要求,最好能體現該“kit”的屬性;在“編譯器”和“Qt版本”中選擇自己需要的選項;在“設備類型”選擇程序運行的設備,電腦上一般默認“桌面”。不匹配時會有或 錯誤提醒和警告,添加的“kit”會在“手動設置”顯示。可以通過“設爲默認”把其中某個“kit”設爲默認,設爲默認後,在打開工程和修改工程“kit”時會自動勾選。

 

4、新建項目時,根據需要選擇相應的“Kit”,默認情況下爲全選。

 

5、查看工程使用的“Kit”。把鼠標移至或點擊界面左下角的電腦圖標

 

6、修改項目的“Kit”。

A、點擊左側菜單中的“項目”,選擇“構建和運行”,點擊“-”減號刪除當前“Kit”:

 

B、在彈出的窗口下選擇新“kit”,點擊“配置項目”即可。

1.2.4、新建項目

(1)點擊“create Project”

 

(2)選擇項目及應用類型

 

(3)項目命名,指定創建路徑,注意路徑不要出現中文

 

(4)選擇構建套件,可根據需要勾選,默認爲全選

 

(5)選擇基類類型,“下一步”->“完成”

QT中QWidget、QDialog及QMainWindow的區別(來源:http://www.cnblogs.com/aqxin/archive/2011/05/23/2054156.html

QWidget類是所有用戶界面對象的基類。 窗口部件是用戶界面的一個基本單元:它從窗口系統接收鼠標、鍵盤和其它事件,並且在屏幕上繪製自己。每一個窗口部件都是矩形的,並且它們按Z軸順序排列。一個窗口部件可以被它的父窗口部件或者它前面的窗口部件蓋住一部分。

   QMainWindow 類提供一個有菜單條、錨接窗口(例如工具條)和一個狀態條的主應用程序窗口。主窗口通常用在提供一個大的中央窗口部件(例如文本編輯或者繪製畫布)以及周圍菜單、工具條和一個狀態條。QMainWindow常常被繼承,因爲這使得封裝中央部件、菜單和工具條以及窗口狀態條變得更容易,當用戶點擊菜單項或者工具條按鈕時,槽會被調用。

   QDialog類是對話框窗口的基類。對話框窗口是主要用於短期任務以及和用戶進行簡要通訊的頂級窗口。QDialog可以是模態對話框也可以是非模態對話框。QDialog支持擴展性並且可以提供返回值。它們可以有默認按鈕。QDialog也可以有一個QSizeGrip在它的右下角,使用setSizeGripEnabled()。

   QDialog 是最普通的頂級窗口。一個不會被嵌入到父窗口部件的窗口部件叫做頂級窗口部件。通常情況下,頂級窗口部件是有框架和標題欄的窗口(儘管使用了一定的窗口部件標記,創建頂級窗口部件時也可能沒有這些裝飾。)在Qt中,QMainWindow和不同的QDialog的子類是最普通的頂級窗口。

    如果是頂級對話框,那就基於QDialog創建,如果是主窗體,那就基於QMainWindow,如果不確定,或者有可能作爲頂級窗體,或有可能嵌入到其他窗體中,則基於QWidget創建。

    當然了,實際中,你還可以基於任何其他部件類來派生。看實際需求了,比如QFrame、QStackedWidget等等。

 

(6)點擊“錘子”圖標編譯,點擊“綠色箭頭”運行

1.2.5、編譯測試

(1)選擇默認“kit”編譯(編譯器、Qt版本的位數與系統位數相同)

1、mac和windows上,編譯通過,程序運行正常;

2、linux下初次編譯可能會報錯:cannot find –lGL;

解決辦法:在終端輸入sudo apt-getinstall libgl1-mesa-dev下載相應的文件。

(2)同一系統下是否同時支持編譯32bit和64bit的程序

經測試,初步得出結論:32bit系統下不支持編譯64bit程序;mac-64bit系統下可以編譯32bit程序;linux-64bit系統下編譯不了32bit程序,猜測是系統缺少32位庫文件。(詳細情況請查看《Qt安裝及編譯測試錯誤報告》):

1.3、VS+Qt插件(還有問題沒解決

1.3.1、安裝包

插件包:Qt Library + VS200X(X = 5,8,10…本文以VS2010爲例進行說明)

Qt Library在官網上沒有Qt5SDK單獨的包,均捆包在Qt Creator集成包裏,可通過安裝Qt Creator集成包獲取。

·        Visual Studio Add-in 1.2.0 for Qt5  (VS插件)

 

1.3.2、安裝

(1)安裝步驟

1、安裝VS2005或以上版本。安裝比較簡單,基本是“安裝”->“完成”的自動模式。

2、安裝Qt的SDK。雙擊即可安裝,官網上暫無發現單獨的Qt5 SDK,都集成到了Qt Creator安裝包裏面了,可以通過安裝Qt Creator安裝包獲取其SDK(但需手動設置路徑,下面會說)。

3、安裝Visual Studio Add-in。雙擊即可安裝,安裝完成後,VS菜單上會多出一個“Qt”選項。

 

參考網址:

http://www.cnblogs.com/qq78292959/archive/2012/05/03/2481971.html

1.3.3、配置

(1)配置步驟

1、啓動VS,點擊“Qt”->“Options”進行路徑設置。

 

2、VS可以自動檢測到並添加單獨安裝的Qt SDK路徑,如下所示:

 

3、但使用集成到QtCreator的SDK則需要手動添加路徑,如下所示:

 

4、找到bin路徑,“確定”->“ok”:

 

5、路徑設置不正確時,有紅字提醒並且“ok”按鈕無效:

 

6、點擊“OK”完成設置。

 

(2)配置問題導致的常見錯誤

         1、Visual Studio Add-in與Qt SDK版本要匹配,不能添加比自身對應版本高的SDK。否則會報錯:

1.3.4、新建項目

(1)“文件”->“新建”->“項目”

 

(2)選擇項目種類,命名項目並指定路徑

 

(3)在彈出的界面中直接點擊“下一步”,選擇需要的模塊

 

(4)設置基類等,完成

(5)生成解決方案,啓動

1.3.5、編譯測試(編譯沒通過,可能配置不正確

1win32編譯,報錯:

1>------ 已啓動生成: 項目: VSQt5, 配置: Debug Win32 ------

1>Rcc'ing vsqt5.qrc...

1>RCC Parse Error: 'd:\Qt+Creator\VSQt5\VSQt5\vsqt5.qrc'Line: 1 Column: 1 [Encountered incorrectly encoded content.]

1>Project : error PRJ0019: 某個工具從以下位置返回了錯誤代碼: "Rcc'ingvsqt5.qrc..."

1>生成日誌保存在file://D:\Qt+Creator\VSQt5\Win32\Debug\BuildLog.htm

1>VSQt5 - 1 個錯誤,個警告

========== 生成: 成功0 個,失敗1 個,最新0 個,跳過0 個==========

 

解決辦法:尚未解決,根據報錯是在RCC解析vsqt5.qrc文件時,遇到不正確的編碼內容。對此做了進一步測試:

 

1VS.qrc文件的項目測試

Qt Console ApplicationQt5)項目,源碼,文件,結果如下:

編譯通過,運行正常,所以驗證了的確跟.qrc文件有關。

 

2、在VSQt Creator裏建同樣的工程,嘗試通過對比.qrc文件發現錯誤的編碼內容,但Qt Creator建的項目沒有.qrc文件

A、有.qrc文件的項目測試:

Qt ApplicationQt5)項目,其中基類爲:QMainWindow;源碼,文件,結果如下:

 

曾懷疑跟下面文件的紅色提示有關,但網上的例子也是一樣的截圖。

 

B、 建同樣的工程,Qt Creator目錄沒有.qrc文件

3、網上下載別人VS開發的Qt程序源碼,看看重新編譯後是否能通過,對比.qrc文件是否不一樣。(該部分暫時還沒做)

2x64b編譯,報錯:

 

原因猜測:沒有64位的庫文件和連接器等,插件不支持64位編譯。

 

1.4、小結

         在Qt Creator上的搭建是成功的,在VS上插件的安裝配置遇到了問題,但可以知道的是VS上用目前的32bit的SDK也同樣無法編譯64位程序的,而且VS僅限於windows系統。綜上,我們可以選擇Qt Creator進行Qt的開發。

 

2、系統庫的使用及程序發佈

2.1、系統API的使用

可以通過包含相應頭文件來直接使用API函數,如:

此外,外部的文件通過“添加現有文件”,再#include即可使用,跟在MFC上使用沒多大區別。

 

2.2、庫的添加

2.2.1、只對本項目起作用的庫的添加

Qt Creator可以把庫添加到具體項目的屬性,添加後只對本項目起作用,不影響其他項目,下面以Qt Creator-msvc添加“外部庫”爲例講解如何添加庫文件:

(1)右鍵要添加庫的目標項目->“添加庫”

 

(2)選擇要添加庫的類型,此處會有各類型庫的說明

 

(3)勾選對應的“平臺”和“鏈接”,通過“瀏覽”獲取“庫文件”路徑以及“包含文件”路徑,注意的是選“庫文件”時自動添加的“包含路徑”不一定是正確的,應填寫該庫頭文件的實際路徑。

值得注意的是:在windows下以這種方式導入的庫文件必須是.lib後綴,因爲在文件選擇對話框裏已經把文件類型限制爲(*.lib),而QtCreator-mingw生成的靜態庫是.a後綴的。

 

(4)在完成前會有彙總顯示

 

(5)在導入完成後,會根據彙總做相應的修改,一般爲在.pro添加相應的路徑信息,此時可以通過#include相應的頭文件來使用庫函數

2.2.2、公共庫的添加(測試沒通過

參考網址:http://qt.csdn.net/articles.aspx?pointid=264&pointid2=

點擊主界面左邊菜單的“項目”->“構建和運行”,打開下方的“構建環境”->“詳情”,可以看到QtCreator對環境變量的使用情況:

從紅色框裏的INCLUDE,LIB和LIBPATH,我們可以看出,Qt Creator是通過這三個環境變量的路徑找到相應的系統庫文件的,所以理論上我們可以通過在這三個環境變量裏添加相應的文件路徑來達到添加“公共庫”的目的。但在嘗試中發現,如果在這裏修改這三個環境變量,新增的路徑只對本項目有用,並不影響到其他項目。要實現真正意義上的“公共庫”,需要到“我的電腦”->“屬性”裏修改這三個環境變量。

在實際操作中遇到下面的問題沒解決:

設置環境變量後,包含頭文件,使用Lib裏面的函數時報錯:

2.3、靜態編譯與動態編譯(靜態編譯沒實踐檢驗

QtCreator開發的程序可以通過以下兩種方法發佈到沒Qt庫的電腦:

1、靜態編譯

可參考:

http://blog.csdn.net/c154387417/article/details/6330245

官網發佈的安裝包在默認情況下是動態編譯的,而且沒有靜態編譯所需的Qt庫,據網上所說要靜態編譯需先自己編譯出靜態編譯所需的Qt庫,然後在project.pro添加QMAKE_LFLAGS=-static指定爲靜態編譯即可。由於編譯所需時間太長(據說好幾小時),暫時尚未嘗試。

2、複製運行時提示缺少的dll文件到當前目錄,可參考:(win32下測試通過)

http://hi.baidu.com/dbzhang800/item/5c92691dc965017a7a5f2542

有一個dll(debug模式下爲:libEGLd.dll;release模式下位:libEGL.dll)需特別注意的,缺少時並不會提示,debug編譯的exe運行時直接報錯:

release編譯的exe缺少時點擊沒反應。

 

3、靜態庫和動態庫

參考: QT 靜態庫和動態庫http://mobile.51cto.com/symbian-267846.htm

在各平臺上用Qt Creator創建、使用Qt靜態庫和動態庫的方法是一樣的,這裏選擇Qt 5.0.1for Windows 32-bit (MinGW 4.7) 測試。

3.1、靜態庫的創建和使用

3.1.1、靜態庫的創建

(1)新建項目,選擇“庫”->“C++庫”

 

(2)選擇庫的類型爲“靜態鏈接庫”,命名項目名稱,這裏命名爲“staticlib”

 

(3)選擇構建套件

 

(4)選擇模塊

 

(5)類信息一般不用修改,直接“下一步”->“完成”

 

(6)項目的文件架構如下

 

(7)添加測試代碼

1、.h頭文件添加函數聲明:voidtest();

 

2、.cpp文件添加函數體

 

3、.pro文件添加:QT+=widgets;這主要是因爲Qt5用widgets組件代替了QtGui,而在創建庫項目過程中的模塊選擇時並沒有Q widgets選項,所以要使用界面組件時只能通過勾選QtGui並在.pro文件中加上QT+=widgets來達到使用目的;Qt5.0.2已解決這個問題,在創建庫時已經有Q widgets選項,但如果你勾選的依然是QtGui,在.pro文件中除了要加上QT+=widgets外,還要加上QT-=gui。

 

另外,在已經構建好(即已編譯生成Makefile)的項目裏,手動修改.pro文件後要點擊“構建”->“執行make”,否則,儘管是“重新構建項目”,所做的修改還是不起作用的。

 

(8)編譯

 

3.1.2、靜態庫的使用

(1)新建測試工程

 

(2)命名項目,指定工程路徑,這裏命名爲“staticlibtest”

 

(3)選擇構建套件

 

(4)選擇“基類”,“下一步”->“完成”

 

(5)工程文件結構

 

(6)在.pro添加靜態庫路徑,其中“INCLUDEPATH +=”用於指定頭文件路徑,“LIBS +=”用於指定庫文件路徑

 

(7)在main.cpp調用靜態庫函數

(8)編譯運行,其中“靜態庫測試”爲調用靜態庫生成的

3.2、動態庫的創建和使用

3.2.1、動態庫的創建

(1)動態庫的創建方法與靜態庫創建相同,只是在第二步時選擇“庫的類型”時選擇“共享庫”,這裏命名爲“libdll”

 

(2)頭文件結構,比靜態庫多了一個“libdll_global.h”頭文件

 

(3)添加測試代碼

1、.pro文件添加:QT  +=  widgets

 

2、libdll.h添加函數聲明:voidtest();

 

3、.cpp文件添加函數體

 

(4)編譯

3.2.2、動態庫的使用

(1)新建測試項目的方法與靜態庫測試項目的新建一樣,這裏命名爲“libdlltest”

(2)把.dll文件拷貝到執行文件的目錄

 

(3)在.pro文件添加路徑

 

(4)在main.cpp裏調用.dll裏的函數

 

(5)編譯,運行;下面的“這是動態庫測試”是由.dll生成的。

 

3.3、小結

在各平臺上用Qt Creator創建、使用Qt靜態庫和動態庫的方法是差不多是一樣的,只是生成的庫文件後綴不一樣而已,除了以上方法使用庫文件外,還可以通過添加“外部庫”的方法添加到目標項目裏使用;但是在windows下,導入的庫文件格式限定爲(*lib),而Qt Creator-mingw生成的是.a後綴的靜態庫文件,不能以此方法,同樣也不能用此方法添加動態庫。其實這裏通過寫代碼使用庫文件的使用方法跟MFC庫的“隱式調用”是類似的,而上面的“添加庫”通過設置使用庫文件則可以類比爲MFC裏庫的“顯式調用”。另外,創建和使用過程中還應注意以下兩點:

 

(1)在linux下編譯庫文件時,系統時間不正確時會出現以下類型的錯誤:error: Warning: File `../LIB/LIB.pro' has modification time 4e+05 sin…,改正系統時間即可。

(2)使用庫時應特別注意INCLUDEPATH +=和LIBS +=的正確寫法,尤其是在跨平臺移植時,應注意路徑格式的轉變,很多notfound錯誤都是由於這兩個路徑不正確引起的。

 

4、Qt程序的跨平臺移植

4.1、Qt的跨平臺

Qt的可移植性,指的是代碼不用修改,就可以在多個平臺編譯通過並運行。針對每一種OS平臺,Qt都有一套對應的底層類庫,而接口是完全一致的。因此只要是在Qt庫上開發的程序,放在任何一種所支持的平臺下都可以編譯運行(前提條件是:程序中沒有使用某OS特有的機能)。也就是說在OS和應用層之間,增加了一個平臺層來保證可移植性。

4.2、移植方法

1、源代碼裏只使用Qt庫,沒有與平臺相關的代碼時,一般只需在目標平臺的Qt(版本要一樣,新版本對上一版本不完全兼容)上重新編譯即可,但要注意源碼裏是否包含絕對路徑,Qt的跨平臺性是一次編寫多次編譯,不同於java的一次編譯多次執行。

2、如果程序中使用某些平臺相關的庫函數,那麼在移植時就需要針對不同平臺作一些改動。

364位下開發的QT程序, 在32位電腦上重新編譯一下就可以在32位機上運行了, 前提是不要用到64位下才支持的函數和功能,但要注意某些數據類型所佔字節數的不同。

4.3、移植時應注意的問題


1、字符的編碼問題。Windows下是ANCII編碼的,Linux下是Unicode編碼的,源程序注意轉化編碼。關於編碼的設置可參考:
windows下默認是GBK的編碼格式,如果想使用UTF8就要先修改Qt Creator的編碼格式,方法如下
Tools->Options->Environment->General->Default file encoding
修改好UTF8格式之後,再創建工程,就可以顯示UTF8格式的漢字了

代碼如下:

QTextCodec::setCodecForLocale(QTextCodec::codecForName("UTF8"));
QTextCodec::setCodecForCStrings(QTextCodec::codecForName("UTF8"));
QTextCodec::setCodecForTr(QTextCodec::codecForName("UTF8"));
qDebug()<<"不怕神一樣的對手,就怕豬一樣的隊友";

或者使用這樣輸出

QTextCodec* codec = QTextCodec::codecForName("UTF8")
QString str = codec->toUnicode("不怕神一樣的對手,就怕豬一樣的隊友");
qDebug()<<str;
來自網站:http://zhidao.baidu.com/question/186780737.html 
2、Linux下的文件名連後綴都是區分大小寫的,所以一些涉及到文件讀寫的程序,後綴名也要注意一下。另外,在包含動態庫或靜態庫的程序在移植到另一個平臺時,相應的庫文件也要注意後綴,不同時應當重新編譯。

3、儘量不要在程序裏寫絕對路徑,要用相對路徑;路徑不要含中文,注意‘/’和‘\’的轉換。

 

5、版本不兼容常見問題

在初學Qt,我們難免要參考網上例子,但網上的例子大多是在Qt4上開發的,所以會出現一些不兼容的問題。

(1)、QtGui模塊的問題。用Qt5編譯Qt4的工程出現最多的就是下面類型的問題:
   
錯誤:C1083: 無法打開包括文件:“QApplication”: No such file or directory
   
錯誤:C1083: 無法打開包括文件:“QMainWindow”: No such file or directory
   
出現原因:Qt5裏不再用QtGui模塊,而是使用QtWidgets模塊。

解決方法:在.pro里加上QT += widgets

(2)其他常見問題集錦:

http://hi.baidu.com/xchinux/item/9044d8ce986accbb0d0a7b87

 

三、Qt界面庫基本的開發過程,基本的控件

本部分是基於Qt5.0.1 + Qt Creator2.6.2進行開發的,目前還沒發現網上有Qt5的教程,鑑於與Qt4的使用大同小異,所以可以參考Qt4教程,推薦教程如下:

QtCreator教程:

《qt+creator系列教程》或《Qt_CreatoR_入門》,這兩本書內容基本一樣:http://wenku.baidu.com/view/eac2b64133687e21af45a996.html

文檔集: http://www.open-open.com/doc/list/185

 

《C++ GUI Qt4 編程》或《精通QT4編程》,這兩本書內容基本一樣:

http://ishare.iask.sina.com.cn/f/9045395.html

 

Qt各控件詳細說明:

http://wenku.baidu.com/view/d64a7863af1ffc4ffe47ac7f.html

1、helloworld例子

(1)      啓動Qt Creator,點擊“Create Project”創建新項目;

 

(2)      指定項目名

 

(3)      選擇構建套件,一般默認即可;

 

(4)      指定基類

 

(5)      直接點擊“完成”;

(6)      點擊“mainwindow.ui”文件,進入“設計器”;

(7)      從控件庫拉一個靜態文本框“Label”到主界面;

(8)      右擊控件->“改變普通文本”,寫入“helloworld”;也可以在“屬性欄”編輯;

(9)      保存,編譯;

(10)  運行;

(11)  效果如下:

 

進一步修改:(信號-槽的使用)

1往主界面添加一個按鈕“pushButton”;

2點擊“信號槽編輯器”->綠色“+”,新建信號-槽;(此方法適合綁定控件自帶的信號和槽)

 

3右擊“pushButton”按鈕,在彈出的菜單選擇“轉到槽”,在彈出的窗口選擇clicked信號;

 

4在轉到的槽函數裏編輯自定義槽函數

voidMainWindow::on_pushButton_clicked()

{

    ui->label->setText("signal-slot!");

}

 

5保存,編輯,運行。

點擊按鈕前:

點擊按鈕後:

 

在修改後的程序裏主要演示了兩種使用信號-槽的方法,另外還可以用connect(*p, SIGNAL(f()), this, SLOT(f1()));使用信號槽,在後面會講到,此處暫不演示。

2、可視化編程介紹

Qt Gui初始界面我們可以在“設計模式”使用可視化編程來設計界面,這樣比寫代碼更簡單快捷。

(1)      雙擊“界面文件”下的.ui文件轉到“設計模式”

 

(2)      從控件庫往主界面拉控件構造自己界面,選中控件可以在屬性欄編輯控件屬性;

 

 

(3)      在行爲編輯器裏可以爲控件添加行爲和“信號-槽”

 

3、常用控件的常見接口

本部分只簡單列舉常用的函數、信號和槽,詳細的介紹可以查看幫助文檔。

1.1、Layouts和spacers

兩者都主要是在佈局中用到,通過各種嵌套可以構造出複雜的界面佈局,一般不會用到接口。

1.2、label ----靜態文本框

1、常用函數

QString     selectedText() const           //選中的內容

void  setSelection(int start, int length)   //設置選中

void  setTextFormat(Qt::TextFormat)   //設置字體格式

QString     text() const               //獲取控件文本

2、常用信號

void    linkActivated(constQString & link)       //點擊鏈接

void    linkHovered(constQString & link)     //鼠標移到鏈接

要使label能發送這兩個信號,必須先設置超鏈接,設置示例如下:

QLabel*openfilelabel=newQLabel(this);

openfilelabel->setOpenExternalLinks(true);/*這句很關鍵啊,否則就只能通過linkActivated信號,連接到自定義槽函數中打開了*/

openfilelabel->setText(tr("<ahref=\"http://www.csdn.net/\">打開CSDN"));

openfilelabel.show();

3、常用槽

void    clear()                                 //清空

void    setPicture(const QPicture &picture)   //顯示圖片

void    setText(const QString &)              //設置顯示文字

1.3、PushButton----按鈕

1、常用函數

QPushButton(QWidget* parent = 0)                        //構造函數

QPushButton(constQString & text, QWidget * parent = 0)     

QPushButton(constQIcon & icon, const QString & text, QWidget * parent = 0)    

void QButton::setText ( const QString &)     // 設置這個按鈕上顯示的文本

QString  text() const //返回這個按鈕上顯示的文本

2、常用信號

Clicked()  //被點擊

3、常用槽

setEnabled(bool)   //設置按鈕有效

setDisabled(bool) //設置按鈕失效

 

1.4、CheckBox----複選框

1、常用函數

Bool isChecked() const                        //檢查是否被勾選

2、常用信號

stateChanged(int)  //狀態改變

3、常用槽

setChecked(bool)             //設置選中狀態

setEnabled(bool)   //設置按鈕有效

setDisabled(bool) //設置按鈕失效

1.5、listWidget----列表

1、常用函數

void addItem(constQString & label)                                //加入項(參數爲字符串)

void addItem(QListWidgetItem* item)                         //加入項(參數爲字符串)

void addItems(constQStringList & labels)                       //加入多項(參數爲列表)

void  insertItem(int row, QListWidgetItem *item)    //插入項

void  insertItem(int row, const QString &label)

void  insertItems(int row, const QStringList& labels)

QListWidgetItem *  currentItem() const                                     //獲取當前項

void  removeItemWidget(QListWidgetItem *item)       //刪除項,但在實際應用中調用該函數後,並沒有刪除項,需要再調用delete才能刪除,其實直接調用delete也可以刪除,但不知道會不會有什麼不良後果。使用舉例如下:

listWidget->removeItemWidget(listWidget->currentItem());

delete listWidget->currentItem();

參考網址:http://sweetdum.com/wordpress/?p=290

2、常用信號

void  currentItemChanged(QListWidgetItem *current, QListWidgetItem * previous)

void  currentRowChanged(int currentRow)

void  currentTextChanged(const QString &currentText)

void  itemChanged(QListWidgetItem * item)

void  itemClicked(QListWidgetItem * item)

void  itemDoubleClicked(QListWidgetItem *item)

void  itemSelectionChanged()

3、常用槽

Clear()                                 //清空

ScrollToItem(QListWidgetItem * item)            //轉到項,可用於查找

 

1.6、tableWidget----表格

推薦網址:http://music.573114.com/Blog/Html/6016/203347.html

1、常用函數

QTableWidget(int rows, int columns, QWidget * parent = 0)                  //構造表格

void  setColumnCount(int columns)                                                           //設置表格列數

void  setRowCount(int rows)                                                                             //設置表格行數

void  setHorizontalHeaderItem(int column,QTableWidgetItem * item)       //設置列名

void  setHorizontalHeaderLabels(constQStringList & labels)                          //設置表頭

void  setItem(int row, int column,QTableWidgetItem * item)                           //設置單元表格內容

2、常用信號

//此處cell和item是差不多的,只是cell用行和列定位,item用指針定位。

void  cellChanged(int row, int column)

void  cellClicked(int row, int column)

void  cellDoubleClicked(int row, int column)           

void  currentCellChanged(int currentRow, intcurrentColumn, int previousRow, int previousColumn)

void  currentItemChanged(QTableWidgetItem *current, QTableWidgetItem * previous)

void  itemChanged(QTableWidgetItem * item)

void  itemClicked(QTableWidgetItem * item)

void  itemDoubleClicked(QTableWidgetItem *item)

void  itemSelectionChanged()

3、常用槽

void  clear()                                            //清空表格

void  clearContents()                          //清空表格內容

void  insertColumn(int column)       //插入列

void  insertRow(int row)                    //插入行

void  removeColumn(int column)    //刪除列

void  removeRow(int row)                //刪除行

void  scrollToItem( const QTableWidgetItem * item, QAbstractItemView::ScrollHint hint =EnsureVisible )                  //滾動到項,常用於查找

setSortingEnabled(true);                                // 設置點擊表頭自動排序

setSelectionBehavior(QAbstractItemView::SelectRows);          //整行選中的方式

setEditTriggers(QAbstractItemView::NoEditTriggers);                    //設置單元表格不可編輯

1.7、treeWidget----樹

1、常用函數

void  addTopLevelItem(QTreeWidgetItem * item)                                               //插入一個頂級項

void  addTopLevelItems(constQList<QTreeWidgetItem *> & items)    //插入多個頂級項

QTreeWidgetItem *         currentItem() const                                                                 //獲取當項

void  setHeaderLabel(const QString &label)                                                //加入樹的屬性列名

void  setHeaderLabels(const QStringList &labels)                                               //加入樹的多個屬性列名

2、常用信號

void  currentItemChanged(QTreeWidgetItem *current, QTreeWidgetItem * previous)

void  itemChanged(QTreeWidgetItem * item, intcolumn)

void  itemClicked(QTreeWidgetItem * item, intcolumn)

void  itemDoubleClicked(QTreeWidgetItem *item, int column)

void  itemSelectionChanged()

3、常用槽

void  clear()                                                                                 //清空

void  collapseItem(const QTreeWidgetItem *item)       //收起

void  expandItem(const QTreeWidgetItem *item)                  //展開

void  scrollToItem(const QTreeWidgetItem *item, QAbstractItemView::ScrollHint hint = EnsureVisible)            //滾動到項,常用於查找

 

1.8、progressBar----進度條

1、常用函數

QProgressDialog( const QString & labelText, const QString& cancelButtonText, int minimum, int maximum, QWidget * parent = 0,Qt::WindowFlags f = 0 )            //構造函數

int    maximum() const    //獲取最大值

int    minimum() const     //獲取最小值

int    value() const            //獲取當前值

2、常用信號

void  valueChanged(int value)

3、常用槽

void  reset()

void  setMaximum(int maximum)                               //設置最大值

void  setMinimum(int minimum)                                 //設置最小值

void  setRange(int minimum, int maximum)            //設置值範圍

void  setValue(int value)                                                 //設置當前值

 

1.9、comboBox----組合下拉框

1、常用函數

void  addItem(const QString & text, constQVariant & userData = QVariant())  //加入純文本

void  addItem(const QIcon & icon, constQString & text, const QVariant & userData = QVariant())     //加入圖標和文字

void  addItems(const QStringList & texts)      //批量加入

QString     currentText() const                             //當前內容

void  insertItem(int index, const QString& text, const QVariant & userData = QVariant())

void  insertItem(int index, const QIcon &icon, const QString & text, const QVariant & userData = QVariant())

void  insertItems(int index, constQStringList & list)

void  removeItem(int index)

2、常用信號

void  currentIndexChanged(int index)

void  currentIndexChanged(const QString &text)

void  currentTextChanged(const QString &text)

void  editTextChanged(const QString &text)

void  highlighted(int index)

void  highlighted(const QString & text)

3、常用槽

void  clear()

void  clearEditText()

void  setCurrentIndex(int index)

void  setCurrentText(const QString &text)

void  setEditText(const QString & text)

 

1.10 QmessageBox----消息提示盒

(1)常用函數

QPushButton *         addButton(constQString & text, ButtonRole role)        //加按鈕

QPushButton *         addButton(StandardButtonbutton)

void  removeButton(QAbstractButton * button)

void  setDefaultButton(QPushButton * button)     //設置默認按鈕

void  setInformativeText(const QString &text)

void  setStandardButtons(StandardButtonsbuttons)   //設置標準按鈕

void  setText(const QString & text)

void  setWindowTitle(const QString &title)

 

靜態函數:

void  about(QWidget * parent, const QString& title, const QString & text)

void  aboutQt(QWidget * parent, const QString& title = QString())

StandardButton       critical(QWidget *parent, const QString & title, const QString & text, StandardButtonsbuttons = Ok, StandardButton defaultButton = NoButton)

StandardButton       information(QWidget* parent, const QString & title, const QString & text, StandardButtonsbuttons = Ok, StandardButton defaultButton = NoButton)

StandardButton       question(QWidget *parent, const QString & title, const QString & text, StandardButtonsbuttons = StandardButtons( Yes | No ), StandardButton defaultButton = NoButton)

StandardButton       warning(QWidget *parent, const QString & title, const QString & text, StandardButtonsbuttons = Ok, StandardButton defaultButton = NoButton)

 

(2)常見用法舉例:

例1:

QMessageBox msgBox;

msgBox.setText("The document has beenmodified.");

msgBox.setInformativeText("Do you wantto save your changes?");

msgBox.setStandardButtons(QMessageBox::Save| QMessageBox::Discard | QMessageBox::Cancel);

msgBox.setDefaultButton(QMessageBox::Save);

int ret = msgBox.exec();

 

switch (ret) {

 case QMessageBox::Save:

     // Save was clicked

     break;

 case QMessageBox::Discard:

     // Don't Save was clicked

     break;

 case QMessageBox::Cancel:

     // Cancel was clicked

     break;

 default:

     // should never be reached

     break;

}

效果圖:

 

例2:

int ret = QMessageBox::warning(this,tr("My Application"),

                               tr("Thedocument has been modified.\n"

                                  "Do youwant to save your changes?"),

                              QMessageBox::Save | QMessageBox::Discard

                               |QMessageBox::Cancel,

                              QMessageBox::Save);

效果圖:

 

1.11 QFileDialog----文件選擇框

(1) 常見函數

最常用的靜態成員函數:

1QString      getExistingDirectory( QWidget * parent = 0, const QString & caption= QString(), const QString & dir = QString(), Options options =ShowDirsOnly )

2QString      getOpenFileName ( QWidget * parent = 0,const QString & caption = QString(), const QString & dir = QString(),const QString & filter = QString(), QString * selectedFilter = 0, Optionsoptions = 0 )

3QStringList        getOpenFileNames ( QWidget * parent = 0,const QString & caption = QString(), const QString & dir = QString(),const QString & filter = QString(), QString * selectedFilter = 0, Optionsoptions = 0 )

4QString      getSaveFileName ( QWidget * parent = 0, const QString & caption = QString(),const QString & dir = QString(), const QString & filter = QString(),QString * selectedFilter = 0, Options options = 0 )

 

void  selectFile(const QString &filename)

void  selectNameFilter(const QString &filter)

QStringList       selectedFiles() const

QString     selectedNameFilter() const

void  setAcceptMode(AcceptMode mode)

void  setDefaultSuffix(const QString &suffix)

void  setDirectory(const QString &directory)

void  setDirectory(const QDir &directory)

 

 (2)常見用法舉例:

例1:

QFileDialog fildlg;

   fildlg.setAcceptMode(QFileDialog::AcceptOpen);

   if(fildlg.exec()==QFileDialog::Accepted) // ok

        {

        int ret =QMessageBox::information(this, "Title", "打開成功",

                                  QMessageBox::Ok, QMessageBox::Ok);

 

        }

效果圖:

 

例2:

QStringfileName=QFileDialog::getOpenFileName(this,

tr("OpenImage"),"/home/jana",tr("Image Files(*.png *.jpg *.bmp)"));

效果圖:

1.12 QSystemTrayIcon----托盤類

(1)常用函數

void  setContextMenu( QMenu * menu )       //設置托盤右鍵菜單

void  setIcon( const QIcon & icon )                            //設置圖標

void  setToolTip( const QString & tip )             //設置托盤名稱

void  showMessage( const QString & title, const QString & message, MessageIcon icon =Information, int millisecondsTimeoutHint = 10000 )          //設置氣泡顯示信息

 

常用信號

void  activated( QSystemTrayIcon::ActivationReason reason )      /*激活理由(單擊,雙擊等),通常用

connect(trayIcon,SIGNAL(activated(QSystemTrayIcon::ActivationReason)),this,SLOT(iconActivated(QSystemTrayIcon::ActivationReason)));綁定。*/

void  messageClicked()

1.13 QThread----線程類

(1)常用函數

void  exit( int returnCode = 0 )         //退出,返回一個代碼

bool isFinished() const                      //檢查線程是否結束

bool isRunning() const                     //檢查線程是否在運行

 

常用信號

void  finished()                                     //結束

void  started()                                      //開始

void  terminated()                              //終止

 

         常用槽:

         void  quit()                                            //退出,返回0,相當於QThread::exit(0)

void  start (Priority priority = InheritPriority ) //開始

void  terminate()                                 //終止

 

1.14 線程和信號-槽用法舉例

使用舉例:

//MyThread.h

class MyThread :public QThread

{

    Q_OBJECT                           //要使用“信號-槽”機制就要加入這句

signals:

    void ShowWin(int i);

protected:

    void run();

};

 

//MyThread.cpp

voidMyThread::run()                //run是線程的核心函數,自定義操作都在這裏進行

{

    while(1)

    {

        emit ShowWin(10);

    }

}

 

//mainwindow.h

class MainWindow: public QMainWindow

{

    Q_OBJECT

public:

explicit MainWindow(QWidget *parent = 0);

private slots:

    void SetShow(int i);

}

 

//mainwindow.cpp

MainWindow::MainWindow(QWidget*parent) :

    QMainWindow(parent),

    ui(new Ui::MainWindow)

{

    ui->setupUi(this);

 

         MyThread  *thread = new MyThread(parent);

    connect(thread, SIGNAL(ShowWin(int)), this, SLOT(SetShow(int)));        //在綁定信號槽時,信號函數和槽函數的參數均只有數據類型,沒有變量名

    thread->start();

}

 

voidMainWindow:: SetShow(int i)

{

    Std::cout<<i<<std::endl;

    show();

}

 

若要在自定義線程裏編輯界面,不可以直接通過窗口指針來操作界面,直接操作界面會莫名其妙地崩潰,應當通過信號槽機制來編輯界面。

四、QtWebkit的使用

1、QtWebkit從Qt4.4版本開始引入,若Qt4.4以上沒發現QtWebkit組件極有可能是安裝不完全所致。
2、使用webkit時注意要在.pro文件添加相應選項:QT+= webkitwidgets(Qt5版本),QT += webkit(Qt4版本)
3、簡單Demo存放在:\\192.168.1.1\temp\kongfy\webkit_Demo
參考網址:http://blog.csdn.net/liuhongwei123888/article/details/6111434
http://www.tuicool.com/articles/iayIj2

 

發佈了17 篇原創文章 · 獲贊 5 · 訪問量 8萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章