模型視圖結(jié)構(gòu)_第1頁
模型視圖結(jié)構(gòu)_第2頁
模型視圖結(jié)構(gòu)_第3頁
模型視圖結(jié)構(gòu)_第4頁
模型視圖結(jié)構(gòu)_第5頁
已閱讀5頁,還剩10頁未讀 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡(jiǎn)介

1/1模型視圖結(jié)構(gòu)Qt之模型/視圖

(2014-01-0815:48:01)

轉(zhuǎn)載▼

標(biāo)簽:

分類:Qt

qt

qt使用mvc

qtableview

qlistview

qtreeview

關(guān)于Qt中MVC的介紹與使用,助手中有一節(jié)模型/視圖編程

(Model/ViewProgramming)講解的很清晰。

Qt包含一組使用模型/視圖結(jié)構(gòu)的類,可以用來管理數(shù)據(jù)并呈現(xiàn)給用戶。這種體系結(jié)構(gòu)引入的分離使開發(fā)人員更靈活地定制項(xiàng)目,并且提供了一個(gè)標(biāo)準(zhǔn)模型的接口,以允許廣泛范圍的數(shù)據(jù)源被使用到到現(xiàn)有的視圖中。

模型-視圖-控制器(MVC)是一種設(shè)計(jì)模式,由三類對(duì)象組成:

?模型:應(yīng)用程序?qū)ο蟆?/p>

?視圖:屏幕演示。

?控制器:定義了用戶界面響應(yīng)用戶輸入的方式。

在引入MVC之前,用戶界面的設(shè)計(jì)往往是將這些對(duì)象組合在一起。MVC的解耦帶來了靈活性和重用性。

如果視圖和控制器對(duì)象相結(jié)合,其結(jié)果是模型/視圖結(jié)構(gòu),仍然分離了數(shù)據(jù)與呈現(xiàn)給用戶的方式,但提供了基于相同原理的簡(jiǎn)單框架。這種分離使得它可以在幾個(gè)不同的視圖中顯示相同的數(shù)據(jù),并且實(shí)現(xiàn)新類型的視圖,

而無需改變底層的數(shù)據(jù)結(jié)構(gòu)。為了靈活地處理用戶輸入,則引入了委托的概念。在此框架引入委托的優(yōu)點(diǎn)是:它允許項(xiàng)目數(shù)據(jù)顯示和自定義編輯。

模型/視圖結(jié)構(gòu)

模型與數(shù)據(jù)源進(jìn)行通信,在這個(gè)體系結(jié)構(gòu)中為其它組件提供了一個(gè)接口。通信的性質(zhì)依賴于數(shù)據(jù)源的類型以及模型的實(shí)現(xiàn)方式。

視圖從模型中得到模型索引,這些都引用到數(shù)據(jù)項(xiàng)。通過為模型提供模型索引,視圖可以從數(shù)據(jù)源中檢索數(shù)據(jù)項(xiàng)。

在標(biāo)準(zhǔn)的視圖里,委托呈現(xiàn)數(shù)據(jù)項(xiàng)目。當(dāng)一個(gè)項(xiàng)目被編輯,委托與模型直接利用模型索引進(jìn)行通信。

模型/視圖/委托通信

模型、視圖、委托使用信號(hào)和槽相互通信:

?模型的信號(hào):通知視圖關(guān)于改變由數(shù)據(jù)源保持的數(shù)據(jù)。

?視圖的信號(hào):提供了關(guān)于用戶交互顯示的項(xiàng)目信息。

?委托的信號(hào):當(dāng)編輯時(shí)告訴模型和視圖編輯器的狀態(tài)。

模型

所有的模型都基于QAbstractItemModel類。這個(gè)類定義了一個(gè)使用視圖和委托來訪問數(shù)據(jù)的接口。數(shù)據(jù)本身不是必須要存儲(chǔ)在模型中,可以在一個(gè)數(shù)據(jù)結(jié)構(gòu)或一個(gè)單獨(dú)的類、文件、數(shù)據(jù)庫、或其它一些應(yīng)用組件。

QAbstractItemModel為數(shù)據(jù)提供了一個(gè)接口,它足夠的靈活性來處理表格、列表、樹形式的數(shù)據(jù)視圖。然而,實(shí)現(xiàn)新的列表和類似于表的數(shù)據(jù)結(jié)構(gòu)模型時(shí),QAbstractListModel和QAbstractTableModel類是更好的起點(diǎn),因?yàn)樗鼈兲峁┝诉m當(dāng)?shù)某S玫墓δ艿哪J(rèn)實(shí)現(xiàn)。這些類可以派生子類,用來提供支持特定種類的列表和表格的模型。

