Qt入門培訓(xùn)教材_第1頁
Qt入門培訓(xùn)教材_第2頁
Qt入門培訓(xùn)教材_第3頁
Qt入門培訓(xùn)教材_第4頁
Qt入門培訓(xùn)教材_第5頁
已閱讀5頁,還剩31頁未讀 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

1、目錄Qt入門31開發(fā)環(huán)境配置31.1下載31.2配置環(huán)境變量31.3設(shè)置編譯器31.4設(shè)置調(diào)試器31.5QtCreator快捷鍵42第一個(gè)Qt項(xiàng)目52.1使用QtCreator52.1.1創(chuàng)建Qt項(xiàng)目52.1.2編輯項(xiàng)目代碼52.1.3構(gòu)建運(yùn)行項(xiàng)目72.2使用幫助文檔72.3使用設(shè)計(jì)器72.3.1通過設(shè)計(jì)器來實(shí)現(xiàn)一個(gè)簡(jiǎn)單界面。72.4使用Qt語言家93Qt控件124窗口164.1對(duì)話框164.2消息框164.3菜單欄174.4工具欄174.5狀態(tài)欄175布局管理185.1垂直線性布局185.2水平線性布局185.3網(wǎng)格布局196信號(hào)與槽216.1使用Qt定義的信號(hào)與槽216.2自定義信號(hào)與槽2

2、16.2.1信號(hào)的聲明216.2.2信號(hào)的發(fā)送226.2.3槽函數(shù)的聲明226.2.4槽函數(shù)的實(shí)現(xiàn)226.2.5連接信號(hào)和槽227事件248Model-View架構(gòu)258.1自定義模型258.1.1自定義模型268.1.2模型的實(shí)現(xiàn)288.1.3模型的使用318.2自定義委托318.2.1委托的定義318.2.2委托的實(shí)現(xiàn)328.2.3委托的使用349內(nèi)存管理36Qt入門1 開發(fā)環(huán)境配置1.1 下載從Qt官網(wǎng)(/downloads)下載Qt5.3.X。本文檔使用的Qt版本為5.3.1,下載后使用了默認(rèn)的安裝路徑C:Qt。1.2 配置環(huán)境變量Win7系統(tǒng)下

3、,“計(jì)算機(jī)”-右鍵屬性-高級(jí)系統(tǒng)設(shè)置,在系統(tǒng)屬性對(duì)話框里選擇“高級(jí)”tab,點(diǎn)擊最下方的“環(huán)境變量”?;蛘?控制面板-系統(tǒng)和安全-系統(tǒng)-高級(jí)系統(tǒng)設(shè)置,打開系統(tǒng)屬性對(duì)話框。² 配置PATH環(huán)境變量,在環(huán)境變量PATH的值的最后添加Qt安裝路徑下bin目錄的位置(根據(jù)實(shí)際情況進(jìn)行設(shè)置,我這里是C:QtQtmsvc2012_openglbin)。² 配置QTDIR環(huán)境變量,檢查是否有QTDIR環(huán)境變量,沒有則新建,設(shè)置其值為bin目錄的上層目錄(根據(jù)實(shí)際情況進(jìn)行設(shè)置,我這里是C:QtQtmsvc2012_opengl)。1.3 設(shè)置編譯器打開QtC

4、reator,菜單欄上選擇“工具”-“選項(xiàng)”,彈出選項(xiàng)對(duì)話框,選項(xiàng)對(duì)話框左側(cè)列表中選擇“構(gòu)建和運(yùn)行”,切換到編譯器tab,能查看到已有的編譯器。Linux下,QtCreator自動(dòng)檢測(cè)已安裝的gcc作為其編譯器。Windows下,QtCreator能自動(dòng)檢測(cè)到已安裝的VS編譯器。1.4 設(shè)置調(diào)試器打開QtCreator,菜單欄上選擇“工具”-“選項(xiàng)”,彈出選項(xiàng)對(duì)話框,左側(cè)列表中選擇“構(gòu)建和運(yùn)行”,切換到Debuggers Tab,查看已有的調(diào)試器。Linux下,QtCreator檢測(cè)已安裝的gdb作為其調(diào)試器。Windows下,需要手動(dòng)下載安裝CDB,之后QtCreator能將其作為調(diào)試器。下

