Qt5初見筆記(二)關於Qt的MVC結構(參考Sherriff, Nicholas《Learn Qt5》)
參考書目:
Sherriff, Nicholas.Learn Qt5: Build Modern, Responsive Cross-platform Desktop Applications with Qt, C++, and QML
OS: Windows 10
IDE: Qt Creator
Qt version: 5.10.0
為了更好地配合教材,這次把Qt的版本換成了和教材一致的5.10.0版本。
這篇文章講的是如何使用Qt Creator建立一個MVC框架的專案。
囉嗦一下:在上一篇文章(Qt5學習筆記(一)使用單個.pro檔案建立Hello World工程(參考Sherriff, Nicholas《Learn Qt5》)
這次的例子是遵循MVC框架實現的一個多專案工程。關於MVC,這裡簡單說明一下:MVC(Model View Controller)是一種設計思路,遵循它可以把使用者介面(View)、功能邏輯(Controller、Model)的程式碼分開實現。
M、V、C以及之間的關係是:
- V:View代表使用者介面,一般是提供互動式的圖形介面由使用者下達各種指令。它可以訪問Controller和Model,因為它需要將使用者通過使用者介面發出的命令傳遞給Controller控制Model並呈現結果;
- C:Controller代表控制器,用來接收使用者通過View傳遞給它的指令對資料模型Model進行操作。可以訪問Model,因為它需要對Model的資料進行操作,但是Controller並不能訪問到View;
- M:Model可以看作是各種資料模型,用來提供各種資料。它既不能訪問View也不能訪問Controller。
在選單欄中單擊檔案->新建檔案或專案->其他專案->子目錄專案,然後單擊Choose..建立工程。
專案名稱為cm,路徑任選,這裡放在上一篇文章中建立的qt資料夾裡,Next。
然後進入開發包選擇。Desktop Qt 5.10.0 MinGW 32bit為必選,其他可選。這裡全選(不全選當然OK),下一步。
最後兩個全部選擇預設<None> 之後,單擊“完成& 新增子專案”完成子目錄專案的建立。
然後會彈出“新建子專案”視窗,選擇Application->Qt Quick Application - Empty,單擊Choose..
子專案命名為“cm-ui” ,路徑預設放在cm目錄下,下一步。
Build system預設選qmake,下一步。
Minimal required Qt version預設選Qt 5.9,Use Qt Virtual Keyboard預設不選,下一步。
和之前的開發包選擇一樣,Desktop Qt 5.10.0 MinGW 32bit為必選,其他可選。這裡全選(不全選也OK),然後下一步。
最後,預設選擇作為子專案新增到專案cm.pro中,新增到版本控制系統預設選擇<None>,完成建立。
至此,我們MVC中的View部分已經建立完畢。 接下來建立業務邏輯部分。
在“專案”面板中,右擊最頂部的cm資料夾,選擇“新子專案...”。
選擇Library->C++庫,單擊Choose..
型別預設選擇共享庫,名稱為cm-lib,建立路徑預設在cm資料夾下,下一步。
模組預設只選擇QtCore,下一步。
這裡我們可以建立自己的類了,這裡類名為Client,然後標頭檔案和原始檔會自動命名為client.h和client.cpp,下一步。
最後,和之前建立的cm-ui一樣,預設選擇作為子專案新增到專案cm.pro中,新增到版本控制系統預設選擇<None>,完成建立。
至此cm-lib子工程已建立完畢。接下來建立最後一個子工程cm-tests,用於單元測試。
右擊專案面板的cm資料夾,選擇“新子專案...”,在“其他專案”中選擇“Qt單元測試”,單擊“Choose..”。
專案名稱命名為“cm-tests” ,路徑預設在cm資料夾下,下一步。
模組預設選擇QtCore和QtTest,下一步。
類名命名為“ClientTests”,勾選“生成初始化和清理程式碼”,檔案命名為client-tests.cpp,下一步。
專案管理中,同樣預設選擇作為子專案新增到專案cm.pro中,新增到版本控制系統預設選擇<None>,完成建立。
經歷過漫長的建立嚮導,至此三個子工程已全部建立完成,現在我們的專案面板結構應該是這樣的:
下面對這三個子工程分別處理。
cm-lib
首先在cm-lib資料夾下新建資料夾source(Tip:新建資料夾的快捷鍵是Shift+Ctrl+N),把cm-lib下的cm-lib_global.h移動到source下,然後在source資料夾下再新建資料夾models,把cm-lib下的client.cpp和client.h移動到models下。
然後回到Qt Creator,開啟cm-lib.pro,編輯程式碼如下:
QT -= gui
TARGET = cm-lib
TEMPLATE = lib
CONFIG += c++14
DEFINES += CMLIB_LIBRARY
INCLUDEPATH += source
SOURCES += source/models/client.cpp
HEADERS += source/cm-lib_global.h \
source/models/client.h
逐行解釋:
由於cm-lib是一個庫工程,所以這裡不用載入預設的GUI模組,所以我們在變數QT中去掉了這個模組。
TARGET變數是我們要給我們的二進位制輸出檔案起的名字(這裡是cm-lib.dll),如果沒有給TARGET變數賦值,這個輸出檔案的名字就預設為工程名。
TEMPLATE變數在上一篇文章中提到過,它指的是工程的型別,這次我們的型別不再是app而是lib。
CONFIG變數也在上一篇文章中提到過,這裡仍然使用C++14的特性。
cm-lib_global.h是一個前處理器模板,用於匯出.dll檔案,這裡新增值CMLIB_LIBRARY到DEFINES可以觸發這次匯出。
INCLUDEPATH的值對應於原始檔中#include的宣告,當使用#include包含某個檔案時,會根據INCLUDEPATH的值尋找。
SOURCES和HEADERS的值較原來修改了一下,來匹配之前移動.cpp和.h檔案的操作。
現在在專案面板中右擊cm-lib資料夾,單擊“執行qmake”,成功後再次右擊cm-lib單擊“重新構建”。
cm-tests
在cm-tests目錄下新建兩層子目錄source\models,把client-tests.cpp移動到models下。
回到Qt Creator,編輯cm-tests.pro:
QT += testlib
QT -= gui
TARGET = client-tests
TEMPLATE = app
CONFIG += c++14
CONFIG += console
CONFIG -= app_bundle
INCLUDEPATH += source
SOURCES += source/models/client-tests.cpp
這裡配置與cm-lib.pro相似,只是工程型別是app而不是lib了;而且這次也不需要GUI模組,但需要新增testlib模組用來獲取Qt單元測試的功能。
然後對cm-tests執行qmake,然後重新構建。
cm-ui
這次在cm-ui目錄下新建兩個資料夾:source、views,把main.cpp移動到source下,把main.qml移動到views下,並把qml.qrc重新命名為views.qrc。編輯cm-ui.pro:
QT += qml quick
TEMPLATE = app
CONFIG += c++14
INCLUDEPATH += source
SOURCES += source/main.cpp
RESOURCES += views.qrc
# Additional import path used to resolve QML modules in Qt Creator's code model
QML_IMPORT_PATH = $$PWD
實現UI介面要使用QML編寫,這裡需要的是qml和quick兩個模組。
關於變數QML_INCLUDE_PATH等到之後使用QML模組時再解釋。
接下來在檔案資源管理器中用文字編輯器(這裡使用的Atom)編輯views.qrc:
<RCC>
<qresource prefix="/">
<file>views/main.qml</file>
</qresource>
</RCC>
最後,編輯main.cpp,只需要修改這一行:
engine.load(QUrl(QStringLiteral("qrc:/views/main.qml")));
好了,對cm-ui執行cmake並重新構建。
執行之前,先調整一下左下角的配置:
配置好之後就可以點綠色三角運行了:
嗯,就是一個空白的Hello World視窗,說明執行成功了。這就是目前構建的MVC多專案解決方案(multiproject solution)