Qt提供了一些現(xiàn)成的模型,可以用來處理數(shù)據(jù)項(xiàng):

?QStringListModel:用于存儲(chǔ)簡(jiǎn)單的QString的列表項(xiàng)。

?QStandardItemModel:管理更復(fù)雜的樹結(jié)構(gòu)件,其中每一個(gè)項(xiàng)目可以包含任意數(shù)據(jù)。

?QFileSystemModel:提供有關(guān)本地文件系統(tǒng)的文件和目錄信息。

?QSqlQueryModel、QSqlTableModel、QSqlRelationalTableModel:使用模型/視圖約定來訪問數(shù)據(jù)庫。

如果這些標(biāo)準(zhǔn)模型不能滿足要求,則可以繼承化QAbstractItemModel、QAbstractListModel或QAbstractTableModel來創(chuàng)建自定義模型。

視圖

提供了完整的實(shí)現(xiàn)為各種不同的視圖:而QListView顯示項(xiàng)目列表,QTableView中從一個(gè)表模型中顯示數(shù)據(jù),QTreeView則顯示了層次列表的

數(shù)據(jù)模型項(xiàng)目。每個(gè)類是基于QAbstractItemView抽象基類。雖然這些類是準(zhǔn)備使用的實(shí)現(xiàn),他們也可以被子類化,以提供自定義的視圖。

委托

QAbstractItemDelegate在模型/視圖框架中代表抽象的基類。默認(rèn)的委托實(shí)現(xiàn)由QStyledItemDelegate提供,這被Qt的標(biāo)準(zhǔn)視圖用作默認(rèn)的委托。然而,QStyledItemDelegate和QItemDelegate獨(dú)立替代繪畫,且為視圖項(xiàng)提供編輯器。它們之間的區(qū)別在于QStyledItemDelegate使用當(dāng)前樣式來繪制項(xiàng)目。因此,建議實(shí)現(xiàn)自定義委托或當(dāng)與Qt樣式表一起使用時(shí),使用QStyledItemDelegate作為基類。

排序

在模型/視圖結(jié)構(gòu)中有兩種接近的排序方式,選擇哪種方式取決于你的基礎(chǔ)模型。

如果你的模型是可排序的,也就是說,如果重新實(shí)現(xiàn)了QAbstractItemModel::sort()方法,QTableView和QTreeView都提供了一個(gè)API,允許以編程方式排序來排序模型數(shù)據(jù)。此外,可以啟用交互式排序(即允許用戶將數(shù)據(jù)通過單擊視圖的標(biāo)題進(jìn)行排序),由QHeaderView::sortIndicatorChanged()信號(hào)分別連接到QTableView::sortByColumn()槽或QTreeView::sortByColumn()槽。

另一種方法,如果模型沒有所需的接口,或者如果想使用一個(gè)列表視圖來顯示數(shù)據(jù),使用代理模型呈現(xiàn)數(shù)據(jù)視圖之前應(yīng)轉(zhuǎn)換模型的結(jié)構(gòu)。

方便的類

一些便利類都源于標(biāo)準(zhǔn)視圖類的依賴Qt的項(xiàng)目為基礎(chǔ)的項(xiàng)目視圖和表類應(yīng)用的好處。他們不打算被繼承。

這些類的實(shí)例包括QListWidget,QTreeWidget和QTableWidget。

這些類比視圖類靈活性差,且不能與任意的模型使用。建議使用模型/視圖的方法來處理在項(xiàng)目視圖中的數(shù)據(jù),除非強(qiáng)烈需要一個(gè)基于項(xiàng)目的類。

如果想利用模型/視圖提供的特性方法,同時(shí)使用一個(gè)基于項(xiàng)目的接口,可以考慮使用視圖類,例如:QListView、QTableView、QTreeView與QStandardItemModel。

使用視圖與現(xiàn)有的模型

QListView和QTreeView類是最合適的視圖來使用QFileSystemModel。下面介紹的示例在樹視圖中顯示一個(gè)目錄,旁邊列表視圖中顯示相同的信息。該視圖共享用戶的選擇,這樣選擇的項(xiàng)目在兩個(gè)視圖中高亮顯示。

