qstandarditemmodel 是標準的以項數據為單位的基于m/v模型的一種標準數據管理方式,model/view 是qt中的一種數據編排結構,其中model代表模型,view代表視圖,視圖是顯示和編輯數據的界面組件,而模型則是視圖與原始數據之間的接口,通常該類結構都是用在數據庫中較多,例如模型結構負責讀取或寫入數據庫,視圖結構則負責展示數據,其條理清晰,編寫代碼便于維護。
qstandarditemmodel組件通常會配合tableview
組件一起使用,當數據庫或文本中的記錄發生變化時會自動同步到組件中,首先繪制ui界面。
其次綁定頂部toolbar
菜單,分別對菜單增加對應的功能屬性的描述等。
初始化構造函數: 當程序運行時,我們需要對頁面中的控件逐一初始化,并將table表格與模型通過調用ui->tableview->setmodel(model)
進行綁定。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
|
#include "mainwindow.h" #include "ui_mainwindow.h" #include <iostream> #include <qlabel> #include <qstandarditem> #include <qitemselectionmodel> #include <qfiledialog> #include <qtextstream> #include <qlist> // 默認構造函數 // https://www.cnblogs.com/lyshark mainwindow::mainwindow(qwidget *parent): qmainwindow(parent), ui( new ui::mainwindow) { ui->setupui( this ); // 初始化部分 model = new qstandarditemmodel(3,fixedcolumncount, this ); // 數據模型初始化 selection = new qitemselectionmodel(model); // item選擇模型 // 為tableview設置數據模型 ui->tableview->setmodel(model); // 設置數據模型 ui->tableview->setselectionmodel(selection); // 設置選擇模型 // 默認禁用所有action選項,只保留打開 ui->actionsave->setenabled( false ); ui->actionview->setenabled( false ); ui->actionappend->setenabled( false ); ui->actiondelete->setenabled( false ); ui->actioninsert->setenabled( false ); // 創建狀態欄組件,主要來顯示單元格位置 labcurfile = new qlabel( "當前文件:" , this ); labcurfile->setminimumwidth(200); labcellpos = new qlabel( "當前單元格:" , this ); labcellpos->setminimumwidth(180); labcellpos->setalignment(qt::alignhcenter); labcelltext = new qlabel( "單元格內容:" , this ); labcelltext->setminimumwidth(150); ui->statusbar->addwidget(labcurfile); ui->statusbar->addwidget(labcellpos); ui->statusbar->addwidget(labcelltext); //選擇當前單元格變化時的信號與槽 connect(selection, signal (currentchanged(qmodelindex,qmodelindex)), this ,slot(on_currentchanged(qmodelindex,qmodelindex))); } mainwindow::~mainwindow() { delete ui; } |
初始化時同時需要綁定一個on_currentchanged(qmodelindex,qmodelindex)
信號,當用戶選中指定單元格時相應用戶。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
// 選擇單元格變化時的響應,通過在構造函數中綁定信號和槽函數實現觸發 // https://www.cnblogs.com/lyshark void mainwindow::on_currentchanged( const qmodelindex &current, const qmodelindex &previous) { q_unused(previous); if (current.isvalid()) //當前模型索引有效 { labcellpos->settext(qstring::asprintf( "當前單元格:%d行,%d列" ,current.row(),current.column())); //顯示模型索引的行和列號 qstandarditem *aitem; aitem=model->itemfromindex(current); //從模型索引獲得item this ->labcelltext->settext( "單元格內容:" +aitem->text()); //顯示item的文字內容 } } |
當頁面被初始化時,默認界面如下:
打開并填充組件: 當工具欄中打開文件被點擊后則觸發,打開文件時通過afile.open
打開,循環讀入文件,并將文件中的內容逐行追加到qstringlist ffilecontent
中,當追加完畢后,直接調用inimodelfromstringlist(ffilecontent);
完成對頁面tableview組件的初始化,并設置其他控件狀態為可點擊。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
|
void mainwindow::on_actionopen_triggered() { qstring curpath=qcoreapplication::applicationdirpath(); // 獲取應用程序的路徑 // 調用打開文件對話框打開一個文件 // https://www.cnblogs.com/lyshark qstring afilename=qfiledialog::getopenfilename( this , "打開一個文件" ,curpath, "數據文件(*.txt);;所有文件(*.*)" ); if (afilename.isempty()) { return ; // 如果未選擇文件則退出 } qstringlist ffilecontent; // 文件內容字符串列表 qfile afile(afilename); // 以文件方式讀出 if (afile.open(qiodevice::readonly | qiodevice::text)) // 以只讀文本方式打開文件 { qtextstream astream(&afile); // 用文本流讀取文件 ui->plaintextedit->clear(); // 清空列表 // 循環讀取只要不為空 while (!astream.atend()) { qstring str=astream.readline(); // 讀取文件的一行 ui->plaintextedit->appendplaintext(str); // 添加到文本框顯示 ffilecontent.append(str); // 添加到stringlist } afile.close(); // 關閉文件 inimodelfromstringlist(ffilecontent); // 從stringlist的內容初始化數據模型 } // 打開文件完成后,就可以將action全部開啟了 ui->actionsave->setenabled( true ); ui->actionview->setenabled( true ); ui->actionappend->setenabled( true ); ui->actiondelete->setenabled( true ); ui->actioninsert->setenabled( true ); // 打開文件成功后,設置狀態欄當前文件列 this ->labcurfile->settext( "當前文件:" +afilename); //狀態欄顯示 } |
如上inimodelfromstringlist(ffilecontent);
函數是后期增加的,我們需要自己實現,該函數的作用是從傳入的stringlist
中獲取數據,并將數據初始化到tableview
模型中,實現代碼如下。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
|
void mainwindow::inimodelfromstringlist(qstringlist& afilecontent) { int rowcnt=afilecontent.count(); // 文本行數,第1行是標題 model->setrowcount(rowcnt-1); // 實際數據行數,要在標題上減去1 // 設置表頭 qstring header=afilecontent.at(0); // 第1行是表頭 // 一個或多個空格、tab等分隔符隔開的字符串、分解為一個stringlist // https://www.cnblogs.com/lyshark qstringlist headerlist=header.split(qregexp( "\\s+" ),qstring::skipemptyparts); model->sethorizontalheaderlabels(headerlist); // 設置表頭文字 // 設置表格中的數據 int x = 0,y = 0; qstandarditem *item; // 有多少列數據就循環多少次 // https://www.cnblogs.com/lyshark for (x=1; x < rowcnt; x++) { qstring linetext = afilecontent.at(x); // 獲取數據區的一行 // 一個或多個空格、tab等分隔符隔開的字符串、分解為一個stringlist qstringlist tmplist=linetext.split(qregexp( "\\s+" ),qstring::skipemptyparts); // 循環列數,也就是循環fixedcolumncount,其中tmplist中的內容也是. for (y=0; y < fixedcolumncount-1; y++) { item = new qstandarditem(tmplist.at(y)); // 創建item model->setitem(x-1,y,item); // 為模型的某個行列位置設置item } // 最后一個數據需要取出來判斷,并單獨設置狀態 item= new qstandarditem(headerlist.at(y)); // 最后一列是checkable,需要設置 item->setcheckable( true ); // 設置為checkable // 判斷最后一個數值是否為0 if (tmplist.at(y) == "0" ) item->setcheckstate(qt::unchecked); // 根據數據設置check狀態 else item->setcheckstate(qt::checked); model->setitem(x-1,y,item); //為模型的某個行列位置設置item } } |
初始化組件后效果如下:
實現添加一行數據: 為tableview添加一行數據,在文件末尾插入。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
|
void mainwindow::on_actionappend_triggered() { qlist<qstandarditem *> itemlist; // 創建臨時容器 qstandarditem *item; // 模擬添加一列的數據 for ( int x=0; x<fixedcolumncount-1; x++) { item = new qstandarditem( "測試(追加行)" ); // 循環創建每一列 itemlist << item; // 添加到鏈表中 } // 創建最后一個列元素,由于是選擇框所以需要單獨創建 // https://www.cnblogs.com/lyshark // 1.獲取到最后一列的表頭下標,最后下標為6 qstring str = model->headerdata(model->columncount()-1,qt::horizontal,qt::displayrole).tostring(); item= new qstandarditem(str); // 創建 "是否合格" 字段 item->setcheckable( true ); // 設置狀態為真 itemlist << item; // 最后一個選項追加進去 model->insertrow(model->rowcount(),itemlist); // 插入一行,需要每個cell的item qmodelindex curindex=model->index(model->rowcount()-1,0); // 創建最后一行的modelindex selection->clearselection(); // 清空當前選中項 selection->setcurrentindex(curindex,qitemselectionmodel::select); // 設置當前選中項為當前選擇行 } |
插入代碼演示效果:
實現插入一行數據: 為tableview插入一行數據(在文件任意位置插入數據)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
// https://www.cnblogs.com/lyshark void mainwindow::on_actioninsert_triggered() { qlist<qstandarditem*> itemlist; // qstandarditem的列表類 qstandarditem *item; // 模擬插入前五列數據 for ( int i=0;i<fixedcolumncount-1;i++) { item= new qstandarditem( "測試(插入行)" ); // 新建一個qstandarditem itemlist << item; // 添加到列表類 } qstring str; // 獲取表頭文字 str=model->headerdata(model->columncount()-1,qt::horizontal,qt::displayrole).tostring(); item= new qstandarditem(str); // 創建item item->setcheckable( true ); // 設置為可使用checkbox itemlist<<item; // 添加到列表類 qmodelindex curindex=selection->currentindex(); // 獲取當前選中項的索引 model->insertrow(curindex.row(),itemlist); // 在當前行的前面插入一行 selection->clearselection(); // 清除當前選中項 selection->setcurrentindex(curindex,qitemselectionmodel::select); // 設置當前選中項為當前選擇行 } |
插入代碼演示效果:
實現刪除一行數據: 刪除數據之前需要通過selection->currentindex()
確定當前選中行,并通過model->removerow()
移除即可。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
// https://www.cnblogs.com/lyshark void mainwindow::on_actiondelete_triggered() { qmodelindex curindex = selection->currentindex(); // 獲取當前選擇單元格的模型索引 // 先判斷是不是最后一行 if (curindex.row()==model->rowcount()-1) { model->removerow(curindex.row()); //刪除最后一行 } else { model->removerow(curindex.row()); //刪除一行,并重新設置當前選擇行 selection->setcurrentindex(curindex,qitemselectionmodel::select); } }<br> |
刪除代碼效果演示:
實現字體數據對齊: 表格中的字體可以實現多種對其方式,對齊方式分為 居中對齊,左對齊,右對齊 三種。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
|
// 設置表格居中對齊 void mainwindow::on_pushbutton_clicked() { if (!selection->hasselection()) return ; qmodelindexlist selectedindex=selection->selectedindexes(); qmodelindex index; qstandarditem *item; for ( int i=0; i<selectedindex.count(); i++) { index=selectedindex.at(i); item=model->itemfromindex(index); item->settextalignment(qt::alignhcenter); } } // 設置表格左對齊 // https://www.cnblogs.com/lyshark void mainwindow::on_pushbutton_2_clicked() { if (!selection->hasselection()) //沒有選擇的項 return ; //獲取選擇的單元格的模型索引列表,可以是多選 qmodelindexlist selectedindex=selection->selectedindexes(); for ( int i=0;i<selectedindex.count();i++) { qmodelindex aindex=selectedindex.at(i); //獲取其中的一個模型索引 qstandarditem* aitem=model->itemfromindex(aindex); //獲取一個單元格的項數據對象 aitem->settextalignment(qt::alignleft); //設置文字對齊方式 } } // 設置表格右對齊 void mainwindow::on_pushbutton_3_clicked() { if (!selection->hasselection()) return ; qmodelindexlist selectedindex=selection->selectedindexes(); qmodelindex aindex; qstandarditem *aitem; for ( int i=0;i<selectedindex.count();i++) { aindex=selectedindex.at(i); aitem=model->itemfromindex(aindex); aitem->settextalignment(qt::alignright); } } |
對齊代碼效果演示:
實現字體數據加粗: 將選中行的字體進行加粗顯示。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
// 設置字體加粗顯示 // https://www.cnblogs.com/lyshark void mainwindow::on_pushbutton_4_clicked() { if (!selection->hasselection()) return ; //獲取選擇單元格的模型索引列表 qmodelindexlist selectedindex=selection->selectedindexes(); for ( int i=0;i<selectedindex.count();i++) { qmodelindex aindex=selectedindex.at(i); //獲取一個模型索引 qstandarditem* aitem=model->itemfromindex(aindex); //獲取項數據 qfont font=aitem->font(); //獲取字體 font.setbold( true ); //設置字體是否粗體 aitem->setfont(font); //重新設置字體 } |
加粗代碼效果演示:
實現保存文件: 當保存文件被點擊后觸發,通過便利tablewidget模型組件中的數據,并將數據通過astream << str << "\n";
寫出到記事本中。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
|
// https://www.cnblogs.com/lyshark // 【保存文件】 void mainwindow::on_actionsave_triggered() { qstring curpath=qcoreapplication::applicationdirpath(); // 獲取應用程序的路徑 // 調用打開文件對話框選擇一個文件 qstring afilename=qfiledialog::getsavefilename( this ,tr( "選擇一個文件" ),curpath, "數據文件(*.txt);;所有文件(*.*)" ); if (afilename.isempty()) // 未選擇文件則直接退出 return ; qfile afile(afilename); // 以讀寫、覆蓋原有內容方式打開文件 if (!(afile.open(qiodevice::readwrite | qiodevice::text | qiodevice::truncate))) return ; qtextstream astream(&afile); // 用文本流讀取文件 qstandarditem *item; qstring str; int x = 0,y = 0; ui->plaintextedit->clear(); // 獲取表頭文字 for (x=0; x<model->columncount(); x++) { item=model->horizontalheaderitem(x); // 獲取表頭的項數據 str= str + item->text() + "\t\t" ; // 以tab制表符隔開 } astream << str << "\n" ; // 文件里需要加入換行符\n ui->plaintextedit->appendplaintext(str); // 獲取數據區文字 for ( x=0; x < model->rowcount(); x++) { str = "" ; for ( y=0; y < model->columncount()-1; y++) { item=model->item(x,y); str=str + item->text() + qstring::asprintf( "\t\t" ); } // 對最后一列需要轉換一下,如果判斷為選中則寫1否則寫0 item=model->item(x,y); if (item->checkstate()==qt::checked) str= str + "1" ; else str= str + "0" ; ui->plaintextedit->appendplaintext(str); astream << str << "\n" ; } } // 【導出txt文件】:將tableview中的數據導出到plaintextedit顯示 void mainwindow::on_actionview_triggered() { ui->plaintextedit->clear(); qstandarditem *item; qstring str; //獲取表頭文字 int x=0,y=0; for (x=0; x<model->columncount(); x++) { // item=model->horizontalheaderitem(x); str= str + item->text() + "\t" ; } ui->plaintextedit->appendplaintext(str); //獲取數據區的每行 for (x=0; x<model->rowcount(); x++) { str= "" ; for (y=0; y<model->columncount()-1; y++) { item=model->item(x,y); str= str + item->text() + qstring::asprintf( "\t" ); } item=model->item(x,y); if (item->checkstate()==qt::checked) str= str + "1" ; else str= str + "0" ; ui->plaintextedit->appendplaintext(str); } } |
文件保存后如下:
到此這篇關于c/c++中的 qt standarditemmodel 數據模型應用解析的文章就介紹到這了,更多相關c++ qt standarditemmodel 數據模型內容請搜索服務器之家以前的文章或繼續瀏覽下面的相關文章希望大家以后多多支持服務器之家!
原文鏈接:https://www.cnblogs.com/LyShark/p/15637813.html