C++用QTreeView实现,在“未完成”节点下有很多条复选框,在“已完成”节点下也有很多条复选框
时间: 2024-02-13 16:04:50 浏览: 133
你可以通过继承QAbstractItemModel类,自定义数据模型,并重写相应的虚函数来实现这个功能。下面是一个简单的示例代码,实现了一个包含“未完成”和“已完成”两个节点的树形结构,每个节点下面有多个复选框。
```c++
#include <QApplication>
#include <QStandardItemModel>
#include <QTreeView>
class MyModel : public QAbstractItemModel
{
public:
MyModel(QObject *parent = nullptr) : QAbstractItemModel(parent)
{
rootItem = new QStandardItem("Root");
QStandardItem *unfinishedItem = new QStandardItem("未完成");
QStandardItem *completedItem = new QStandardItem("已完成");
rootItem->appendRow(unfinishedItem);
rootItem->appendRow(completedItem);
for (int i = 0; i < 5; i++) {
QStandardItem *item1 = new QStandardItem("任务" + QString::number(i + 1));
QStandardItem *item2 = new QStandardItem("任务" + QString::number(i + 6));
for (int j = 0; j < 3; j++) {
QStandardItem *checkBox1 = new QStandardItem("复选框" + QString::number(j + 1));
QStandardItem *checkBox2 = new QStandardItem("复选框" + QString::number(j + 4));
item1->appendRow(checkBox1);
item2->appendRow(checkBox2);
}
unfinishedItem->appendRow(item1);
completedItem->appendRow(item2);
}
}
QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const override
{
if (!hasIndex(row, column, parent))
return QModelIndex();
QStandardItem *parentItem = getItem(parent);
QStandardItem *childItem = parentItem->child(row, column);
if (childItem)
return createIndex(row, column, childItem);
else
return QModelIndex();
}
QModelIndex parent(const QModelIndex &index) const override
{
if (!index.isValid())
return QModelIndex();
QStandardItem *childItem = getItem(index);
QStandardItem *parentItem = childItem->parent();
if (parentItem == rootItem)
return QModelIndex();
return createIndex(parentItem->row(), 0, parentItem);
}
int rowCount(const QModelIndex &parent = QModelIndex()) const override
{
QStandardItem *parentItem = getItem(parent);
return parentItem->rowCount();
}
int columnCount(const QModelIndex &parent = QModelIndex()) const override
{
Q_UNUSED(parent)
return 1;
}
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override
{
if (!index.isValid())
return QVariant();
QStandardItem *item = getItem(index);
if (role == Qt::DisplayRole)
return item->text();
if (role == Qt::CheckStateRole && item->rowCount() == 0)
return item->checkState();
return QVariant();
}
Qt::ItemFlags flags(const QModelIndex &index) const override
{
if (!index.isValid())
return Qt::NoItemFlags;
QStandardItem *item = getItem(index);
if (item->rowCount() == 0)
return Qt::ItemIsEnabled | Qt::ItemIsUserCheckable;
return Qt::ItemIsEnabled;
}
bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) override
{
if (role == Qt::CheckStateRole) {
QStandardItem *item = getItem(index);
item->setCheckState(value.toBool() ? Qt::Checked : Qt::Unchecked);
emit dataChanged(index, index);
return true;
}
return false;
}
private:
QStandardItem *getItem(const QModelIndex &index) const
{
if (index.isValid()) {
QStandardItem *item = static_cast<QStandardItem*>(index.internalPointer());
if (item)
return item;
}
return rootItem;
}
QStandardItem *rootItem;
};
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QTreeView treeView;
MyModel myModel;
treeView.setModel(&myModel);
treeView.show();
return a.exec();
}
```
在这个示例代码中,自定义的数据模型MyModel继承自QAbstractItemModel类。数据模型中包含一个根节点rootItem,以及“未完成”和“已完成”两个子节点unfinishedItem和completedItem。每个子节点下面有多个复选框。在数据模型中重写了虚函数index、parent、rowCount、columnCount、data、flags和setData,用来返回相应的数据和属性信息。QTreeView控件中通过setModel函数设置数据模型为MyModel,然后就可以显示出树形结构。可以看到,在QTreeView中,每个复选框都可以被勾选或取消勾选,同时,也可以展开或折叠每个节点。
阅读全文