代碼如下:

intmain(intargc,char*argv[])

{

QApplicationapp(argc,argv);

QSplitter*splitter=newQSplitter;

QFileSystemModel*model=newQFileSystemModel;

model->setRootPath(QDir::currentPath());

QTreeView*tree=newQTreeView(splitter);

tree->setModel(model);

tree->setRootIndex(model->index(QDir::currentPath()));

QListView*list=newQListView(splitter);

list->setModel(model);

list->setRootIndex(model->index(QDir::currentPath()));

splitter->setWindowTitle("Twoviewsontothesamefilesystemmodel");

splitter->show();

returnapp.exec();

}

上面的例子中,我們忽略提及如何處理選擇的項(xiàng)目。下面將詳細(xì)講述在視圖中處理所選的項(xiàng)目。

基本概念

在模型/視圖結(jié)構(gòu)中,模型提供了視圖與委托訪問數(shù)據(jù)的標(biāo)準(zhǔn)接口。在Qt中,標(biāo)準(zhǔn)的接口由QAbstractItemModel類定義。無論多么數(shù)據(jù)項(xiàng)被存儲(chǔ)在任何底層的數(shù)據(jù)結(jié)構(gòu)中,QAbstractItemModel的所有子類所代表的數(shù)據(jù)作為包含視圖項(xiàng)的分層結(jié)構(gòu)。視圖使用這個(gè)約定來訪問模型中的數(shù)據(jù)項(xiàng),但并不限制將該信息傳達(dá)給用戶的方式。

Modelindexes

為確保數(shù)據(jù)被分開被訪問,模型索引的概念被引入??梢酝ㄟ^模型索引來獲得每條信息。視圖與委托使用這些索引來請(qǐng)求顯示的數(shù)據(jù)項(xiàng)。

因此,模型只需要知道如何獲取數(shù)據(jù),并通過模型管理的數(shù)據(jù)的類型可以被相當(dāng)普遍定義。型號(hào)索引包含一個(gè)指向創(chuàng)建它們的模型的指針,在處理多個(gè)模型時(shí)可以防止混亂。

QAbstractItemModel*model=index.model();

模型索引提供臨時(shí)參考信息,并且可以用于通過模型來檢索或修改數(shù)據(jù)。由于模型可能重組其內(nèi)部結(jié)構(gòu),模型的索引可能會(huì)變得無效,不宜存儲(chǔ)。如果需要長期參考一條信息,必須創(chuàng)建一個(gè)持久性模型索引。這為模型保持最新信息提供了一個(gè)參考。臨時(shí)模型索引由QModelIndex類提供,持久性模型索引由QPersistentModelIndex類提供。

取得對(duì)應(yīng)于數(shù)據(jù)項(xiàng)的模型索引,模型中必須制定三個(gè)屬性:一個(gè)行號(hào)、一個(gè)列號(hào),以及父項(xiàng)的模型索引。

行和列

在最基本的形式中,模型可以被一個(gè)簡(jiǎn)單的表訪問,表項(xiàng)位于行號(hào)和列號(hào),這并不意味著底層數(shù)據(jù)存儲(chǔ)在數(shù)據(jù)結(jié)構(gòu)中,使用行號(hào)和列號(hào)只是一個(gè)慣例,以允許組件相互通信。我們可以通過指定行號(hào)和列號(hào)的模型索引有關(guān)的任何特定信息,通過下面的方式得到項(xiàng)目的索引:

QModelIndexindex=model->index(row,column,...);

模型提供的接口簡(jiǎn)單,單級(jí)的數(shù)據(jù)結(jié)構(gòu)如列表和表格不需要提供任何其他信息。但是,正如上面的代碼所示,當(dāng)獲得一個(gè)模型索引時(shí),我們需要提供更多的信息。

行和列

圖中顯示了一個(gè)基本的表模型,其中的每個(gè)項(xiàng)目的位置由一對(duì)行號(hào)和列號(hào)表示。我們通過模型索引(一個(gè)項(xiàng)目數(shù)據(jù))行號(hào)和列號(hào)來獲取。

QModelIndexindexA=model->index(0,0,QModelIndex());

QModelIndexindexB=model->index(1,1,QModelIndex());

QModelIndexindexC=model->index(2,1,QModelIndex());

父節(jié)點(diǎn)

