




版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領
文檔簡介
QT5開發及實例(第5版)第9章Qt5模型/視圖及實例——模型/視圖架構01基本概念基本概念模型/視圖架構的理念其實源于Web開發領域的MVC。MVC是起源于Smalltalk的一種與用戶界面相關的設計模式,它包括3個基本元素:表示數據的模型M(Model)、表示界面的視圖V(View)以及管理用戶界面操作邏輯的控制器C(Controller)。Qt的模型/視圖架構可分為三部分:模型M(Model)、視圖V(View)和代理D(Delegate)。其中,模型直接與數據源通信,并為程序其他部件提供數據接口,它從原始數據提取所需內容供給各類視圖組件去顯示或編輯;視圖也就是程序界面上以各種豐富多樣的形式展示數據的控件,它們從模型中獲得所要引用數據條目項的模型索引(ModelIndex),再以索引方式獲取和呈現各自的顯示內容;而代理則負責繪制界面上的數據條目,當用戶編輯條目時,它就直接與模型進行通信,它們之間的互動關系如圖。02實
現
類實
現
類1.模型類模型/視圖架構中的所有模型都基于抽象基類QAbstractItemModel,此類針對各種視圖組件和代理都有與之相適應的數據存取接口,由此而派生出一系列不同用途的子模型類,如圖。實
現
類其中,各個主要方面用途的類及其子類說明如下。文本、字符串列表:QAbstractListModel類是列表模型的抽象基類,通常程序界面上的列表項數據內容是以文本或字符串形式出現的,在Qt中用QStringList結構存儲,其對應的模型類QStringListModel就是從QAbstractListModel繼承而來。數據庫相關:數據庫的數據在界面上常以表格展示,由表格模型抽象類QAbstractTableModel派生出QtSql模塊用戶接口層的三個類QSqlQueryModel、QSqlTableModel及QSqlRelationalTableModel,分別實現對SQL語句查詢結果數據、表數據及關系表外鍵數據的讀寫。文件系統和目錄:QDirModel類是操作系統目錄數據的存儲模型;QFileSystemModel用于存儲文件系統信息。代理:QAbstractProxyModel與QProxyModel類分別是代理模型的抽象類及其實現類。實
現
類2.視圖類模型/視圖架構中的所有視圖都基于抽象基類QAbstractItemView,視圖及相關類繼承的層次結構如圖。下面就這幾個視圖類所對應組件的用途加以說明。QListView:列表視圖。用于顯示單列的列表數據,如組合框、下拉列表框控件的選項。QTableView:表格視圖。用于顯示表格形式的數據,常用于在界面上展示數據庫中的表或視圖的記錄內容。QTreeView:樹狀視圖。用于顯示可展開/折疊的多層次節點數據項,例如,瀏覽本地計算機操作系統的目錄樹。QColumnView:列視圖。當在界面上以多個并排級聯列表的形式展示樹狀層次結構數據時,每一級列表就是一個QColumnView。QHeaderView:表頭視圖。提供表格控件的行表頭或列表頭內容顯示。實
現
類3.代理類模型/視圖架構中的所有代理都基于抽象基類QAbstractItemDelegate,此類由QItemDelegate和QStyledItemDelegate類繼承。其中,QItemDelegate類由表示數據庫中關系代理的QSqlRelationalDelegate類繼承。QT5開發及實例(第5版)第9章Qt5模型/視圖及實例——常用模型/視圖組件實例01表格視圖/模型及實例1.表格視圖組件:QTableView2.表格模型3.實例表格視圖/模型及實例1.表格視圖組件:QTableView表格視圖QTableView組件用于在程序界面上展示二維數據表格,它常與Qt通用的標準項模型QStandardItemModel配合使用,通過setItem(i,j,項)方法將標準項QStandardItem的實例對象添加到表格正文內容的第i行第j列中,調用setModel(model)方法將模型關聯進表格視圖。QTableView常用方法如下:(1)rowHeight():獲得表中每一行的高度。(2)columnWidth():獲得表中每一列的寬度。(3)showGrid():顯示一個網格。(4)stretchLastSection():展開表中的單元格。(5)hideRow()和hideColumn():隱藏行和列。(6)showRow()和showColumn():顯示行和列。(7)selectRow()和selectColumn():選擇行和列。(8)resizeColumnsToContents()或resizeRowsToContents():根據每個列或行的空間需求分配可用空間。在模型/視圖架構中還有一個表頭視圖QHeaderView可用于顯示和控制QTableView的表頭,其方法如下:(1)verticalHeader():獲得垂直表頭。(2)horizontalHeader():獲得水平表頭。(3)hide():隱藏表頭。表格視圖/模型及實例2.表格模型QTableView通過綁定模型來更新其上的內容,可用的模型如表。模
型作
用QStringListModel存儲一組字符串QStandardItemModel存儲任意層次結構的數據QDirModel對文件系統進行封裝QSqlQueryModel對SQL的查詢結果集進行封裝QSqlTableModel對SQL中的表格進行封裝QSqlRelationalTableModel對帶有外鍵的SQL表格進行封裝QSortFilterProxyModel對模型中的數據進行排序或過濾表格視圖/模型及實例3.實例【例】(簡單)(CH901)用QStandardItemModel模型存儲課程信息,在QTableView表格視圖中顯示。以“直接編寫代碼”(即取消勾選“Generateform”復選框)方式創建Qt項目,項目名tableView,“ClassInformation”頁基類選“QWidget”。代碼如下(tableView.cpp):運行程序,顯示如圖。02樹狀視圖/模型及實例1.樹狀視圖組件:QTreeView2.實例樹狀視圖/模型及實例1.樹狀視圖組件:QTreeView樹狀視圖QTreeView組件用于顯示具有層次結構的節點數據項,也常與標準項模型一起使用,QStandardItemModel的實例對象model通過appendRow(QStandardItem*dotItem1)方法將標準項實例對象dotItem1添加進第一個節點,再調用setModel(model)方法將模型關聯進樹狀視圖。使用樹狀視圖,可以先創建一個標準項作為頂層對象,然后設置它的屬性,再創建子項添加到該項下……每一級均是如此,最后將頂層對象加入創建的樹狀視圖中。2.實例【例】(難度一般)(CH902)創建南京師范大學及其學院、系樹視圖。以“直接編寫代碼”(即取消勾選“Generateform”復選框)方式創建Qt項目,項目名treeView,“ClassInformation”頁基類選“QMainWindow”,類名命名為“mainWin”。代碼如下(treeView.cpp):樹狀視圖/模型及實例運行程序,如圖。03文件目錄瀏覽器實例文件目錄瀏覽器實例【例】(簡單)(CH903)實現一個簡單的文件目錄瀏覽器,完成效果如圖。以“直接編寫代碼”(即取消勾選“Generateform”復選框)方式創建Qt項目,項目名DirModeEx,“ClassInformation”頁基類選“QMainWindow”。在源文件main.cpp中編寫代碼如下。04自定義模型實例自定義模型實例【例】(難度一般)(CH904)實際應用中,常常將一些重復的文字字段用數值代碼保存,使用時再通過關聯操作(如外鍵)來獲取其真實的內容,此種方法可有效避免數據存儲的冗余。試開發一個通過將數值代碼映射為文字的模型來保存不同軍種的各種武器信息,實現效果如圖。自定義模型實例開發步驟如下。(1)在項目中創建ModelEx類繼承自QAbstractTableModel類,其頭文件modelex.h的代碼如下。(2)在ModelEx類的構造函數(位于源文件modelex.cpp)中編寫代碼如下:#include"modelex.h"ModelEx::ModelEx(QObject*parent):QAbstractTableModel(parent){armyMap[1]="空軍";armyMap[2]="海軍";armyMap[3]="陸軍";armyMap[4]="海軍陸戰隊";weaponTypeMap[1]="轟炸機";weaponTypeMap[2]="戰斗機";weaponTypeMap[3]="航空母艦";weaponTypeMap[4]="驅逐艦";weaponTypeMap[5]="直升機";weaponTypeMap[6]="坦克";weaponTypeMap[7]="兩棲攻擊艦";weaponTypeMap[8]="兩棲戰車";populateModel();}自定義模型實例最后的populateModel()函數完成表格數據的初始化填充,具體實現代碼如下:voidModelEx::populateModel(){header<<"軍種"<<"種類"<<"武器";army<<1<<2<<3<<4<<2<<4<<3<<1;weaponType<<1<<3<<5<<7<<4<<8<<6<<2;weapon<<"B-2"<<"尼米茲級"<<"阿帕奇"<<"黃蜂級"<<"阿利伯克級"<<"AAAV"<<"M1A1"<<"F-22";}自定義模型實例(3)實現父類虛函數用戶自定義的模型類必須實現父類中所有的虛函數,一共4個虛函數,分別實現如下。①虛函數rowCount()返回模型的行數,代碼為:intModelEx::rowCount(constQModelIndex&parent)const{returnarmy.size();}②虛函數columnCount()函數返回模型的列數。因為模型的列固定為3,所以直接返回3:intModelEx::columnCount(constQModelIndex&parent)const{return3;}自定義模型實例③虛函數data()返回指定索引的數據,即將數值映射為文字,代碼如下:QVariantModelEx::data(constQModelIndex&index,introle)const{if(!index.isValid())returnQVariant();if(role==Qt::DisplayRole){switch(index.column()){case0:returnarmyMap[army[index.row()]];break;case1:returnweaponTypeMap[weaponType[index.row()]];break;case2:returnweapon[index.row()];default:returnQVariant();}}returnQVariant();}自定義模型實例見表列出了Item主要的角色及其描述。常
量描
述Qt::DisplayRole顯示文字Qt::DecorationRole繪制裝飾數據(通常是圖標)Qt::EditRole在編輯器中編輯的數據Qt::ToolTipRole工具提示Qt::StatusTipRole狀態欄提示Qt::WhatsThisRoleWhat’sThis文字Qt::SizeHintRole尺寸提示Qt::FontRole默認代理的繪制使用的字體Qt::TextAlignmentRole默認代理的對齊方式Qt::BackgroundRole默認代理的背景畫刷Qt::ForegroundRole默認代理的前景畫刷Qt::CheckStateRole默認代理的檢查框狀態Qt::UserRole用戶自定義數據的起始位置自定義模型實例④虛函數headerData()返回固定的表頭數據,設置水平表頭的標題,具體代碼如下:QVariantModelEx::headerData(intsection,Qt::Orientationorientation,introle)const{if(role==Qt::DisplayRole&&orientation==Qt::Horizontal)returnheader[section];returnQAbstractTableModel::headerData(section,orientation,role);}自定義模型實例(4)最后,在源文件main.cpp中將自定義的模型與表格視圖關聯,代碼如下:#include<QApplication>#include"modelex.h"#include<QTableView>intmain(intargc,char*argv[]){QApplicationa(argc,argv);ModelExmodelEx; //自定義模型QTableViewview; //表格視圖view.setModel(&modelEx);view.setWindowTitle("自定義模型");view.resize(400,400);view.show();returna.exec();}自定義模型實例(5)運行程序,顯示出自定義模型中數據的效果如圖。QT5開發及實例(第5版)第9章Qt5模型/視圖及實例——代理及應用實例01代理概念及開發步驟1.什么是代理2.代理開發步驟代理概念及開發步驟1.什么是代理從前面的實例可見,表格視圖QTableView可以支持用戶對表單元格中的內容進行編輯,但是Qt默認的單元格編輯控件只有文本框(QLineEdit)一種(圖),而實際應用需求是多樣的,可能更適宜采用其他類型的控件來接受用戶輸入,例如,想要限定單元格的內容只能從幾個固定選項中選取,就要用下拉列表框(QComboBox)(圖),Qt的模型/視圖架構通過一種叫做“代理”的機制來實現此類功能。
代理概念及開發步驟2.代理開發步驟(1)創建代理類用QtCreator打開要開發代理的項目,右擊項目名,選“添加新文件...”,彈出對話框選擇新建一個“C++Class”類模板,點“Choose”按鈕,在接下來的向導界面上輸入自定義代理類的名稱及要繼承的代理基類,勾選“AddQ_OBJECT”,如圖9.10所示。代理概念及開發步驟(2)實現代理函數無論是從QItemDelegate還是QStyledItemDelegate類繼承創建的代理類,要實現代理功能,都必須重寫4個基本的函數。先在自定義代理類的頭文件中聲明這4個函數的原型,代碼如下:......#include<QItemDelegate(或QStyledItemDelegate)>#include<代理對應的Qt控件庫>
class自定義代理類:publicQItemDelegate(或QStyledItemDelegate){Q_OBJECTpublic:ComboDelegate(QObject*parent=0);QWidget*createEditor(QWidget*parent,constQStyleOptionViewItem&option,constQModelIndex&index)const; //函數1voidsetEditorData(QWidget*editor,constQModelIndex&index)const; //函數2voidsetModelData(QWidget*editor,QAbstractItemModel*model,constQModelIndex&index)const; //函數3voidupdateEditorGeometry(QWidget*editor,constQStyleOptionViewItem&option,constQModelIndex&index)const; //函數4};......代理概念及開發步驟(3)關聯到視圖開發好代理類后,就可以在界面視圖開發中為表格的任一列設置代理,將控件關聯到這列上的單元格,使用setItemDelegateForColumn函數,語句如下:視圖對象.setItemDelegateForColumn(列號,&代理類對象);其中,列號從0開始,通常在視圖的模型設置setModel函數之后調用這條語句將代理與視圖關聯,這樣就可在所設列的單元格中使用代理類的控件來編輯其內容。02代理應用實例1.開發視圖界面2.實現日歷編輯框3.實現下拉列表框4.實現數字選擇框代理應用實例【例】(難度中等)(CH905)針對如圖的表格視圖數據,開發幾種代理類分別以不同類型的控件編輯表格中不同列的數據內容。代理應用實例以“直接編寫代碼”(即取消勾選“Generateform”復選框)方式創建Qt項目,項目名DateDelegate,“ClassInformation”頁基類選“QMainWindow”。開發步驟如下。1.開發視圖界面(1)在源文件main.cpp中編寫代碼如下。(2)在QtCreator中選擇菜單“構建”→“構建項目"DateDelegate"”項,生成Debug目錄。(3)按照圖的格式編輯本例視圖數據來源的文件test.txt,將其保存到項目Debug目錄下,然后運行程序。代理應用實例2.實現日歷編輯框想要通過手動選擇日期的方式實現對生日的錄入編輯,需要定義一個代理類來實現日歷編輯框QDateTimeEdit,如下。(1)創建代理類在項目中創建一個代理類DateDelegate繼承自QItemDelegate類。(2)實現代理函數在代理類頭文件datedelegate.h中聲明4個代理函數,如下:#include<QItemDelegate>classDateDelegate:publicQItemDelegate{Q_OBJECTpublic:DateDelegate(QObject*parent=0);QWidget*createEditor(QWidget*parent,constQStyleOptionViewItem&option,constQModelIndex&index)const;voidsetEditorData(QWidget*editor,constQModelIndex&index)const;voidsetModelData(QWidget*editor,QAbstractItemModel*model,constQModelIndex&index)const;voidupdateEditorGeometry(QWidget*editor,constQStyleOptionViewItem&option,constQModelIndex&index)const;};代理應用實例在代理類源文件datedelegate.cpp中編寫實現這4個函數的代碼,具體如下。①createEditor()函數的實現代碼:QWidget*DateDelegate::createEditor(QWidget*parent,constQStyleOptionViewItem&/*option*/,constQModelIndex&/*index*/)const{QDateTimeEdit*editor=newQDateTimeEdit(parent); //(a)editor->setDisplayFormat("yyyy-MM-dd"); //(b)editor->setCalendarPopup(true); //(c)editor->installEventFilter(const_cast<DateDelegate*>(this)); //(d)returneditor;}②setEditorData()函數的實現代碼:voidDateDelegate::setEditorData(QWidget*editor,constQModelIndex&index)const{QStringdateStr=index.model()->data(index).toString(); //(a)QDatedate=QDate::fromString(dateStr,Qt::ISODate); //(b)QDateTimeEdit*edit=static_cast<QDateTimeEdit*>(editor); //(c)edit->setDate(date); //設置控件的顯示數據}代理應用實例③setModelData()函數的實現代碼:voidDateDelegate::setModelData(QWidget*editor,QAbstractItemModel*model,constQModelIndex&index)const{QDateTimeEdit*edit=static_cast<QDateTimeEdit*>(editor); //(a)QDatedate=edit->date(); //(b)model->setData(index,QVariant(date.toString(Qt::ISODate))); //(c)} ④updateEditorGeometry()函數的實現代碼:voidDateDelegate::updateEditorGeometry(QWidget*editor,constQStyleOptionViewItem&option,constQModelIndex&index)const{editor->setGeometry(option.rect);}代理應用實例(3)關聯到視圖在main.cpp文件中添加代理類頭文件包含:#include"datedelegate.h"在語句tableView.setModel(&model);后面添加如下代碼:DateDelegatedateDelegate;tableView.setItemDelegateForColumn(1,&dateDelegate);此時運行程序,雙擊表格第2列的任一單元格,將出現如圖的日歷編輯框,可從中選擇修改生日日期。代理應用實例3.實現下拉列表框想要通過下拉列表選擇職業類型,需要定義一個代理類來實現下拉列表框QComboBox,如下。(1)創建代理類在項目中創建一個代理類ComboDelegate繼承自QItemDelegate類。(2)實現代理函數在代理類頭文件combodelegate.h中聲明4個代理函數,如下:#include<QItemDelegate>classComboDelegate:publicQItemDelegate{Q_OBJECTpublic:ComboDelegate(QObject*parent=0);QWidget*createEditor(QWidget*parent,constQStyleOptionViewItem&option,constQModelIndex&index)const;voidsetEditorData(QWidget*editor,constQModelIndex&index)const;voidsetModelData(QWidget*editor,QAbstractItemModel*model,constQModelIndex&index)const;voidupdateEditorGeometry(QWidget*editor,constQStyleOptionViewItem&option,constQModelIndex&index)const;};代理應用實例在代理類源文件combodelegate.cpp中編寫實現這4個函數的代碼,具體如下。①createEditor()函數的實現代碼:QWidget*ComboDelegate::createEditor(QWidget*parent,constQStyleOptionViewItem&/*option*/,constQModelIndex&/*index*/)const{QComboBox*editor=newQComboBox(parent);editor->addItem("工人");editor->addItem("農民");editor->addItem("醫生");editor->addItem("律師");editor->addItem("軍人");editor->installEventFilter(const_cast<ComboDelegate*>(this));returneditor;}代理應用實例②setEditorData()函數的實現代碼:voidComboDelegate::setEditorData(QWidget*editor,constQModelIndex&index)const{QStringstr=index.model()->data(index).toString();QComboBox*box=static_cast<QComboBox*>(editor);inti=box->findText(str);box->setCurrentIndex(i);}代理應用實例③setModelData()函數的實現代碼:voidComboDelegate::setModelData(QWidget*editor,QAbstractItemModel*model,constQModelIndex&index)const{QComboBox*box=static_cast<QComboBox*>(editor);QStringstr=box->currentText();model->setData(index,str);}④updateEditorGeometry()函數的實現代碼:voidComboDelegate::updateEditorGeometry(QWidget*editor,constQStyleOptionViewItem&option,constQModelIndex&/*index*/)const{editor->setGeometry(option.rect);}代理應用實例(3)關聯到視圖在main.cpp文件中添加代理類頭文件包含:#include"combodelegate.h"在語句tableView.setModel(&model);的后面添加以下代碼:ComboDelegatecomboDelegate;tableView.setItemDelegateForColumn(2,&comboDelegate);此時運行程序,雙擊表格第3列的任一單元格,顯示如圖的下拉列表。代理應用實例4.實現數字選擇框想要通過上下箭頭調整最后一列的收入值,需要定義一個代理類來實現數字選擇框QSpinBox,如下。(1)創建代理類在項目中創建一個代理類SpinDelegate繼承自QItemDelegate類。(2)實現代理函數在代理類頭文件spindelegate.h中聲明4個代理函數,如下:#include<QItemDelegate>classSpinDelegate:publicQItemDelegate{Q_OBJECTpublic:SpinDelegate(QObject*parent=0);QWidget*createEditor(QWidget*parent,constQStyleOptionViewItem&option,constQModelIndex&index)const;voidsetEditorData(QWidget*editor,constQModelIndex&index)const;voidsetModelData(QWidget*editor,QAbstractItemModel*model,constQModelIndex&index)const;voidupdateEditorGeometry(QWidget*editor,constQStyleOptionViewItem&option,constQModelIndex&index)const;};代理應用實例在代理類源文件spindelegate.cpp中編寫實現這4個函數的代碼,具體如下。①createEditor()函數的實現代碼:QWidget*SpinDelegate::createEditor(QWidget*parent,constQStyleOptionViewItem&/*option*/,constQModelIndex&/*index*/)const{QSpinBox*editor=newQSpinBox(parent);editor->setRange(0,10000);editor->installEventFilter(const_cast<SpinDelegate*>(this));returneditor;}②setEditorData()函數的實現代碼:voidSpinDelegate::setEditorData(QWidget*editor,constQModelIndex&index)const{intvalue=index.model()->data(index).toInt();QSpinBox*box=static_cast<QSpinBox*>(editor);box->setValue(value);}代理應用實例③setModelData()函數的實現代碼:voidSpinDelegate::setModelData(QWidget*editor,QAbstractItemModel*model,constQModelIndex&index)const{QSpinBox*box=static_cast<QSpinBox*>(editor);intvalue=box->value();model->setData(index,value);}④updateEditorGeometry()函數的實現代碼:voidSpinDelegate::updateEditorGeometry(QWidget*editor,constQStyleOptionViewItem&option,constQModelIndex&/*index*/)const{editor->setGeometry(option.rect);}代理應用實例(3)關聯到視圖在main.cpp文件中添加代理類頭文件包含:#include"spindelegate.h"在語句tableView.setModel(&model);的后面添加內容如下:SpinDelegatespinDelegate;tableView.setItemDelegateForColumn(3,&spinDelegate);此時運行程序,雙擊表格第4列的任一單元格,出現帶箭頭的數字選擇框如圖,可上下翻動調整收入值。QT5開發及實例(第5版)第9章Qt5模型/視圖及實例——綜合實例:汽車信息管理系統綜合實例:汽車信息管理系統【例】(較難)(CH906)開發一個汽車信息管理系統,界面上用多個模型和視圖以主從配合的方式呈現豐富的信息,如圖。01開發前的準備1.安裝MySQL2.創建數據庫3.編譯MySQL驅動開發前的準備1.安裝MySQL從Oracle官網下載MySQL安裝包可執行程序,雙擊啟動向導,按照向導界面指引安裝;或者下載MySQL壓縮包,手動編寫配置文件,通過Windows命令行安裝MySQL服務。2.創建數據庫安裝好MySQL后,再安裝一個可視化操作工具(筆者用的是NavicatPremium),創建數據庫carview,其中創建兩個表:factory(汽車制造商表)和cars(汽車表),并錄入測試用數據。在NavicatPremium中新建一個查詢,通過執行以下SQL語句來完成上述操作:(1)創建factory表、錄入數據:CREATETABLEfactory(idintPRIMARYKEY,manufactoryvarchar(40),addressvarchar(40));INSERTINTOfactoryVALUES(1,'一汽大眾','長春');INSERTINTOfactoryVALUES(2,'二汽神龍','武漢');INSERTINTOfactoryVALUES(3,'上海大眾','上海');開發前的準備(2)創建cars表、錄入數據:CREATETABLEcars(caridintPRIMARYKEY,namevarchar(50),factoryidint,yearint,detailsjsonNULL,FOREIGNKEY(factoryid)REFERENCESfactory(id));INSERTINTOcarsVALUES(1,'奧迪A6',1,2023,null);INSERTINTOcarsVALUES(2,'捷達',1,2011,null);INSERTINTOcarsVALUES(3,'寶來',1,2018,null);INSERTINTOcarsVALUES(4,'畢加索',2,2017,null);INSERTINTOcarsVALUES(5,'富康',2,2022,null);INSERTINTOcarsVALUES(6,'標致307',2,2019,null);INSERTINTOcarsVALUES(7,'桑塔納',3,2013,null);INSERTINTOcarsVALUES(8,'帕薩特',3,2018,null);開發前的準備(3)在cars表JSON字段中錄入車型詳細信息數據:UPDATEcarsSETdetails=JSON_OBJECT("01","排量:2393ml","02","價格:43.26萬元","03","排放:歐4","04","油耗:7.0l(90km/h)8.3l(120km/h)","05","功率:130/6000")WHEREcarid=1;UPDATEcarsSETdetails=JSON_OBJECT("01","排量:1600ml","02","價格:8.98萬元","03","排放:歐3","04","油耗:6.1l(90km/h)","05","功率:68/5800")WHEREcarid=2;UPDATEcarsSETdetails=JSON_OBJECT("01","排量:1600ml","02","價格:11.25萬元","03","排放:歐3帶OBD","04","油耗:6.0l(90km/h)8.1l(120km/h)","05","功率:74/6000")WHEREcarid=3;UPDATEcarsSETdetails=JSON_OBJECT("01","排量:1997ml","02","價格:15.38萬元","03","排放:歐3帶OBD","04","油耗:6.8l(90km/h)","05","功率:99/6000")WHEREcarid=4;UPDATEcarsSETdetails=JSON_OBJECT("01","排量:1600ml","02","價格:6.58萬元","03","排放:歐3","04","油耗:6.5l(90km/h)","05","功率:65/5600")WHEREcarid=5;UPDATEcarsSETdetails=JSON_OBJECT("01","排量:1997ml","02","價格:16.08萬元","03","排放:歐4","04","油耗:7.0l(90km/h)","05","功率:108/6000")WHEREcarid=6;UPDATEcarsSETdetails=JSON_OBJECT("01","排量:1781ml","02","價格:7.98萬元","03","排放:國3","04","油耗:≤7.2l(90km/h)","05","功率:70/5200")WHEREcarid=7;UPDATEcarsSETdetails=JSON_OBJECT("01","排量:1984ml","02","價格:19.58萬元","03","排放:歐4","04","油耗:7.1l(90km/h)","05","功率:85/5400")WHEREcarid=8;3.編譯MySQL驅動如果是初次開發基于MySQL的Qt項目,需要用Qt的源碼工程自行編譯生成MySQL的驅動DLL庫后引入開發環境02開發視圖界面1.聲明界面元素2.布局主界面3.創建界面元素開發視圖界面1.聲明界面元素主窗口MainWindow類繼承自QMainWindow類,在其頭文件mainwindow.h中聲明了主界面上所有要顯示的界面元素及其創建函數,代碼如下:#include<QMainWindow>#include<QGroupBox>#include<QTableView>#include<QListWidget>#include<QLabel>classMainWindow:publicQMainWindow{Q_OBJECTpublic:MainWindow(QWidget*parent=nullptr);~MainWindow();private:QGroupBox*createFactoryGroupBox(); //創建“汽車制造商”視圖組框QGroupBox*createCarGroupBox(); //創建“汽車”視圖組框QGroupBox*createDetailsGroupBox(); //創建“詳細信息”組框voidcreateMenuBar(); //創建操作菜單QTableView*factoryView; //汽車制造商視圖QTableView*carView; //汽車視圖QLabel*profileLabel; //制造商概要信息標簽QLabel*titleLabel; //品牌標簽QListWidget*attribList; //車型詳細信息列表};開發視圖界面2.布局主界面在主窗口源文件mainwindow.cpp中通過編寫代碼來布局汽車信息管理系統的主界面,如下。3.創建界面元素在布局界面的過程中,通過調用函數創建界面元素,調用了以下4個函數。(1)createFactoryGroupBox()函數創建界面左上區域的“汽車制造商”視圖組框,代碼如下:QGroupBox*MainWindow::createFactoryGroupBox(){factoryView=newQTableView; //創建汽車制造商視圖factoryView->setEditTriggers(QAbstractItemView::NoEditTriggers); //禁止用戶編輯汽車制造商視圖factoryView->setSortingEnabled(true);factoryView->setSelectionBehavior(QAbstractItemView::SelectRows);factoryView->setSelectionMode(QAbstractItemView::SingleSelection); //設置視圖選擇模式為單行選擇factoryView->setShowGrid(false); //不顯示網格factoryView->setAlternatingRowColors(true);QGroupBox*box=newQGroupBox("汽車制造商");QGridLayout*layout=newQGridLayout;layout->addWidget(factoryView,0,0); //將視圖添加進組框box->setLayout(layout);returnbox;}開發視圖界面(2)createCarGroupBox()函數創建界面左下區域的“汽車”視圖組框,代碼如下:QGroupBox*MainWindow::createCarGroupBox(){QGroupBox*box=newQGroupBox("汽車");carView=newQTableView; //創建汽車視圖carView->setEditTriggers(QAbstractItemView::NoEditTriggers);carView->setSortingEnabled(true);carView->setSelectionBehavior(QAbstractItemView::SelectRows);carView->setSelectionMode(QAbstractItemView::SingleSelection);carView->setShowGrid(false);carView->verticalHeader()->hide();carView->setAlternatingRowColors(true);QVBoxLayout*layout=newQVBoxLayout;layout->addWidget(carView,0,0); //將視圖添加進組框box->setLayout(layout);returnbox;}開發視圖界面(3)createDetailsGroupBox()函數創建界面右區的“詳細信息”組框,代碼如下:QGroupBox*MainWindow::createDetailsGroupBox(){QGroupBox*box=newQGroupBox("詳細信息");profileLabel=newQLabel; //創建顯示汽車制造商概要信息的標簽profileLabel->setWordWrap(true);profileLabel->setAlignment(Qt::AlignBottom);titleLabel=newQLabel; //創建顯示品牌的標簽titleLabel->setWordWrap(true);titleLabel->setAlignment(Qt::AlignBottom);attribList=newQListWidget; //創建顯示車型詳細信息的列表QGridLayout*layout=newQGridLayout;layout->addWidget(profileLabel,0,0,1,2);layout->addWidget(titleLabel,1,0,1,2);layout->addWidget(attribList,2,0,1,2); //將創建的各界面元素添加進布局layout->setRowStretch(2,1);box->setLayout(layout);returnbox;}開發視圖界面(4)createMenuBar()函數創建系統的操作菜單,本系統的菜單包含“添加”、“刪除”和“退出”三個選項,用于后面往系統中添加和刪除汽車信息以及退出系統,代碼如下:voidMainWindow::createMenuBar(){QAction*addAction=newQAction("添加",this);QAction*deleteAction=newQAction("刪除",this);QAction*quitAction=newQAction("退出",this);addAction->setShortcut(tr("Ctrl+A"));deleteAction->setShortcut(tr("Ctrl+D"));quitAction->setShortcut(tr("Ctrl+Q"));QMenu*fileMenu=menuBar()->addMenu("操作菜單");fileMenu->addAction(addAction);fileMenu->addAction(deleteAction);fileMenu->addSeparator();fileMenu->addAction(quitAction);}開發視圖界面汽車信息管理系統的界面就開發好了,運行程序顯示主界面及菜單效果如圖。02連接數據庫1.添加登錄對話框界面類2.設計登錄對話框界面3.聲明獲取參數及連接函數4.加載可用數據庫驅動5.獲取參數6.建立連接7.啟動登錄對話框連接數據庫本系統用戶是通過如圖的對話框圖形界面配置參數連上數據庫,然后登錄進系統的,下面來開發這個模塊。連接數據庫1.添加登錄對話框界面類(1)右擊項目名,選擇“添加新文件...”,彈出“新建文件”向導對話框,選擇模板“Qt”→“Qt設計師界面類”條目項,如圖,單擊“Choose...”按鈕。連接數據庫(2)接下來在如圖的界面上,選擇“DialogwithoutButtons”界面模板,單擊“下一步”按鈕。連接數據庫(3)在“選擇類名”界面上將登錄對話框的類名(Classname)命名為ConnDlg,在下方的幾欄分別命名與其相關的程序文件:頭文件(Headerfile)名為connectdlg.h、源文件(Sourcefile)名為connectdlg.cpp、界面文件(Formfile)名為connectdlg.ui,如圖,單擊“下一步”按鈕,最后單擊“完成”按鈕。連接數據庫2.設計登錄對話框界面登錄對話框界面采用QtCreator的可視化方式進行設計。在開發環境項目樹形視圖中雙擊“Forms”節點下的界面文件connectdlg.ui,進入到QtDesigner設計環境,往設計區窗體上拖曳添加如圖的控件并布局整齊。連接數據庫各控件的屬性見表。類名
稱文
本類名
稱文
本QGroupBoxconnGroupBox數據庫連接設置
QLabeltextLabel2驅動:QComboBoxcomboDriver
QLabeltextLabel3數據庫名:QLineEditeditDatabasecarviewQLabeltextLabel4用戶名:QLineEditeditUsernamerootQLabeltextLabel4_2密碼:QLineEditeditPassword123456QLabeltextLabel5主機名:QLineEditeditHostnamelocalhostQLabeltextLabel5_2端口:QSpinBoxportSpinBox3306QLabeltextLabel1狀態:QLabellabelStatus
QPushButtonokButton連接QPushButtoncancelButton退出連接數據庫3.聲明獲取參數及連接函數ConnDlg類繼承自QDialog類,它的主要功能是從登錄對話框界面上獲取用戶所設置的各項連接參數,然后以這些參數值來建立數據庫連接。在ConnDlg類的頭文件connectdlg.h中聲明了這些獲取參數及建立連接的函數,如下。4.加載可用數據庫驅動(1)在項目的配置文件MyC中添加一句:QT+=sql連接數據庫(2)在源文件connectdlg.cpp中,ConnDlg類的構造函數在初始化UI界面的時候查找當前Qt系統中所有可用的數據庫驅動,將它們載入界面上的驅動組合框中,代碼如下:#include"connectdlg.h"#include"ui_connectdlg.h"#include<QSqlDatabase>#include<QtSql>ConnDlg::ConnDlg(QWidget*parent):QDialog(parent),ui(newUi::ConnDlg){ui->setupUi(this);QStringListdrivers=QSqlDatabase::drivers(); //(a)ui->comboDriver->addItem("");ui->comboDriver->addItems(drivers); //(b)ui->comboDriver->clearEditText();ui->labelStatus->setText("準備連接..."); //(c)}連接數據庫5.獲取參數在源文件connectdlg.cpp中編寫前面聲明的用于獲取參數的各個函數(driverName()、databaseName()、userName()、password()、hostName()、port()),代碼如下:6.建立連接當用戶設置完參數單擊“連接”按鈕時,系統會自動執行登錄對話框的on_okButton_clicked()槽函數,編寫其代碼如下:voidConnDlg::on_okButton_clicked(){if(ui->comboDriver->currentText().isEmpty()) //(a){ui->labelStatus->setText("請選擇一個數據庫驅動!");ui->comboDriver->setFocus();}else{QSqlErrorerr=addConnection(driverName(),databaseName(),userName(),password(),hostName(),port()); //(b)if(err.type()!=QSqlError::NoError) //(c){ui->labelStatus->setText(err.text());}else{ //(d)ui->labelStatus->setText("連接成功!");accept();}}}連接數據庫addConnection()函數用來建立一條數據庫連接,其具體實現代碼如下:QSqlErrorConnDlg::addConnection(constQString&driver,constQString&dbName,constQString&user,constQString&passwd,constQString&host,intport){QSqlErrorerr;QSqlDatabasedb=QSqlDatabase::addDatabase(driver);db.setDatabaseName(dbName);db.setHostName(host);db.setPort(port);if(!db.open(user,passwd)){err=db.lastError();}returnerr;}連接數據庫7.啟動登錄對話框登錄對話框是必須在程序運行一開始就首先啟動的界面,只有成功連上了數據庫才能接著訪問汽車信息管理系統的主界面,否則無法進入系統。為了在一開始首先啟動登錄對話框,需要修改項目入口文件main.cpp的代碼如下:#include"mainwindow.h"#include<QApplication>#include<QDialog>#include"connectdlg.h"intmain(intargc,char*argv[]){QApplicationa(argc,argv);ConnDlgdialog;if(dialog.exec()!=QDialog::Accepted)return-1;dialog.show();MainWindoww;w.show();returna.exec();}連接數據庫啟動程序,出現登錄對話框,由于本例使用的后臺數據庫是MySQL,所以在第一欄驅動組合框中選擇Qt的MySQL驅動“QMYSQL”,如圖。03開發主/從視圖1.創建和加載模型數據2.實現主從視圖聯動3.顯示汽車詳細信息4.關聯模型/視圖、信號/槽開發主/從視圖首先,在頭文件mainwindow.h中添加如下幾部分代碼。(1)包含要用的庫:#include<QSqlTableModel>#include<QSqlRelationalTableModel>#include<QModelIndex>#include<QJsonObject>#include<QJsonDocument>(2)聲明槽函數:privateslots:voidchangeFactory(QModelIndexindex);voidshowFactorytProfile(QModelIndexindex);voidshowCarDetails(QModelIndexindex);(3)定義模型及聲明私有函數:private:QSqlTableModel*factoryModel;QSqlRelationalTableModel*carModel;voidloadModel();QModelIndexindexOfFactory(constQString&factory);開發主/從視圖1.創建和加載模型數據在源文件mainwindow.cpp構造函數中添加如下代碼:#include<QMessageBox>#include<QSqlRecord>MainWindow::MainWindow(QWidget*parent):QMainWindow(parent){factoryModel=newQSqlTableModel(this); //(a)carModel=newQSqlRelationalTableModel(this); //(b)loadModel(); //(c)......}開發主/從視圖說明:(a)factoryModel=newQSqlTableModel(this):為汽車制造商表factory創建一個QSqlTableModel模型。(b)carModel=newQSqlRelationalTableModel(this):為汽車表cars創建一個QSqlRelationalTableModel模型。(c)loadModel():這個函數用來加載模型數據,由于同樣的加載操作在程序其他地方也會用到,故封裝為一個函數,此函數代碼如下:voidMainWindow::loadModel(){factoryModel->setTable("factory");factoryModel-
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經權益所有人同意不得將文件中的內容挪作商業或盈利用途。
- 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
- 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 《茶壺》的讀后感
- 2022年北京冬奧會閉幕式觀后感
- 海水(咸水)淡化工程規劃設計方案
- 供水管道換新改造項目可行性研究報告
- 幼兒故事文字排版設計
- 女性服裝設計
- 山西省朔州市懷仁市第九中學高中部2023-2024學年高一上學期11月期中物理含解析
- 心理常識思維導圖設計
- 大理護理職業學院《基礎筆譯》2023-2024學年第二學期期末試卷
- 吉林建筑大學《俄語口譯》2023-2024學年第二學期期末試卷
- 水文學試題題庫及答案
- 2025天津東疆綜合保稅區管理委員會招聘10人筆試參考題庫附帶答案詳解
- 法院書記員招聘2023年筆試考試必做題有答案
- 2024年北京大興國際機場臨空經濟區幼兒園招聘教師考試真題
- (三模)烏魯木齊地區2025年高三年級第三次質量監測理科綜合試卷(含答案)
- 《刑法學課件 》課件各章節內容-第十章 共同犯罪
- 2025神農科技集團有限公司第一批校園招聘17人(山西)筆試參考題庫附帶答案詳解
- 【北京市人社局】2025年北京市人力資源市場薪酬數據報告(一季度)
- 安裝噴泉設備采購合同協議
- 2025年鐵路車輛鉗工(技師)職業技能鑒定考試題庫(含答案)
- 新生兒重度窒息討論制度
評論
0/150
提交評論