標籤:style blog http color get 使用
資料項目中引入模型/視圖架構,可以方便的將資料與表現層分開。
-------------------------------------
模型Model:一般來說,Model裡面並不真正儲存資料(資料少的話也可以直接儲存在Model裡),只是負責從諸如磁碟檔案,資料庫,網路通訊等獲得來源資料,並提供給View,View對資料進行修改,然後再通過Model更新來源資料。
Model 另一個重要工作時為來源資料添加索引(ModelIndex)。列表形式採用row/colum編號,樹形式為建立父子間的層次關係而多添加了一個ParentIndex索引。
當View需要顯示資料或者需要View中的指定資料項目時,通過模組索引(ModelIndex)從Model中擷取資料,如果View中添加了自訂“委託”,要通過調用mapFromSource 返回和源Model相映射的“委託模組”的索引來擷取資料。
-------------------------------------
為每個視圖都提供了一個預設的委託——可以使用自訂的委託來替換顯示每一項,並為可編輯項提供一個合適的編輯器。
-------------------------------------
模型:用於儲存資料項目(data item)。
純粹的視圖組件:QListView、QColumnView、QTableView、QColumnView和QTreeView,必須為視圖提供一個模型與之配合。
-------------------------------------
便利的視窗組件:QListWidget、QTableview和QTreeWidget,都有自己的內建模型並能直接使用。
QComboBox:既是一個便利視窗組件也是一個視圖組件,即既能直接使用(內建的模型),也可當做視圖(外部提供合適模型)。
-------------------------------------
QStyledItemDelegate委託:所有的標準視圖都提供了一個預設的QStyledItemDelegate委託(顯示視圖中各個項並為可編輯的項提供一個合適的編輯器)。可以自訂委託,控制視圖中的各個項的顯示和編輯。
-------------------------------------
對於有數百或數千個項的資料集,假設資料集在任何時候僅僅顯示在一個組件中,那麼選擇便利視窗組件(內建模型視圖組件)比較合適。
-------------------------------------
儘管有統一的API,但仍有兩種不同類型的模型:行列特性表格模型和父子關係的樹模型。
-------------------------------------
QStandardItemModel:是一個可被當成列表模型、表格模型或樹模型來使用的通用模型。它提供了一個基於項的API。對於能夠直接把資料恰好填充入列表、表格或樹模型的各個資料項目中,並能夠直接使用或僅需做微小改動即可的情況,使用QStandardItemModel是理想的選擇。
QAbstractTableModel:不儲存資料,使用者需要從這些類派生出子類,並在子類中定義某種資料結構來儲存資料。與此不同,類QStandardItemModel負責儲存資料,每個資料項目被表示為類QStandardItem的對象。
QStandardItem資料項目:一個資料項目由若干個『角色/*字型、顏色等資訊*/,資料子項』對組成,該類負責儲存、訪問這些資料。該類的內部定義了一個類型為QVector的容器,每個容器元素本質上存放一個『角色,資料子項』對,且各個角色可能對應具有不同類型的資料子項。
void setData ( const QVariant & value, int role)//將『role, value』對存入QStandardItem對象
QVariant data ( int role = ) const //讀取角色role對應的資料子項
QStandardItemModel將類QStandardItem表示的資料項目組織起來,形成列表、表格、樹甚至更複雜的資料結構。
QStandardItemModel提供了一群組成員函數:添加資料項目appendRow()/*資料集為列表形式*/,更改資料項目或刪除資料項目。
void QStandardItemModel::appendRow(const QList<QStandardItem *> & items)
-------------------------------------
QSortFilterProxyModel代理:過濾資料,擁有“防火牆”的作用,限制輸出到View中進行顯示的資料。代理處理完資料,不是直接交給委託,而是交給View,View再負責傳遞給Item,Item再通過委託顯示特定的樣式。(代理->視圖->委託->顯示)
voidQSortFilterProxyModel::setSourceModel(QAbstractItemModel * sourceModel)
--------------------------------------
QStyledItemDelegate委託處理過程(Item預設使用textedit顯示資料):
-------------------------------------
View通過ModelIndex從model中擷取資料:
QVariant QAbstractProxyModel::data(const QModelIndex & proxyIndex, int role = Qt::DisplayRole) const
當Model中的data變化時,自動發dataChanged signal給所有的view以便它們更新。
View修改Model中對應ModelIndex的資料:
bool QAbstractProxyModel::setData(const QModelIndex & index, const QVariant & value, int role = Qt::EditRole)
View負責組織資料並顯示,但真正的顯示工作交給代理delegate,代理負責最終的顯示資料和處理使用者互動的工作。
------------------------------------
通過代理delegate編輯並顯示資料項目的過程:
當通過雙擊滑鼠或斷行符號等操作觸發了View的edit trigger時,Delegate會建立一個合適的widget
(如line edit或combo box等)處理使用者的輸入,使用者編輯完成以後發射commitData“編輯完成訊號”,
delegate通過setModelData將更新Model中的資料。
1)void paint(QPainter *painter, const QStyleOptionViewItem &option, //View通過delegate重繪Item、渲染內容
const QModelIndex &index) const;
------------------------------------
2)QWidget *createEditor(QWidget *parent,//建立修改資料編輯器
const QStyleOptionViewItem &option,
const QModelIndex &index) const;//QModelIndex選擇需要進行渲染的列
void setEditorData(QWidget *editor, //為editor提供編輯的未經處理資料
const QModelIndex &index) const;
//當使用者開始編輯時,視圖首先調用 委託的createEditor( ) 建立一個編輯器,然後調用 setEditorData( )
並使用當前資料項目 Item 中的資料初始化編輯器。
------------------------------------
//當使用者點擊斷行符號,或者從 QTimeEidt 等控制項上失去輸入焦點後,editingFinished() 訊號就發送出來,
並且 commitAndColseEditor() 槽函數被調用。
connect( ..., SIGNAL(editingFinished()), ..., SLOT(CommitAndCloseEditor()) );
3)void ItemDelegate::CommitAndCloseEditor()
{
//QObject::sender() Returns a pointer to the object that sent the signal
QTimeEdit *editor = qobject_cast<QTimeEdit *>(sender()); //使用 sender() 來獲得編輯器
emit commitData( editor );//發送commitData() 訊號提醒視圖有一個已編輯好的資料需要更新了
emit closeEditor( editor );//發送closeEditor( ) 訊號通知視圖編輯控制項不需要了,模型刪除該編輯器
}
--------------------------------------
//擷取編輯器中的資料並儲存到指定模組索引的Model中
4)void setModelData(QWidget *editor, QAbstractItemModel *model,
const QModelIndex &index) const;