由模型提供的類似于表的接口給數(shù)據(jù)項(xiàng)是理想的當(dāng)在表格或列表視圖中使用數(shù)據(jù),行號(hào)和列號(hào)準(zhǔn)確地映射到視圖顯示項(xiàng)目的方式。然而,結(jié)構(gòu),如樹視圖需要更模型為項(xiàng)目暴露一個(gè)更靈活的接口。因此,每個(gè)項(xiàng)目也可以是另一個(gè)表的父項(xiàng),大致相同的方式,在一個(gè)樹視圖中的頂級(jí)項(xiàng)目可以包含另一個(gè)列表項(xiàng)。

當(dāng)請(qǐng)求的一個(gè)模型項(xiàng)的索引時(shí),必須提供有關(guān)該項(xiàng)目的父項(xiàng)目的一些信息。在模型外,指定一個(gè)項(xiàng)目的唯一途徑是通過一個(gè)模型索引,所以父模型索引也必須如下給出:

QModelIndexindex=model->index(row,column,parent);

父項(xiàng),行和列

該圖顯示了一個(gè)樹模型,其中每個(gè)項(xiàng)目都依賴于由一個(gè)父項(xiàng),一個(gè)行號(hào)和一個(gè)列號(hào)。

項(xiàng)目的“A”和“C”表示模型頂層的兄弟姐妹:

項(xiàng)目“A”有很多孩子,可以通過如下方式由“A”索引得到“B”索引:QModelIndexindexB=model->index(1,0,indexA);

QModelIndexindexA=model->index(0,0,QModelIndex());

QModelIndexindexC=model->index(2,1,QModelIndex());

項(xiàng)目角色

模型中的項(xiàng)目可以為其他組件演繹不同的角色,允許為不同的情況提供不同類型的數(shù)據(jù)。例如,Qt::DisplayRole可以在用于訪問視圖中被顯示為文本的字符串。通常情況下,包含數(shù)據(jù)的項(xiàng)目用于若干不同的角色,且標(biāo)準(zhǔn)角色被Qt::ItemDataRole定義。

我們可以通過模型索引傳遞給相應(yīng)的項(xiàng)目向模型請(qǐng)求項(xiàng)目數(shù)據(jù),并通過指定一個(gè)角色來獲取想要的數(shù)據(jù)類型,如下:

QVariantvalue=model->data(index,role);

數(shù)據(jù)類型被稱為模型的角色指示器。視圖可以以不同的方式顯示角色,因此,為每個(gè)角色提供相應(yīng)的信息非常重要。

項(xiàng)目數(shù)據(jù)最常見的用途是覆蓋在Qt::ItemDataRole中定義的標(biāo)準(zhǔn)角色。通過為每個(gè)角色提供相應(yīng)的項(xiàng)目數(shù)據(jù),模型可以為視圖和委托提供有關(guān)項(xiàng)目應(yīng)如何呈現(xiàn)給用戶的指示,不同的視圖可以根據(jù)需要來解釋或忽略此信息。此外,也可以為應(yīng)用程序的特定目的而定義附加的角色。

使用模型索引

為了演示如何將數(shù)據(jù)從一個(gè)模型中進(jìn)行檢索,使用模型索引,我們創(chuàng)建了一個(gè)QFileSystemModel,在窗體上沒有視圖以及顯示文件和目錄的名稱。雖然這并不是使用模型的正常方式,它表明模型在處理模型索引上的約定。

我們用以下述方式構(gòu)建了一個(gè)文件系統(tǒng)模型:

QFileSystemModel*model=newQFileSystemModel;

QModelIndexparentIndex=model->index(QDir::currentPath());

intnumRows=model->rowCount(parentIndex);

在這種情況下,我們?cè)O(shè)置了一個(gè)默認(rèn)QFileSystemModel,由該模型使用index()的特定實(shí)現(xiàn)來獲取父索引,使用rowCount()函數(shù)來計(jì)算行號(hào)。

為簡(jiǎn)單起見,我們只關(guān)心模型中的第一列中的項(xiàng)目。我們檢查每一行,依次獲取每一行中的第一個(gè)項(xiàng)目的模型索引,以及讀出所存儲(chǔ)在該模型項(xiàng)目中的數(shù)據(jù)。

