Qt?是目前最先進(jìn)、最完整的跨平臺(tái)C++開(kāi)發(fā)工具。它不僅完全實(shí)現(xiàn)了一次編寫,所有平臺(tái)無(wú)差別運(yùn)行,更提供了幾乎所有開(kāi)發(fā)過(guò)程中需要用到的工具。如今,Qt已被運(yùn)用于超過(guò)70個(gè)行業(yè)、數(shù)千家企業(yè),支持?jǐn)?shù)百萬(wàn)設(shè)備及應(yīng)用。
點(diǎn)擊獲取Qt Widget組件下載(Q技術(shù)交流:166830288)
樹(shù)項(xiàng)類定義
該類提供包含多個(gè)數(shù)據(jù)的簡(jiǎn)單項(xiàng),包括有關(guān)其父項(xiàng)和子項(xiàng)的信息:TreeItem
class TreeItem
{
public:
explicit TreeItem(const QList<QVariant> &data, TreeItem *parent = nullptr);
~TreeItem();
TreeItem *child(int number);
int childCount() const;
int columnCount() const;
QVariant data(int column) const;
bool insertChildren(int position, int count, int columns);
bool insertColumns(int position, int columns);
TreeItem *parent();
bool removeChildren(int position, int count);
bool removeColumns(int position, int columns);
int childNumber() const;
bool setData(int column, const QVariant &value);
private:
QList<TreeItem *> childItems;
QList<QVariant> itemData;
TreeItem *parentItem;
};
我們將 API 設(shè)計(jì)為類似于?QAbstractItemModel?提供的 API,為每個(gè)項(xiàng)目提供返回信息列數(shù)、讀取和寫入數(shù)據(jù)以及插入和刪除列的函數(shù)。但是,我們通過(guò)提供處理“子”而不是“行”的函數(shù)來(lái)明確項(xiàng)目之間的關(guān)系。
每個(gè)項(xiàng)都包含一個(gè)指向子項(xiàng)的指針列表、一個(gè)指向其父項(xiàng)的指針,以及一個(gè)?QVariant?對(duì)象列表,這些對(duì)象對(duì)應(yīng)于模型中給定行的列中保存的信息。
樹(shù)項(xiàng)類實(shí)現(xiàn)
每個(gè)都由數(shù)據(jù)列表和一個(gè)可選的父項(xiàng)構(gòu)造:TreeItem
TreeItem::TreeItem(const QList<QVariant> &data, TreeItem *parent)
: itemData(data), parentItem(parent)
{}
最初,每個(gè)項(xiàng)目都沒(méi)有子項(xiàng)。這些函數(shù)使用后面介紹的函數(shù)添加到項(xiàng)的內(nèi)部成員中。childItemsinsertChildren()
析構(gòu)函數(shù)確保在刪除項(xiàng)本身時(shí)刪除添加到項(xiàng)的每個(gè)子項(xiàng):
TreeItem::~TreeItem()
{
qDeleteAll(childItems);
}
由于每個(gè)項(xiàng)目都存儲(chǔ)指向其父項(xiàng)的指針,因此該函數(shù)很簡(jiǎn)單:parent()
TreeItem *TreeItem::parent()
{
return parentItem;
}
三個(gè)函數(shù)提供有關(guān)項(xiàng)的子項(xiàng)的信息。 從內(nèi)部子項(xiàng)列表中返回特定的子項(xiàng):child()
TreeItem *TreeItem::child(int number)
{
if (number < 0 || number >= childItems.size())
return nullptr;
return childItems.at(number);
}
該函數(shù)返回子項(xiàng)的總數(shù):childCount()
int TreeItem::childCount() const
{
return childItems.count();
}
該函數(shù)用于確定子項(xiàng)在其父項(xiàng)的子項(xiàng)列表中的索引。它直接訪問(wèn)父級(jí)的成員以獲取此信息:childNumber()childItems
int TreeItem::childNumber() const
{
if (parentItem)
return parentItem->childItems.indexOf(const_cast<TreeItem*>(this));
return 0;
}
根項(xiàng)沒(méi)有父項(xiàng);對(duì)于此項(xiàng),我們返回零以與其他項(xiàng)保持一致。
該函數(shù)僅返回?QVariant?對(duì)象內(nèi)部列表中的元素?cái)?shù):columnCount()itemData
int TreeItem::columnCount() const
{
return itemData.count();
}
使用函數(shù)檢索數(shù)據(jù),該函數(shù)訪問(wèn)列表中的相應(yīng)元素:data()itemData
QVariant TreeItem::data(int column) const
{
if (column < 0 || column >= itemData.size())
return QVariant();
return itemData.at(column);
}
數(shù)據(jù)是使用函數(shù)設(shè)置的,該函數(shù)僅將有效列表索引的值存儲(chǔ)在列表中,對(duì)應(yīng)于模型中的列值:setData()itemData
bool TreeItem::setData(int column, const QVariant &value)
{
if (column < 0 || column >= itemData.size())
return false;
itemData[column] = value;
return true;
}
為了使模型的實(shí)現(xiàn)更容易,我們返回 true 以指示數(shù)據(jù)已成功設(shè)置。
可編輯模型通常需要調(diào)整大小,以便插入和刪除行和列。在模型中給定模型索引下插入行會(huì)導(dǎo)致在相應(yīng)的項(xiàng)中插入新的子項(xiàng),由以下函數(shù)處理:insertChildren()
bool TreeItem::insertChildren(int position, int count, int columns)
{
if (position < 0 || position > childItems.size())
return false;
for (int row = 0; row < count; ++row) {
QList<QVariant> data(columns);
TreeItem *item = new TreeItem(data, this);
childItems.insert(position, item);
}
return true;
}
這可確保使用所需列數(shù)創(chuàng)建新項(xiàng),并將其插入到內(nèi)部列表中的有效位置。使用以下函數(shù)刪除項(xiàng)目:childItemsremoveChildren()文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-460842.html
bool TreeItem::removeChildren(int position, int count)
{
if (position < 0 || position + count > childItems.size())
return false;
for (int row = 0; row < count; ++row)
delete childItems.takeAt(position);
return true;
}
如上所述,用于插入和刪除列的函數(shù)與用于插入和刪除子項(xiàng)的函數(shù)使用方式不同,因?yàn)樗鼈儜?yīng)該在樹(shù)中的每個(gè)項(xiàng)上調(diào)用。我們通過(guò)在項(xiàng)目的每個(gè)子項(xiàng)上遞歸調(diào)用此函數(shù)來(lái)實(shí)現(xiàn)這一點(diǎn):文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-460842.html
bool TreeItem::insertColumns(int position, int columns)
{
if (position < 0 || position > itemData.size())
return false;
for (int column = 0; column < columns; ++column)
itemData.insert(position, QVariant());
for (TreeItem *child : std::as_const(childItems))
child->insertColumns(position, columns);
return true;
}
到了這里,關(guān)于界面開(kāi)發(fā)框架Qt新手入門教程 - 可編輯樹(shù)模型的示例(一)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!