5、載地址:1.5 QtCreator快捷鍵Ctrl + B構(gòu)建Ctrl + R運(yùn)行F5調(diào)試啟動(dòng)F9新建/刪除斷點(diǎn)F10單步調(diào)試(不進(jìn)入函數(shù))F11單步調(diào)試(進(jìn)入函數(shù)內(nèi)部)F2轉(zhuǎn)到定義2 第一個(gè)Qt項(xiàng)目通過helloqt 項(xiàng)目,掌握QtCreator、Designer、Linguist的使用。2.1 使用QtCreator2.1.1 創(chuàng)建Qt項(xiàng)目在QtCreator編輯視圖左側(cè)區(qū)域點(diǎn)右鍵,選擇“新建項(xiàng)目”,彈出新建項(xiàng)目對(duì)話框,在項(xiàng)目下選擇“應(yīng)用程序”,右側(cè)選擇“Qt Widget Application”,點(diǎn)擊“choose按鈕”。彈出Qt Widget Application對(duì)話框。項(xiàng)目介紹和位

6、置頁,設(shè)置名稱和創(chuàng)建路徑,下一步;Kit Selection頁,可配置Debug版和Release版程序的生成路徑,下一步;類信息頁,設(shè)置類名、基類、頭文件、源文件、去掉“創(chuàng)建界面”的勾選,下一步;項(xiàng)目管理頁,完成。2.1.2 編輯項(xiàng)目代碼編輯頭文件mainwindow.h#ifndef MAINWINDOW_H#define MAINWINDOW_H#include <QMainWindow>#include <QPushButton>/ 手動(dòng)添加class MainWindow : public QMainWindow Q_OBJECTpublic: MainWin

7、dow(QWidget *parent = 0); MainWindow();private: QPushButton * m_pPBHello;/ 手動(dòng)添加;#endif / MAINWINDOW_H編輯源碼文件mainwindow.cpp#include "mainwindow.h"MainWindow:MainWindow(QWidget *parent) : QMainWindow(parent)/ 添加下列三行 m_pPBHello = new QPushButton(this); m_pPBHello->setText(tr("Hello, Qt

8、!"); m_pPBHello->move(10, 10);MainWindow:MainWindow()查看一下main.cpp#include "mainwindow.h"#include <QApplication>int main(int argc, char *argv) QApplication a(argc, argv); MainWindow w; w.show(); return a.exec();2.1.3 構(gòu)建運(yùn)行項(xiàng)目編輯視圖左側(cè)區(qū)域,在項(xiàng)目“helloqt”上右鍵,選擇“將項(xiàng)目設(shè)置為活動(dòng)項(xiàng)目”,按下Ctrl + B 構(gòu)建項(xiàng)

9、目,按下Ctrl + R 運(yùn)行項(xiàng)目。程序啟動(dòng)后即可看到界面,第一個(gè)Qt項(xiàng)目運(yùn)行成功。練習(xí)1:熟悉QtCreator的界面,重點(diǎn)查看菜單欄中,“構(gòu)建”和“調(diào)試”中的菜單項(xiàng);并查看菜單欄“工具”-“選項(xiàng)”,選項(xiàng)對(duì)話框中的各種設(shè)置。練習(xí)2:使用QtCreator創(chuàng)建一個(gè)Qt Widgets Application,查看自動(dòng)生成的代碼文件和pro后綴的項(xiàng)目文件,并運(yùn)行項(xiàng)目。2.2 使用幫助文檔QtCreator左側(cè)選擇“幫助”,點(diǎn)擊幫助界面左上角的下拉列表,選擇“索引”,在查找框中輸入QPushButton,點(diǎn)擊下方匹配的結(jié)果即可查看QPushButton相關(guān)幫助。練習(xí)3:使用Assistant查看Q