for(introw=0;rowindex(row,0,parentIndex);

為了獲得一個(gè)模型索引,我們指定了行號(hào)、列號(hào)(第一列為零),以及所有我們想要的項(xiàng)目的父項(xiàng)目的模型索引。每個(gè)項(xiàng)目中的文本檢索可以使用模型的

data()函數(shù)來獲取。我們指定了模型索引和Qt::DisplayRole來獲取數(shù)據(jù)項(xiàng)中的字符串。

QStringtext=model->data(index,Qt::DisplayRole).toString();

//Displaythetextinawidget.

}

使用模型

我們創(chuàng)建一個(gè)字符串列表模型作為例子,設(shè)置一些數(shù)據(jù),并構(gòu)造一個(gè)視圖來顯示模型的內(nèi)容。這都可以在一個(gè)單一的函數(shù)執(zhí)行:

intmain(intargc,char*argv[])

{

QApplicationapp(argc,argv);

QStringListnumbers;

numberssetModel(model);

視圖正常顯示方式

view->show();

returnapp.exec();

}

視圖展現(xiàn)模型的內(nèi)容,通過模型的接口訪問數(shù)據(jù)。當(dāng)用戶試圖編輯一個(gè)項(xiàng)目時(shí),視圖使用缺省代表提供一個(gè)編輯器部件。

上面的圖顯示QListView如何使用字符串列表模型表示數(shù)據(jù)。由于模型可編輯,視圖會(huì)自動(dòng)允許列表中的每個(gè)項(xiàng)目使用默認(rèn)的委托進(jìn)行編輯。

一個(gè)模型的多個(gè)視圖

一個(gè)模型可以為多個(gè)視圖所使用。在下面的代碼中,我們創(chuàng)建兩個(gè)表視圖,使用的均是創(chuàng)建好的同一個(gè)模型。

QTableView*firstTableView=newQTableView;

QTableView*secondTableView=newQTableView;

firstTableView->setModel(model);

secondTableView->setModel(model);

在模型/視圖框架中使用信號(hào)和槽是指更改模型可以傳遞給所有相連的視圖,以確保始終可以訪問相同的數(shù)據(jù),而不管所使用的視圖。

上面的圖顯示了統(tǒng)一模型的兩種不同的視圖,每個(gè)都包含了一些選定的項(xiàng)目。盡管模型中的數(shù)據(jù)在視圖顯示一致,每個(gè)視圖維護(hù)它自己的內(nèi)部選擇模型。這在某些情況下有用,但對(duì)于許多應(yīng)用來說,則需要一個(gè)共享的選擇模型。

視圖共享選擇

雖然視圖類提供自己的默認(rèn)選擇模型很方便,但當(dāng)我們使用多個(gè)視圖到同一個(gè)模型時(shí),通常需要所有的模型數(shù)據(jù)和用戶的選擇在所有視圖顯示一致。由于視圖類允許其內(nèi)部選擇模型進(jìn)行更換,那么可以使用如下方式實(shí)現(xiàn)視圖之間的統(tǒng)一:

secondTableView->setSelectionModel(firstTableView->selectionModel());

第二個(gè)視圖給出了第一個(gè)視圖的選擇模型。這兩種視圖現(xiàn)在在同一個(gè)選擇模型進(jìn)行操作,保持了數(shù)據(jù)和所選項(xiàng)目的同步。

Qt之模型/視圖(委托)

(2014-01-0913:58:09)

轉(zhuǎn)載▼

分類:Qt

標(biāo)簽:

qt

qt委托

qlistview委托

qtableview委托

qtreeview委托

概念

不同于模型-視圖-控制器模式,模型/視圖設(shè)計(jì)不包括用于管理與用戶交互的一個(gè)完全獨(dú)立的組件。一般情況,視圖負(fù)責(zé)將模型數(shù)據(jù)呈現(xiàn)給用戶以及處理用戶輸入。為了輸入更加具有靈活性,則由委托來執(zhí)行交互。這些組件提供輸入功能,且在一些視圖中還負(fù)責(zé)渲染個(gè)別項(xiàng)目。控制委托的標(biāo)準(zhǔn)接口在QAbstractItemDelegate類中定義。

委托能夠通過實(shí)現(xiàn)的paint()和sizeHint()函數(shù)來展示它們的內(nèi)容。然而,簡(jiǎn)單基礎(chǔ)部件的委托可以繼承QItemDelegate而不是QAbstractItemDelegate,并使用這些函數(shù)的默認(rèn)實(shí)現(xiàn)。

委托編輯器可以通過使用小工具來管理編輯過程或直接處理事件來實(shí)現(xiàn)。

使用現(xiàn)有委托

