衆所周知,Qt提供了一套Model/View框架供開發者使用,Model用來提供數據, View則用來提供視覺層的顯示。實際上這是一套遵循MVC設計模式的GUI框架,由於Qt還提供了默認的Delegate做爲Controller來做爲控制器。html
MVC的好處這裏就很少說了,爲了開發者使用方便,Qt還提供了基於項(Item)的Model/View實現----QXxxWidget(QTableWidget、QListWidget等),對於一些簡單的應用場景,這已經足夠了而且使用起來很是方便。這裏咱們簡單介紹下如何使用自定義的數據模型,來知足各類花式的要求。git
Qt實現了4類標準數據模型供咱們在不一樣的場景下使用:github
若是使用狀況和上述狀況之一比較類似,則能夠考慮繼承對應的模型類,並從新實現少數虛函數。數據庫
抽象數據模型有3類:設計模式
Qt官方提供了完善的文檔來幫助開發者來自定義模型類。根據官網,子類化模型須要開發者實現的功能(即須要從新實現的虛函數)按功能來分能夠分爲三類:數據結構
咱們只須要按照本身的功能需求來實現其中的一些虛函數。框架
這裏咱們來實現一個自定義模型,並在QTableView中使用它,所以咱們選擇繼承QAbstractTableModel,這樣咱們須要作的改動最少。但使用QTableModel並不意味着咱們的數據結構就是Table狀的,例以下面的例子中咱們根本不須要內部數據結構。函數
下面咱們要實現這樣一個數據模型:設計
該模型繼承自QAbstractTableModel,做爲只讀模型,咱們只須要實現如下幾個虛函數:3d
virtual Qt::ItemFlags flags(const QModelIndex &index) const; virtual QVariant data(const QModelIndex &index, int role) const; virtual QVariant headerData(int section, Qt::Orientation orientation, int role) const; virtual int rowCount(const QModelIndex &parent) const; virtual int columnCount(const QModelIndex &parent) const;
data()
函數與項數據有關,這裏數據有好幾種角色(role),最基本的就是Qt::DisplayRole
,這裏爲了實現居中效果,咱們還處理了Qt::TextAlignmentRole
角色:
QVariant MyTableModel::data(const QModelIndex &index, int role) const { if (role == Qt::DisplayRole) { return index.column() * index.column(); } if (role == Qt::TextAlignmentRole) { return Qt::AlignCenter; } return QVariant(); }
headerData()
函數提供表頭數據,包括兩個方向(垂直、水平)的表頭。一樣,這裏的數據也有好幾種角色,咱們只處理Qt::DisplayRole
:
QVariant MyTableModel::headerData(int section, Qt::Orientation orientation, int role) const { if (orientation == Qt::Vertical) { if (role == Qt::DisplayRole) return QVariant("row:" + QString::number(section)); else return QVariant(); } if (orientation == Qt::Horizontal) { if (role == Qt::DisplayRole) return QVariant("column:" + QString::number(section)); else return QVariant(); } }
rowCount()
和columnCount()
返回數據模父下標(QModelIndex)的行和列數量,這裏咱們要判別下標是否有效:由於整個表模型的父下標爲無效下標,咱們返回表模型的行列數量;當下標有效時,咱們返回的是父下標指向處的子表的行列:
// if `parent` is invalid, return the whole table row count! // else return the children row count of the `parent` int MyTableModel::rowCount(const QModelIndex &parent) const { if (parent.isValid()) return 0; else return 10; }
完整代碼見此處。