Qt 是目前最先进、最完整的跨平台C++开发工具。它不仅完全实现了一次编写,所有平台无差别运行,更提供了几乎所有开发过程中需要用到的工具。如今,Qt已被运用于超过70个行业、数千家企业,支持数百万设备及应用。
点击获取Qt Widget组件下载(Q技术交流:166830288)
树项类定义
该类提供包含多个数据的简单项,包括有关其父项和子项的信息: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 设计为类似于 QAbstractItemModel 提供的 API,为每个项目提供返回信息列数、读取和写入数据以及插入和删除列的函数。但是,我们通过提供处理“子”而不是“行”的函数来明确项目之间的关系。
每个项都包含一个指向子项的指针列表、一个指向其父项的指针,以及一个 QVariant 对象列表,这些对象对应于模型中给定行的列中保存的信息。
树项类实现
每个都由数据列表和一个可选的父项构造:TreeItem
TreeItem::TreeItem(const QList<QVariant> &data, TreeItem *parent)
: itemData(data), parentItem(parent)
{}
最初,每个项目都没有子项。这些函数使用后面介绍的函数添加到项的内部成员中。childItemsinsertChildren()
析构函数确保在删除项本身时删除添加到项的每个子项:
TreeItem::~TreeItem()
{
qDeleteAll(childItems);
}
由于每个项目都存储指向其父项的指针,因此该函数很简单:parent()
TreeItem *TreeItem::parent()
{
return parentItem;
}
三个函数提供有关项的子项的信息。 从内部子项列表中返回特定的子项:child()
TreeItem *TreeItem::child(int number)
{
if (number < 0 || number >= childItems.size())
return nullptr;
return childItems.at(number);
}
该函数返回子项的总数:childCount()
int TreeItem::childCount() const
{
return childItems.count();
}
该函数用于确定子项在其父项的子项列表中的索引。它直接访问父级的成员以获取此信息:childNumber()childItems
int TreeItem::childNumber() const
{
if (parentItem)
return parentItem->childItems.indexOf(const_cast<TreeItem*>(this));
return 0;
}
根项没有父项;对于此项,我们返回零以与其他项保持一致。
该函数仅返回 QVariant 对象内部列表中的元素数:columnCount()itemData
int TreeItem::columnCount() const
{
return itemData.count();
}
使用函数检索数据,该函数访问列表中的相应元素:data()itemData
QVariant TreeItem::data(int column) const
{
if (column < 0 || column >= itemData.size())
return QVariant();
return itemData.at(column);
}
数据是使用函数设置的,该函数仅将有效列表索引的值存储在列表中,对应于模型中的列值:setData()itemData
bool TreeItem::setData(int column, const QVariant &value)
{
if (column < 0 || column >= itemData.size())
return false;
itemData[column] = value;
return true;
}
为了使模型的实现更容易,我们返回 true 以指示数据已成功设置。
可编辑模型通常需要调整大小,以便插入和删除行和列。在模型中给定模型索引下插入行会导致在相应的项中插入新的子项,由以下函数处理: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;
}
这可确保使用所需列数创建新项,并将其插入到内部列表中的有效位置。使用以下函数删除项目:childItemsremoveChildren()文章来源:https://www.toymoban.com/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;
}
如上所述,用于插入和删除列的函数与用于插入和删除子项的函数使用方式不同,因为它们应该在树中的每个项上调用。我们通过在项目的每个子项上递归调用此函数来实现这一点:文章来源地址https://www.toymoban.com/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;
}
到了这里,关于界面开发框架Qt新手入门教程 - 可编辑树模型的示例(一)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!