Qt提供的標(biāo)準(zhǔn)視圖中使用QItemDelegate提供編輯功能。委托接口的默認(rèn)實(shí)現(xiàn)以一貫風(fēng)格來呈現(xiàn)項(xiàng)目為每個(gè)標(biāo)準(zhǔn)視圖:QListView、QTableView、QTreeView。

所有標(biāo)準(zhǔn)角色由所使用的標(biāo)準(zhǔn)視圖中的默認(rèn)委托處理。

視圖使用委托是由itemDelegate()函數(shù)返回。setItemDelegate()函數(shù)允許你為標(biāo)準(zhǔn)視圖設(shè)定一個(gè)自定義委托,為自定義視圖設(shè)定委托時(shí),有必要使用此功能。

一個(gè)簡(jiǎn)單的委托

這里實(shí)現(xiàn)的委托使用QSpinBox來提供編輯功能,主要用于模型處理整數(shù)。雖然為了這個(gè)目的我們?cè)O(shè)置了一個(gè)自定義的基于整數(shù)的表模型,我們可以很容易地使用QStandardItemModel來代替,因?yàn)樽远x委托控制數(shù)據(jù)輸入。我們構(gòu)造了一個(gè)表視圖來顯示模型的內(nèi)容,可以使用自定義的委托來進(jìn)行編輯。

我們的委托繼承于QItemDelegate,因?yàn)槲覀儾幌刖帉懽远x顯示功能。然而,仍然必須提供管理編輯器窗口小部件的功能:

classSpinBoxDelegate:publicQStyledItemDelegate

{

Q_OBJECT

public:

SpinBoxDelegate(QObject*parent=0);

QWidget*createEditor(QWidget*parent,constQStyleOptionViewItem

voidsetEditorData(QWidget*editor,constQModelIndexvoidsetModelData(QWidget*editor,QAbstractItemModel*model,

constQModelIndex

voidupdateEditorGeometry(QWidget*editor,

constQStyleOptionViewItem};

提供了一個(gè)編輯器

在這個(gè)例子中,當(dāng)表視圖需要提供一個(gè)編輯器時(shí),它將要求委托提供一個(gè)編輯器部件適用于修改該項(xiàng)目。createEditor()函數(shù)提供一切,委托需要能夠建立一個(gè)合適的窗口小部件:

QWidget*SpinBoxDelegate::createEditor(QWidget*parent,

constQStyleOptionViewItem&,

constQModelIndex

editor->setFrame(false);

editor->setMinimum(0);

editor->setMaximum(100);

returneditor;}

注意,我們不需要一個(gè)指向編輯器的部件,因?yàn)楫?dāng)不再需要時(shí),視圖負(fù)責(zé)銷毀它。

在編輯器上安裝代理的默認(rèn)事件過濾器,以確保它提供了用戶所期望的標(biāo)準(zhǔn)編輯快捷方式。編輯器中可以添加額外的快捷鍵,以允許更復(fù)雜的行為。

可以根據(jù)視圖提供的模型索引創(chuàng)建不同的編輯器。例如,如果有一個(gè)整數(shù)列和字符串列,我們可以返回一個(gè)QSpinBox或QLineEdit,這取決于哪一列正在被編輯。

委托必須提供一個(gè)函數(shù)將模型中的數(shù)據(jù)復(fù)制到編輯器中。在這個(gè)例子中,我們讀出存儲(chǔ)在顯示角色中的數(shù)據(jù),并在QSpinBox中設(shè)置的值相應(yīng)。

voidSpinBoxDelegate::setEditorData(QWidget*editor,

constQModelIndex

QSpinBox*spinBox=static_castQSpinBox*>(editor);

spinBox->interpretText();

intvalue=spinBox->value();

model->setData(index,value,Qt::EditRole);

}

由于視圖為委托管理編輯器部件,所以只需要以編輯器提供的內(nèi)容來更新模型。在這種情況下,我們確QSpinBox是最新更新,并使用指定的索引包含的值來更新模型。

標(biāo)準(zhǔn)的QItemDelegate類通過發(fā)射closeEditor()信號(hào)來完成編輯視圖。視圖可確保編輯器部件被關(guān)閉和銷毀。在這個(gè)例子中,我們只提供簡(jiǎn)單的編輯功能,所以我們需要永遠(yuǎn)不會(huì)發(fā)出這個(gè)信號(hào)。

所有的數(shù)據(jù)操作通過QAbstractItemModel提供的接口執(zhí)行。這使得委托大多獨(dú)立于它操縱的數(shù)據(jù)的類型,但為了使用某些類型的編輯器部件,則必須做出一些假設(shè)。在這個(gè)例子中,我們假設(shè)模型總是包含整數(shù)值,但我們?nèi)匀辉诓煌愋偷哪P椭惺褂么宋?,因?yàn)榈腝Variant為意想不到的數(shù)據(jù)提供了合理的默認(rèn)值。