10、PushButton的用法。2.3 使用設(shè)計(jì)器除了手寫代碼實(shí)現(xiàn)界面,還可以通過在設(shè)計(jì)器中拖拽控件進(jìn)行界面設(shè)計(jì),拖拽出的界面信息記錄在相應(yīng)的ui文件中。構(gòu)建項(xiàng)目時(shí),Qt會(huì)通過ui文件里的信息生成以u(píng)i_開頭的.h文件,存放在項(xiàng)目的生成路徑下。要在項(xiàng)目中使用拖拽出來的界面就必須包含該生成的頭文件。一般而言,程序界面最好通過手寫代碼來實(shí)現(xiàn),這樣操控性更好。本人通過使用設(shè)計(jì)器拖拽過幾次界面,感覺不太習(xí)慣,還是手寫代碼好,不過仍然可以通過使用設(shè)計(jì)器來學(xué)習(xí)Qt控件的用法。2.3.1 通過設(shè)計(jì)器來實(shí)現(xiàn)一個(gè)簡(jiǎn)單界面。點(diǎn)擊QtCreator左側(cè)的“編輯”,切換到編輯視圖,在項(xiàng)目helloqt上右鍵,選擇“添加新

11、文件”,彈出新建文件對(duì)話框。在文件和類下選擇“Qt”,右側(cè)選擇“Qt設(shè)計(jì)師界面類”,choose。彈出Qt設(shè)計(jì)師界面類對(duì)話框。選擇界面模板頁,在“templateforms”下選擇“Dialog without buttons”,下一步;選擇類名頁,設(shè)置類名CDlgTest,下一步;項(xiàng)目管理頁,完成。自動(dòng)跳轉(zhuǎn)到設(shè)計(jì)視圖。在設(shè)計(jì)視圖中,從左側(cè)工具箱里,“buttons”下拖動(dòng)Push Button到窗體中。QtCreator左側(cè)欄中點(diǎn)擊“編輯”,切換回編輯視圖。編輯mainwindow.h/ #include <QMainWindow>#include <QPushButton

12、>#include "cdlgtest.h"/ 包含拖拽產(chǎn)生的對(duì)話框類的頭文件class MainWindow : public QMainWindow/ / 添加以下三行private: QPushButton * m_pPBHello; CDlgTest * m_pDlg;/ 編輯mainwindow.cpp#include "mainwindow.h"MainWindow:MainWindow(QWidget *parent) : QMainWindow(parent)/ / 添加以下三行 m_pDlg = new CDlgTest(this

