翻譯|使用教程|編輯:龔雪|2023-02-16 10:35:38.067|閱讀 204 次
概述:本教程將為大家介紹每個(gè)UI開發(fā)人員都應(yīng)該了解的ModelView編程,歡迎下載相關(guān)組件體驗(yàn)~
# 界面/圖表報(bào)表/文檔/IDE等千款熱門軟控件火熱銷售中 >>
相關(guān)鏈接:
每個(gè)UI開發(fā)人員都應(yīng)該了解ModelView編程,本教程的目標(biāo)是為大家提供一個(gè)簡單易懂的介紹。
Qt 是目前最先進(jìn)、最完整的跨平臺C++開發(fā)工具。它不僅完全實(shí)現(xiàn)了一次編寫,所有平臺無差別運(yùn)行,更提供了幾乎所有開發(fā)過程中需要用到的工具。如今,Qt已被運(yùn)用于超過70個(gè)行業(yè)、數(shù)千家企業(yè),支持?jǐn)?shù)百萬設(shè)備及應(yīng)用。
在上文中,我們主要為大家介紹了Model/View(模型/視圖)的一些基本概念(點(diǎn)擊這里回顧>>),本文將繼續(xù)為大家介紹如何創(chuàng)建一個(gè)簡單的模型/視圖應(yīng)用。
Qt技術(shù)交流群:166830288 歡迎一起進(jìn)群討論
如果想開發(fā)一個(gè)模型/視圖應(yīng)用程序,應(yīng)該從哪里開始呢?我們建議從一個(gè)簡單的示例開始,逐步擴(kuò)展它,這使得理解體系結(jié)構(gòu)更加容易。對于許多開發(fā)人員來說,在調(diào)用IDE之前試圖詳細(xì)理解模型/視圖體系結(jié)構(gòu)是不太方便的,從具有演示數(shù)據(jù)的簡單模型/視圖應(yīng)用程序開始實(shí)際上更容易。
下面是7個(gè)非常簡單且獨(dú)立的應(yīng)用程序,它們展示了模型/視圖編程的不同方面,源代碼可以在examples/widgets/tutorials/modelview目錄中找到。
我們?nèi)匀挥幸粋€(gè)只讀表,但這一次內(nèi)容每秒都在變化,因?yàn)檎陲@示當(dāng)前時(shí)間。
(文件來源:examples/widgets/tutorials/modelview/3_changingmodel/mymodel.cpp)
QVariant MyModel::data(const QModelIndex &index, int role) const
{
int row = index.row();
int col = index.column();
if (role == Qt::DisplayRole && row == 0 && col == 0)
return QTime::currentTime().toString();
return QVariant();
}
時(shí)鐘的滴答聲缺少了一些東西,需要每一秒都告訴視圖時(shí)間已經(jīng)改變、需要再次讀取。我們用定時(shí)器來做這個(gè),在構(gòu)造函數(shù)中,我們將其間隔設(shè)置為1秒,并連接其超時(shí)信號。
(文件來源:examples/widgets/tutorials/modelview/3_changingmodel/mymodel.cpp)
MyModel::MyModel(QObject *parent)
: QAbstractTableModel(parent)
, timer(new QTimer(this))
{
timer->setInterval(1000);
connect(timer, &QTimer::timeout , this, &MyModel::timerHit);
timer->start();
}
這里是對應(yīng)的槽位:
(文件來源:examples/widgets/tutorials/modelview/3_changingmodel/mymodel.cpp)
void MyModel::timerHit()
{
// we identify the top left cell
QModelIndex topLeft = createIndex(0,0);
// emit a signal to make the view reread identified data
emit dataChanged(topLeft, topLeft, {Qt::DisplayRole});
}
通過發(fā)出() 信號,我們要求視圖再次讀取左上角單元格中的數(shù)據(jù)。注意,沒有顯式地將dataChanged()信號連接到視圖,這在調(diào)用setModel()時(shí)自動(dòng)發(fā)生。
標(biāo)題可以通過一個(gè)視圖方法隱藏:ableView->verticalHeader()->hide();
然而,頭部內(nèi)容是通過模型設(shè)置的,所以我們重新實(shí)現(xiàn)headerData()方法:
(文件來源:examples/widgets/tutorials/modelview/4_headers/mymodel.cpp)
QVariant MyModel::headerData(int section, Qt::Orientation orientation, int role) const
{
if (role == Qt::DisplayRole && orientation == Qt::Horizontal) {
switch (section) {
case 0:
return QString("first");
case 1:
return QString("second");
case 2:
return QString("third");
}
}
return QVariant();
}
注意,方法()也有一個(gè)參數(shù)role,其含義與()中的相同。
在本例中,我們將構(gòu)建一個(gè)應(yīng)用程序,通過重復(fù)輸入到表格單元格中的值,自動(dòng)用內(nèi)容填充窗口標(biāo)題。為了能夠方便地訪問窗口標(biāo)題,我們將放在中。
模型決定編輯功能是否可用,為了啟用可用的編輯功能,我們只需要修改模型,這是通過重新實(shí)現(xiàn)以下虛擬方法來實(shí)現(xiàn)的:() 和()。
(文件來源:examples/widgets/tutorials/modelview/5_edit/mymodel.h)
// mymodel.h
#include <QAbstractTableModel>
#include <QString>
const int COLS= 3;
const int ROWS= 2;
class MyModel : public QAbstractTableModel
{
Q_OBJECT
public:
MyModel(QObject *parent = nullptr);
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
int columnCount(const QModelIndex &parent = QModelIndex()) const override;
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) override;
Qt::ItemFlags flags(const QModelIndex &index) const override;
private:
QString m_gridData[ROWS][COLS]; //holds text entered into QTableView
signals:
void editCompleted(const QString &);
};
我們使用二維數(shù)組QString m_gridData來存儲數(shù)據(jù),這使得m_gridData成為MyModel的核心。MyModel的其余部分就像一個(gè)包裝器,并將m_gridData適配到QAbstractItemModel接口,同時(shí)我們引入了editCompleted()信號,這使得將修改后的文本傳輸?shù)酱翱跇?biāo)題成為可能。
(文件來源:examples/widgets/tutorials/modelview/5_edit/mymodel.cpp)
bool MyModel::setData(const QModelIndex &index, const QVariant &value, int role)
{
if (role == Qt::EditRole) {
if (!checkIndex(index))
return false;
//save value from editor to member m_gridData
m_gridData[index.row()][index.column()] = value.toString();
//for presentation purposes only: build and emit a joined string
QString result;
for (int row = 0; row < ROWS; row++) {
for (int col= 0; col < COLS; col++)
result += m_gridData[row][col] + ' ';
}
emit editCompleted(result);
return true;
}
return false;
}
每次用戶編輯單元格時(shí)都會調(diào)用(),index參數(shù)告訴我們編輯了哪個(gè)字段,value提供了編輯過程的結(jié)果。角色總是被設(shè)置為 ,因?yàn)槲覀兊膯卧?只包含文本,如果存在一個(gè)復(fù)選框,并且用戶權(quán)限設(shè)置為允許選擇該復(fù)選框,則調(diào)用也會將角色設(shè)置為。
(文件來源:examples/widgets/tutorials/modelview/5_edit/mymodel.cpp)
Qt::ItemFlags MyModel::flags(const QModelIndex &index) const
{
return Qt::ItemIsEditable | QAbstractTableModel::flags(index);
}
可以使用()調(diào)整單元格的各種屬性。
返回足以向編輯器顯示一個(gè)單元格可以被選擇。
如果編輯一個(gè)單元格修改的數(shù)據(jù)多于該特定單元格中的數(shù)據(jù),則模型必須發(fā)出()信號,以便讀取已更改的數(shù)據(jù)。
本站文章除注明轉(zhuǎn)載外,均為本站原創(chuàng)或翻譯。歡迎任何形式的轉(zhuǎn)載,但請務(wù)必注明出處、不得修改原文相關(guān)鏈接,如果存在內(nèi)容上的異議請郵件反饋至chenjj@ke049m.cn
文章轉(zhuǎn)載自:慧都網(wǎng)