更新編輯器的幾何形狀

管理編輯器的幾何形狀是委托的責(zé)任。當(dāng)編輯器被創(chuàng)建,或者當(dāng)項(xiàng)目視圖的的位置、大小在視圖中改變時(shí),幾何形狀必須被設(shè)置。幸運(yùn)的是,視圖提供了視圖選項(xiàng)物體內(nèi)部所有必要的幾何信息。

voidSpinBoxDelegate::updateEditorGeometry(QWidget*editor,constQStyleOptionViewItem

}

這種情況下,我們僅在項(xiàng)目區(qū)域中使用視圖選項(xiàng)提供的位置信息。使用一些元素展現(xiàn)項(xiàng)目的委托不會(huì)直接使用該項(xiàng)目矩形。根據(jù)這個(gè)項(xiàng)目中的其他元素來設(shè)定編輯器的位置。

intmain(intargc,char*argv[])

{

QApplicationapp(argc,argv);

QStandardItemModelmodel(4,2);

QTableViewtableView;

tableView.setModel(

SpinBoxDelegatedelegate;

tableView.setItemDelegate(

tableView.horizontalHeader()->setStretchLastSection(true);

for(introw=0;row2;++column){

QModelIndexindex=model.index(row,column,QModelIndex());model.setData(index,QVariant((row+1)*(column+1)));

}

}

tableView.setWindowTitle(QObject::tr("SpinBoxDelegate"));

tableView.show();

returnapp.exec();

}

Qt之模型/視圖(實(shí)時(shí)更新數(shù)據(jù))

(2014-01-0915:59:48)

轉(zhuǎn)載▼

分類:Qt

標(biāo)簽:

qt

mvc

模型/視圖

qt進(jìn)度條

it

上兩節(jié)簡(jiǎn)單介紹了Qt中對(duì)于模型/視圖的編程,大部分助手里說的很清楚了,現(xiàn)在就開始實(shí)戰(zhàn)部分吧!

在實(shí)際應(yīng)用中,視圖展示的數(shù)據(jù)往往并非一成不變的,那么如何實(shí)時(shí)更新成了一個(gè)很重要的問題!

功能:

(1)添加委托(進(jìn)度條)

(2)顯示文件名稱、大小、進(jìn)度、速度、剩余時(shí)間、狀態(tài)等。

(3)可進(jìn)行添加、更新、刪除、清空等操作。

(4)實(shí)時(shí)更新數(shù)據(jù)

先看一個(gè)效果圖:

委托(進(jìn)度條):

ProgressBarDelegate::ProgressBarDelegate(QObject*parent)

:QItemDelegate(parent)

{

}

voidProgressBarDelegate::paint(QPainter*painter,constQStyleOptionViewItemQStyleOptionProgressBarV2progressBarOption;

progressBarOption.state=QStyle::State_Enabled;

progressBarOption.direction=QApplication::layoutDirection();

progressBarOption.rect=option.rect;

progressBarOption.fontMetrics=QApplication::fontMetrics();

progressBarOption.minimum=0;

progressBarOption.maximum=100;

progressBarOption.textAlignment=Qt::AlignCenter;

progressBarOption.textVisible=true;

progressBarOgress=progress;

progressBarOption.text=

QString("%1%").arg(progressBarOgress);

QApplication::style()->drawControl(QStyle::CE_ProgressBar,

}else{

returnQItemDelegate::paint(painter,option,index);

}

}

模型:

TableModel::TableModel(QObject*parent)

:QAbstractTableModel(parent),arr_row_list(NULL)

{

}

TableModel::~TableModel(void)

{

arr_row_list=NULL;

}

voidTableModel::setHorizontalHeaderList(QStringListhorizontalHeaderList){

horizontal_header_list=horizontalHeaderList;

}

voidTableModel::setVerticalHeaderList(QStringListverticalHeaderList)

{

vertical_header_list=verticalHeaderList;

}

intTableModel::rowCount(constQModelIndex

if(NULL==arr_row_list)

return0;

else

returnarr_row_list->size();

}

intTableModel::columnCount(constQModelIndex

if(NULL==arr_row_list)

return0;

elseif(arr_row_list->size()size()=arr_row_list->size())

returnQVariant();

if(index.column()>=arr_row_list->at(0).size())

returnQVariant();

returnarr_row_list->at(index.row()).at(index.column());

}

returnQVariant();

}