13、); connect(m_pPBHello, SIGNAL(clicked(), m_pDlg, SLOT(show();MainWindow:MainWindow()Helloqt項(xiàng)目上右鍵,選擇“執(zhí)行qmake”。執(zhí)行qmake會(huì)更新項(xiàng)目生成路徑下的makefile文件,保證新添加進(jìn)項(xiàng)目的代碼文件也會(huì)被編譯,否則可能會(huì)在構(gòu)建項(xiàng)目時(shí)出現(xiàn)找不到符號(hào)之類的錯(cuò)誤。按下Ctrl + B 構(gòu)建項(xiàng)目,由ui文件轉(zhuǎn)換得到的頭文件會(huì)存放在項(xiàng)目生成路徑下。按下Ctrl + R運(yùn)行項(xiàng)目。程序運(yùn)行后,點(diǎn)擊按鈕即可彈出使用設(shè)計(jì)器拖拽出的對(duì)話框。練習(xí)4:向項(xiàng)目里添加一個(gè)使用設(shè)計(jì)器拖拽出的對(duì)話框界面,查看設(shè)計(jì)器拖拽出的

14、界面是如何通過代碼進(jìn)行引用,構(gòu)建項(xiàng)目后到生成路徑下查看生成的頭文件,運(yùn)行項(xiàng)目。2.4 使用Qt語言家源代碼中經(jīng)常會(huì)出現(xiàn)一些字符串,比如定義要顯示在控件上的文本,在不同的語言環(huán)境下,可能會(huì)需要顯示不同語言對(duì)應(yīng)的文本。針對(duì)多語言切換的需求,Qt提供的解決方案是,在所有需要翻譯的字符串處都使用QObject:tr()函數(shù),Qt提取出所有QObject:tr()函數(shù)的參數(shù),使用Qt語言家對(duì)其進(jìn)行翻譯后發(fā)布,Qt程序可以在運(yùn)行時(shí)加載發(fā)布的翻譯文件以更新文本字符串。此外,還能通過這種方案解決不同主機(jī)間字符集差異引起的字符亂碼問題。在項(xiàng)目面板下,雙擊對(duì)其進(jìn)行編輯,在最后加上一行TRAN

15、SLATIONS += helloqt_zh_CN.ts在菜單欄上選擇“工具”-“外部”-“Qt語言家”-“更新翻譯”在helloqt項(xiàng)目路徑下生成文件helloqt_zh_CN.ts在任務(wù)欄上“開始”-“所有程序”-“Qt 5.3.1”- “5.3”-“MSVC 2012 opengl”-“Linguist” 打開Qt語言家,“文件”-“打開” 選擇helloqt項(xiàng)目路徑下的helloqt_zh_CN.ts。左側(cè)上下文面板中,選擇MainWindow,在源文下選擇”Hello, Qt!”,在下方面板中,漢語 譯文輸入框中輸入“你好 Qt!”,再點(diǎn)擊源文列表下”Hello, Qt!”前面的問號(hào)

16、圖標(biāo),變?yōu)楣刺?hào)。確認(rèn)這一行已翻譯。Qt語言家的菜單欄中,“文件”-“保存”, 再“文件”-“發(fā)布”,在helloqt 項(xiàng)目路徑下生成文件helloqt_zh_CN.qm?;氐絈tCreator,編輯main.cpp#include "mainwindow.h"#include <QApplication>#include <QTranslator>int main(int argc, char *argv) QApplication a(argc, argv); QTranslator translator; translator.load(&quo

17、t;helloqt_zh_CN"); a.installTranslator(&translator); MainWindow w; w.show(); return a.exec();構(gòu)建項(xiàng)目,將helloqt_zh_CN.qm與生成的exe放在同一目錄下,雙擊運(yùn)行exe,即可看到程序界面上的文字顯示為中文了。練習(xí)5:在項(xiàng)目代碼中使用tr()函數(shù)來生成QString對(duì)象,練習(xí)使用Linguist來翻譯字符串,并在程序中使用發(fā)布后的文件。3 Qt控件類名控件常用函數(shù)QLabel標(biāo)簽setText()setPixmap()setBuddy()setAlignment() set

18、Indent()QCheckBox復(fù)選框setText()setChecked()QRadioButton單選框setText()setChecked()QLineEdit單行文本編輯框QComboBox組合框insertItem()setItemText()addItem()clear()currentIndex()QPushButton按鈕setText()setIcon()QListWidget 列表(基于Item)insertItem()takeItem()currentItem()setCurrentItem()count()QTableWidget表格(基于item)setColu

19、mnCount()setItem()setHorizontalHeaderLabels()setVerticalHeaderLabels()setRowCount()columnCount()rowCount()itemAt()clear()QTreeWidget樹(基于item)setColumnCount()setHeaderLabels()addTopLevelItem()clear()currentItem()expandItem()QListView 列表(基于model - view)QTableView表格(基于model - view)QTreeView樹(基于model -

20、view)QGroupBox分組框setTitle()setLayout()QSplitter分割器addWidget()setStretchFactor()QWidget小部件sizeHint()setSizePolicy()resize()show()hide()close()setLayout()QTabWidget 標(biāo)簽部件addTab()removeTab()setTabText()setTabEnabled()QDialog對(duì)話框exec()show()setModal()QMainWindow主窗口setCentralWidget()menuBar()addToolBar()st

21、atusBar()練習(xí)6:查看各控件的幫助;在項(xiàng)目中練習(xí)使用上述控件,并查看最終效果。4 窗口4.1 對(duì)話框 QDialog dlg; dlg.setWindowTitle(tr("Dialog"); dlg.exec();/ 顯示模態(tài)對(duì)話框 QDialog * dlg2 = new QDialog(this); dlg2->setWindowTitle(tr("Dialog2"); dlg2->setModal(true); dlg2->show();/ 不添加上一行時(shí),顯示非模態(tài)對(duì)話框4.2 消息框 / 消息框 int ret =

22、QMessageBox:information(this, tr("title"), tr("text"); / 詢問框 ret = QMessageBox:question(this, tr("title"), tr("text"); if (QMessageBox:Yes = ret) qDebug("dont click yes"); / 警告框 ret = QMessageBox:warning(this, tr("title"), tr("text&quo

23、t;), QMessageBox:Ok | QMessageBox:Cancel, QMessageBox:Cancel); if (QMessageBox:Ok != ret) qWarning("warning"); 練習(xí)7:分別練習(xí)模態(tài)和非模態(tài)對(duì)話框的顯示;在程序中使用上述三種消息對(duì)話框。4.3 菜單欄 QMenu * mnFile = new QMenu(tr("File"); QAction * actOpen = new QAction(tr("&Open"), this); menuBar()->addMe

24、nu(mnFile);/ 第一次調(diào)用menuBar()時(shí)將創(chuàng)建菜單欄 mnFile->addAction(actOpen);4.4 工具欄 QToolBar * toolbar = new QToolBar(this); addToolBar(toolbar);/ 工具欄需要手動(dòng)添加到界面 QAction * actOpen = new QAction(tr("&Open"), this); toolbar->addAction(actOpen);4.5 狀態(tài)欄 statusBar();/ 第一次調(diào)用statusBar()將創(chuàng)建狀態(tài)欄 statusBar

25、()->showMessage(tr("Ready"), 2000);練習(xí)8:創(chuàng)建一個(gè)Qt Widget項(xiàng)目,為主界面添加菜單欄、工具欄和狀態(tài)欄。5 布局管理常用的布局管理有三種,垂直線性布局,水平線性布局,網(wǎng)格布局。5.1 垂直線性布局被QVBoxLayout管理的部件按添加的先后順序在垂直方向上排成一列。 QWidget * window = new QWidget();QPushButton * button = new QPushButton(); QPushButton * button1 = new QPushButton(); QSpacerItem *

26、 spaceItem = new QSpacerItem(10, 10, QSizePolicy:Minimum, QSizePolicy:Expanding); QVBoxLayout * layout = new QVBoxLayout();layout->addWidget(button); layout->addWidget(button1); layout->addItem(spaceItem);/添加它來占據(jù)垂直方向上所有剩余的空間 window->setLayout(layout);5.2 水平線性布局被QHBoxLayout管理的部件按添加進(jìn)來的先后順序

27、在水平方向上排成一行。 QWidget * window = new QWidget(); QPushButton * button = new QPushButton(); QPushButton * button1 = new QPushButton(); QSpacerItem * spaceItem = new QSpacerItem(10, 10, QSizePolicy:Expanding, QSizePolicy:Minimum); QHBoxLayout * layout = new QHBoxLayout(); layout->addWidget(button); la

28、yout->addWidget(button1); layout->addItem(spaceItem);/ 添加它來占據(jù)水平方向上所有剩余空間 window->setLayout(layout);5.3 網(wǎng)格布局QGridLayout將空間劃分成網(wǎng)格,其中的每一個(gè)部件占據(jù)其中的一格或幾格。添加一個(gè)部件時(shí)指定其占據(jù)的行號(hào)、列號(hào)、行數(shù)、列數(shù)、對(duì)齊方式。 QWidget * pWindow = new QWidget(); QPushButton * pBtn = new QPushButton(tr(“pBtn”); QPushButton * pBtn1 = new QPus

29、hButton(tr(“pBtn1”); QPushButton * pBtn2 = new QPushButton(tr(“pBtn2”); QGridLayout * pLayout = new QGridLayout(); pLayout->addWidget(pBtn, 0, 0, 1, 2, 0); pLayout->addWidget(pBtn1, 1, 0, 1, 1, 0); pLayout->addWidget(pBtn2, 1, 1, 1, 1, 0); pLayout->setRowMinimumHeight(0, 30); pLayout->

30、;setColumnMinimumWidth(0, 30); pLayout->setRowStretch(0, 0); pLayout->setRowStretch(1, 1); pLayout->setColumnStretch(0, 1); pLayout->setColumnStretch(1, 1); pWindow->setLayout(pLayout);練習(xí)9:結(jié)合三種常用布局和常用控件,實(shí)現(xiàn)記事本的查找對(duì)話框。6 信號(hào)與槽信號(hào)和槽是Qt中進(jìn)行對(duì)象間通訊的一種機(jī)制。對(duì)象狀態(tài)改變時(shí),主動(dòng)發(fā)送一個(gè)信號(hào),與此信號(hào)相連接的槽將接收到這個(gè)信號(hào),發(fā)送信號(hào)的對(duì)象不

31、知道也不關(guān)心哪些槽將接收到這個(gè)信號(hào)。槽是一個(gè)能對(duì)信號(hào)進(jìn)行響應(yīng)的函數(shù)。一旦一個(gè)槽與一個(gè)信號(hào)相連接了,槽函數(shù)將在信號(hào)發(fā)送后被調(diào)用。所有繼承自QObject及其子類的類都可以包含信號(hào)和槽。一個(gè)信號(hào)可以與多個(gè)槽相連接,一個(gè)槽也可以與多個(gè)信號(hào)相連接。槽能用來接收信號(hào),它也是普通的成員函數(shù)。信號(hào)和槽可以有任意多個(gè)任意類型的參數(shù),參數(shù)類型和排列順序要相匹配,信號(hào)的參數(shù)個(gè)數(shù)可以多于槽,多余的參數(shù)將被忽視。6.1 使用Qt定義的信號(hào)與槽 connect(m_pPBHello, SIGNAL(clicked(), m_pDlg, SLOT(show();6.2 自定義信號(hào)與槽6.2.1 信號(hào)的聲明/ class

32、MainWindow : public QMainWindow Q_OBJECT/ signals: void btnClicked(bool, int, QString);/ ;/ 6.2.2 信號(hào)的發(fā)送發(fā)送信號(hào)時(shí),使用Qt定義的關(guān)鍵字emit,同時(shí)指定信號(hào)相關(guān)的參數(shù)。 emit btnClicked(true, 20, tr("");6.2.3 槽函數(shù)的聲明聲明槽函數(shù)時(shí),使用Qt定義的關(guān)鍵字slots,也可以指定public等訪問控制符。class MainWindow : public QMainWindowQ_OBJECT/ private slots: void

33、emitMySignal();void showDlg(bool b, int num);/ ;6.2.4 槽函數(shù)的實(shí)現(xiàn)槽函數(shù)的實(shí)現(xiàn)與普通函數(shù)一致。6.2.5 連接信號(hào)和槽使用connect函數(shù)連接信號(hào)和槽,第一個(gè)參數(shù)為信號(hào)的發(fā)出者,第二個(gè)參數(shù)為具體的信號(hào),需要使用SIGNAL()宏,第三個(gè)參數(shù)為信號(hào)的接收者,第四個(gè)參數(shù)為接收信號(hào)的槽函數(shù),需要使用SLOT()宏。 connect(m_pPBHello, SIGNAL(clicked(), this, SLOT(emitMySignal(); connect(this, SIGNAL(btnClicked(bool,int,QString),

34、this, SLOT(showDlg(bool,int);練習(xí)10:練習(xí)自定義信號(hào)和槽函數(shù),熟悉其用法。練習(xí)11:查看幫助文檔,了解常用控件發(fā)送的信號(hào)。7 事件事件是由系統(tǒng)或Qt在不同的時(shí)刻發(fā)出的,比如,鼠標(biāo)釋放事件,窗口關(guān)閉事件,計(jì)時(shí)器事件。通常情況下,我們并不需要關(guān)心事件,Qt組件會(huì)在需要我們關(guān)心的事件發(fā)生時(shí)發(fā)送信號(hào)。但是在某些情形下,仍需要我們對(duì)一些事件進(jìn)行處理,比如,響應(yīng)拖拽,對(duì)控件進(jìn)行自繪。當(dāng)需要自己處理Qt已經(jīng)定義的事件時(shí),我們需要繼承Qt的類,重寫相關(guān)事件的響應(yīng)函數(shù),在函數(shù)體進(jìn)行一些操作,比如發(fā)送適當(dāng)?shù)男盘?hào)之類的。練習(xí)12:重繪控件,比如QPushButton。(提示:重寫pai

35、ntEvent函數(shù))練習(xí)13:響應(yīng)鼠標(biāo)的拖拽事件,拖拽樹控件上的結(jié)點(diǎn)到表格上進(jìn)行顯示。(提示:查看QDrag、QMimeData、重寫QWidget的mousePressEvent、mouseMoveEvent、dragEnterEvent、dropEvent相關(guān)函數(shù))8 Model-View架構(gòu)傳統(tǒng)的MVC模式,即模型、視圖、控制器,分別實(shí)現(xiàn)管理數(shù)據(jù)、顯示數(shù)據(jù)、處理用戶輸入的功能。Qt把視圖和控制器組合在一起,形成其獨(dú)特的Model-View架構(gòu),只對(duì)模型進(jìn)行修改,即可完成視圖的更新。Qt中使用Model/View架構(gòu)的最主要的有三個(gè)類,QTableView、QTreeView、QListV

36、iew,支持自定義模型對(duì)數(shù)據(jù)進(jìn)行管理,和自定義委托處理數(shù)據(jù)的顯示和編輯。對(duì)于一般數(shù)據(jù)量不多的情況,使用相對(duì)應(yīng)的三個(gè)基于Item/View的類QTableWidget、QTreeWidget、QListWidget,對(duì)結(jié)點(diǎn)Item進(jìn)行操作即可滿足需求。8.1 自定義模型模型對(duì)數(shù)據(jù)進(jìn)行管理,并對(duì)外提供操作接口,使得視圖從模型中取出要顯示的數(shù)據(jù),用戶能向模型中加入新數(shù)據(jù)及更新已有數(shù)據(jù)。如果將一個(gè)模型注冊(cè)到多個(gè)視圖,對(duì)模型進(jìn)行一次修改,那么所有的視圖都將同步更新。示例:表格中將顯示所有員工的信息,每一行顯示一個(gè)員工,每一列顯示員工的一個(gè)屬性值。員工類CEmployee#ifndef CEMPLOYEE

37、_H#define CEMPLOYEE_H#include <QObject>class CEmployee : public QObject Q_OBJECTpublic: explicit CEmployee(QObject * parent = 0); explicit CEmployee(QString name, int age, char gender, bool married, QString department, QObject *parent = 0); CEmployee(const CEmployee & employee); CEmployee&

38、amp; operator =(const CEmployee & employee); QString GetName(); void SetName(const QString & name); int GetAge(); void SetAge(int age); char GetGender(); void SetGender(char gender = 'M'); bool isMarried(); void setMarried(bool married); QString GetDepartment(); void SetDepartment(co

39、nst QString & department);private: QString name; int age; char gender; bool married; QString department;Q_DECLARE_METATYPE(CEmployee)#endif / CEMPLOYEE_H為了能在調(diào)用setData()時(shí)將CEmployee類的變量傳給QVariant類型的參數(shù),需要使用宏Q_DECLARE_METATYPE對(duì)類進(jìn)行聲明。8.1.1 自定義模型對(duì)于表格的模型而言,必須實(shí)現(xiàn)rowCount()、columnCount()、data()函數(shù),rowCount

40、()返回視圖應(yīng)該顯示的行數(shù),columnCount()返回視圖應(yīng)顯示的列數(shù),data()函數(shù)根據(jù)參數(shù)返回請(qǐng)求獲取的數(shù)據(jù)。另外,實(shí)現(xiàn)headerData()函數(shù)以控制表頭的顯示。如果要自定義委托對(duì)數(shù)據(jù)進(jìn)行編輯,那么setData()和flags()是必須實(shí)現(xiàn)的兩個(gè)函數(shù),數(shù)據(jù)編輯結(jié)束后會(huì)調(diào)用setData()更新模型中的數(shù)據(jù),調(diào)用flags()來判斷某些位置是否可以進(jìn)行編輯等。CEmployeeTableModel類#ifndef CEMPLOYEETABLEMODEL_H#define CEMPLOYEETABLEMODEL_H#include <QAbstractTableModel&g

41、t;#include <QVector>#include "cemployee.h"class CEmployeeTableModel : public QAbstractTableModel Q_OBJECTpublic: explicit CEmployeeTableModel(QObject *parent = 0); int rowCount(const QModelIndex & parent = QModelIndex() const; int columnCount(const QModelIndex & parent = QMod

42、elIndex() const; QVariant data(const QModelIndex & index, int role = Qt:DisplayRole) const; QVariant headerData(int section, Qt:Orientation orientation, int role = Qt:DisplayRole) const; bool setData(const QModelIndex & index, const QVariant & value, int role = Qt:EditRole); Qt:ItemFlags

43、 flags(const QModelIndex & index) const;signals:public slots:private: QStringList headers; QVector<CEmployee *> datas; enum COLUMN_NAME = 0, COLUMN_AGE, COLUMN_GENDER, COLUMN_MARRIED, COLUMN_DEPARTMENT ;#endif / CEMPLOYEETABLEMODEL_H8.1.2 模型的實(shí)現(xiàn)需要注意以下幾個(gè)經(jīng)常在模型中出現(xiàn)的類和枚舉,QModelIndex指示要操作的具體位置,比如

44、數(shù)據(jù)所在列,所在行;Qt定義的role相關(guān)的枚舉值表示操作的數(shù)據(jù)將以什么角色被使用,比如用來進(jìn)行顯示,用來提供給編輯器進(jìn)行編輯;QVariant類是一個(gè)包裝類型,對(duì)Qt定義的大部分?jǐn)?shù)據(jù)類型都有相關(guān)的轉(zhuǎn)換方法,它也能包裝自定義類型的數(shù)據(jù)。#include "cemployeetablemodel.h"CEmployeeTableModel:CEmployeeTableModel(QObject *parent) : QAbstractTableModel(parent) headers << "Name" << "Age&

45、quot; << "Gender" << "married?" << "Department"int CEmployeeTableModel:rowCount(const QModelIndex &parent) const return datas.count();int CEmployeeTableModel:columnCount(const QModelIndex &parent) const return headers.count();QVariant CEmployee

46、TableModel:data(const QModelIndex &index, int role) const if (role = Qt:TextAlignmentRole) return Qt:AlignHCenter | Qt:AlignBottom; else if (role = Qt:DisplayRole | role = Qt:EditRole) && index.row() < datas.count() CEmployee * employee = datas.at(index.row(); switch(index.column() ca

47、se COLUMN_NAME: return employee->GetName(); case COLUMN_AGE: return employee->GetAge(); case COLUMN_GENDER: return employee->GetGender(); case COLUMN_MARRIED: return employee->isMarried(); case COLUMN_DEPARTMENT: return employee->GetDepartment(); return QVariant();QVariant CEmployeeTa

48、bleModel:headerData(int section, Qt:Orientation orientation, int role) const if (role = Qt:DisplayRole && orientation = Qt:Horizontal && section < headers.count() return headers.at(section); return QVariant();bool CEmployeeTableModel:setData(const QModelIndex &index, const QVa

49、riant &value, int role) if (role = Qt:UserRole) CEmployee * employee = value.value<CEmployee *>(); if (index.row() >= datas.count() datas.append(employee); else if (index.row() > 0) datas.insert(index.row(), employee); else datas.append(employee); return true; else if (role = Qt:Edit

50、Role && index.row() < datas.count() CEmployee * employee = datas.at(index.row(); switch (index.column() case COLUMN_NAME: employee->SetName(value.toString(); break; case COLUMN_AGE: employee->SetAge(value.toInt(); break; case COLUMN_GENDER: employee->SetGender(value.toChar().cell

51、(); break; case COLUMN_MARRIED: employee->setMarried(value.toBool(); break; case COLUMN_DEPARTMENT: employee->SetDepartment(value.toString(); break; default: break; return true; return false;Qt:ItemFlags CEmployeeTableModel:flags(const QModelIndex &index) const if (index.column() = COLUMN_

52、NAME | index.column() = COLUMN_AGE | index.column() = COLUMN_GENDER | index.column() = COLUMN_MARRIED) return QAbstractTableModel:flags(index) | Qt:ItemIsEditable; return QAbstractTableModel:flags(index);8.1.3 模型的使用 tableView = new QTableView(this);tableModel = new CEmployeeTableModel(tableView);tableView->setModel(tableModel);向模型中添加數(shù)據(jù) QModelIndex index =

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論