可以通过继承QAbstractItemModel来实现这个功能。以下是一个简单的例子:
创建一个自定义的model类,继承QAbstractItemModel,并实现必要的函数。
在构造函数中初始化数据结构。
重载rowCount、columnCount和data函数,用于设置树形控件的行数、列数和数据显示。
重载setData函数,在comboBox的选项发生改变时更新对应行的第二个comboBox。
在MainWindow中创建QTreeView控件并设置model为自定义model类。
下面是代码示例:
#include <QtWidgets>
class MyModel : public QAbstractItemModel
{
Q_OBJECT
public:
explicit MyModel(QObject *parent = nullptr);
QModelIndex index(int row, int column, const QModelIndex &parent) const override;
QModelIndex parent(const QModelIndex &index) const override;
int rowCount(const QModelIndex &parent) const override;
int columnCount(const QModelIndex &parent) const override;
QVariant data(const QModelIndex &index, int role) const override;
bool setData(const QModelIndex &index, const QVariant &value, int role) override;
private:
QList<QStringList> m_data; // 存储数据
};
MyModel::MyModel(QObject *parent)
: QAbstractItemModel(parent)
{
// 初始化数据
QStringList headers = {"Header1", "Header2"};
m_data << headers;
for (int i = 0; i < 5; ++i) {
QStringList row = {"ComboBox1", ""};
m_data << row;
}
}
QModelIndex MyModel::index(int row, int column, const QModelIndex &parent) const
{
if (!hasIndex(row, column, parent))
return QModelIndex();
return createIndex(row, column);
}
QModelIndex MyModel::parent(const QModelIndex &index) const
{
Q_UNUSED(index)
return QModelIndex();
}
int MyModel::rowCount(const QModelIndex &parent) const
{
if (parent.column() > 0)
return 0;
if (!parent.isValid())
return m_data.size();
return 0;
}
int MyModel::columnCount(const QModelIndex &parent) const
{
Q_UNUSED(parent)
return m_data.first().size();
}
QVariant MyModel::data(const QModelIndex &index, int role) const
{
if (!index.isValid())
return QVariant();
switch (role) {
case Qt::DisplayRole:
return m_data.at(index.row()).at(index.column());
case Qt::EditRole:
// 返回ComboBox选中的值或者空字符串
if (index.column() == 1 && !m_data.at(index.row()).at(0).isEmpty()) {
QComboBox *comboBox = qobject_cast<QComboBox*>(qvariant_cast<QWidget*>(m_data.at(index.row()).at(1)));
if (comboBox != nullptr)
return comboBox->currentText();
else
return "";
}
break;
case Qt::DecorationRole:
break;
}
return QVariant();
}
bool MyModel::setData(const QModelIndex &index, const QVariant &value, int role)
{
if (role != Qt::EditRole || !index.isValid())
return false;
// 更新第二列数据
if (index.column() == 0) {
m_data[index.row()][0] = value.toString(); // 更新第一列数据
emit dataChanged(createIndex(index.row(), 1), createIndex(index.row(), 1));
return true;
} else if (index.column() == 1) {
m_data[index.row()][1] = value.toString();
emit dataChanged(index, index);
return true;
}
return false;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
private:
QTreeView *m_treeView;
};
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
{
m_treeView = new QTreeView(this);
MyModel *model = new MyModel(this);
m_treeView->setModel(model);
setCentralWidget(m_treeView);
}
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
#include "main.moc"
需要注意的是,在setData函数中更新第二列数据时,要同时发出dataChanged信号,以便让树形控件显示最新的数据。此外,在data函数中返回第二列的数据时,如果当前行没有选中任何项,则应该返回空字符串。