QVariantTableModel::headerData(intsection,Qt::Orientationorientation,introle)const

{

if(role==Qt::DisplayRole)

{

if(orientation==Qt::Horizontal)//水平表頭

{

if(horizontal_header_list.size()>section)

returnhorizontal_header_list[section];

else

returnQVariant();

}

else

{

if(vertical_header_list.size()>section)

returnvertical_header_list[section];//垂直表頭

else

returnQVariant();

}

}

returnQVariant();

}

Qt::ItemFlagsTableModel::flags(constQModelIndex

Qt::ItemFlagsflag=QAbstractItemModel::flags(index);

//flag|=Qt::ItemIsEditable//設(shè)置單元格可編輯,此處解釋,單元格無法被編輯

returnflag;

}

voidTableModel::setModalDatas(QListrowCount(QModelIndex()));

}

視圖:

TableView::TableView(QWidget*parent)

:QTableView(parent)

{

this->setAlternatingRowColors(true);

this->setStyleSheet("QTableView{background-color:rgb(250,250,115);""alternate-background-color:rgb(141,163,215);}");

this->setSelectionBehavior(QAbstractItemView::SelectRows);

this->horizontalHeader()->setStretchLastSection(true);

this->horizontalHeader()->setHighlightSections(false);

this->verticalHeader()->setVisible(false);

this->setShowGrid(false);

this->setEditTriggers(QAbstractItemView::NoEditTriggers);

this->setSelectionMode(QAbstractItemView::ExtendedSelection);

model=newTableModel();

this->setModel(model);

this->initHeader();

model->setModalDatas(

progressbar_delegate=newProgressBarDelegate();

this->setItemDelegate(progressbar_delegate);

connect(model,

this->initHeader();

}

TableView::~TableView(void)

{

if(progressbar_delegate){

deleteprogressbar_delegate;

progressbar_delegate=NULL;

}

if(model){

deletemodel;

model=NULL;

}

grid_data_list.clear();

}

voidTableView::addRow(QStringListrowList)

{

grid_data_list.append(rowList);

model->refrushModel();

}

voidTableView::remove()

{

QModelIndexListmodel_index_list=this->selectedIndexes();intmodel_count=model_index_list.count();

if(model_count=0;i--)

{

grid_data_list.removeAt(list_row.at(i));

}

model->refrushModel();

}

voidTableView::clear()

{

grid_data_list.clear();

model->refrushModel();

}

intTableView::rowCount()

{

returnmodel->rowCount(QModelIndex());

}

voidTableView::initHeader()

{

QStringListheader;

headerrowCount();

if(row_countrefrushModel();

}

完整的工程(源碼)下載地址:

http://./doc/4a1be5cd0029bd64793e2c3d.html/detail/u011012932/6829783。

Qt之模型/視圖(自定義風(fēng)格)

(2014-01-0916:58:10)

轉(zhuǎn)載▼

分類:Qt

標(biāo)簽:

qt

模型/視圖

qt模型視圖

qt進(jìn)度條

qt委托進(jìn)度條

關(guān)于自定義風(fēng)格是針對(duì)視圖與委托而言的,使用事件與QSS都可以進(jìn)行處理,今天關(guān)于美化的細(xì)節(jié)講解一下。

先看下圖:

先撇開界面的美觀性(蘿卜青菜,各有所愛),就現(xiàn)有的這些風(fēng)格,使用QSS+Qt二維繪圖已經(jīng)綽綽有余了。當(dāng)然,如何讓界面更美觀,這個(gè)沒有什么捷徑,我只能說一句:無他,唯手熟爾!基本功搞扎實(shí)了,實(shí)現(xiàn)起來就會(huì)游刃有余。。。

voidDetailProgressBar::paint(QPainter*painter,constQStyleOptionViewItem

if(view_option.state

}

QStyledItemDelegate::paint(painter,view_option,index);

if(index.column()==1){

constQAbstractItemMod

溫馨提示

  • 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)論