在 QTreeview 中使用 QCombobox 委托项
Using a QCombobox delegate item within a QTreeview
我一直在尝试利用 Qt 的 MVC 类型编程来解决我要解决的特定问题。本质上,我想要一个 QTree,它的单元格中填充了各种 QComboBoxes。
我已经创建了我的委托 class 并且 Comboboxes 似乎被正确填充,此外,我正在使用一个自定义槽,当组合框索引更改时调用,但是我无法投射发件人将对象放入组合框中或找到另一种方法来确定在组合框中选择的索引。
如果有人能帮忙,我将不胜感激,我刚刚开始使用 Qt 的 MVC,我觉得我已经接近了,但我就是想不通这一点。
这是主窗口的一部分 class executeLogicWindow.cpp
executeLogicSetupWindow::executeLogicSetupWindow(QWidget *parent):QMainWindow(parent), ui(new Ui::executeLogicSetupWindow)
{
ui->setupUi(this);
int maxRow = 3,maxCol = 2;
treeModel = new QStandardItemModel(maxRow,maxCol,this);
treeItemDelegate = new controlObjectItemDelegate(this);
//tableView.setItemDelegateForColumn(1, delegate); // Column 0 can take any value, column 1 can only take values up to 8.
ui->dynamicObjectTreeView->setModel(treeModel);
ui->dynamicObjectTreeView->setItemDelegate(treeItemDelegate);
for(int row = 0;row< maxRow;row++)
{
for(int col = 0;col< maxCol;col++)
{
QModelIndex index = treeModel->index(row,col,QModelIndex());
//int value = (row+1) * (col+1);
//treeModel->setData(index,QVariant(value),Qt::EditRole);
treeModel->setData(index,"Click to Edit",Qt::EditRole);
}
}
connect(treeModel,SIGNAL(itemChanged(QStandardItem*)),this,SLOT(OnTreeItemCBChanged(QStandardItem *)));
ui->logicSetupTableWidget->setColumnCount(8);
ui->logicSetupTableWidget->setRowCount(1);
ui->logicSetupTableWidget->setHorizontalHeaderLabels(QString("Input Condition;Val A;Comparison;Val B;Reaction;Output Action").split(";"));
methodIndex = 0;
addComboRow(ui->logicSetupTableWidget->rowCount()-1);
}
executeLogicSetupWindow::~executeLogicSetupWindow()
{
delete ui;
}
void executeLogicSetupWindow::OnTreeItemCBChanged(QStandardItem *testItem)
{
QComboBox* combo = qobject_cast<QComboBox*>(sender());
//QComboBox* combo = qobject_cast<QComboBox*>(testItem);
QModelIndex testIndex = testItem->index();
qDebug() << testItem->index();
int row = testItem->index().row();
int col = testItem->index().column();
QVariant value = testItem->data();
//qDebug(testItem);
if (combo)
{
qDebug("It worked");
}
else
{
qDebug("Guess its fucked");
}
}
这里是委托人classcontrolobjectdelegate.cpp
#include "controlobjectitemdelegate.h"
#include "QAbstractItemDelegate"
#include "QAbstractItemModel"
controlObjectItemDelegate::controlObjectItemDelegate(QObject *parent) :
QItemDelegate(parent)
{
}
QWidget* controlObjectItemDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
QComboBox *cellComboBox = new QComboBox(parent);
cellComboBox->addItems(QString("Test 1;Test 2;Test 3").split(";"));
return cellComboBox;
}
void controlObjectItemDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const
{
int value = index.model()->data(index,Qt::EditRole).toInt();
QComboBox *cellComboBox = static_cast<QComboBox*>(editor);
cellComboBox->setCurrentIndex(value);
}
void controlObjectItemDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const
{
QComboBox *cellComboBox = static_cast<QComboBox*>(editor);
QStringList value;
for(int i=0;i<cellComboBox->count();++i)
{
value.append(cellComboBox->itemText(i));
}
model->setData(index, cellComboBox->currentText(), Qt::EditRole);
}
void controlObjectItemDelegate::updateEditorGeometry(QWidget *editor,const QStyleOptionViewItem &option, const QModelIndex &index) const
{
editor->setGeometry(option.rect);
}
首先你必须更正你的委托代码,在方法setEditorData
中使用index.model()->data(index, Qt::EditRole)
时它包含一个不能转换为int的字符串,所以你总是将索引设置为0,因此当您想要 select 另一个选项时,第一项显示为 selected,您必须将该代码更改为以下内容:
void controlObjectItemDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const
{
QString value = index.model()->data(index,Qt::EditRole).toString();
QComboBox *cellComboBox = static_cast<QComboBox*>(editor);
cellComboBox->setCurrentText(value);
}
没有获取委托编辑小部件的方法,但如果我们可以获得它的值,我们可以将该值存储在新角色中:
void controlObjectItemDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const
{
QComboBox *cellComboBox = static_cast<QComboBox*>(editor);
model->setData(index, cellComboBox->currentText(), Qt::EditRole);
# save the index of the QComboBox in the role Qt::UserRole + 1
model->setData(index, cellComboBox->currentIndex(), Qt::UserRole+1);
}
然后在插槽中得到该值:
void executeLogicSetupWindow::OnTreeItemCBChanged(QStandardItem *testItem)
{
QVariant variant = testItem->data(Qt::UserRole+1);
if(variant.isValid()){
qDebug()<<variant.toInt();
}
}
我一直在尝试利用 Qt 的 MVC 类型编程来解决我要解决的特定问题。本质上,我想要一个 QTree,它的单元格中填充了各种 QComboBoxes。
我已经创建了我的委托 class 并且 Comboboxes 似乎被正确填充,此外,我正在使用一个自定义槽,当组合框索引更改时调用,但是我无法投射发件人将对象放入组合框中或找到另一种方法来确定在组合框中选择的索引。
如果有人能帮忙,我将不胜感激,我刚刚开始使用 Qt 的 MVC,我觉得我已经接近了,但我就是想不通这一点。
这是主窗口的一部分 class executeLogicWindow.cpp
executeLogicSetupWindow::executeLogicSetupWindow(QWidget *parent):QMainWindow(parent), ui(new Ui::executeLogicSetupWindow)
{
ui->setupUi(this);
int maxRow = 3,maxCol = 2;
treeModel = new QStandardItemModel(maxRow,maxCol,this);
treeItemDelegate = new controlObjectItemDelegate(this);
//tableView.setItemDelegateForColumn(1, delegate); // Column 0 can take any value, column 1 can only take values up to 8.
ui->dynamicObjectTreeView->setModel(treeModel);
ui->dynamicObjectTreeView->setItemDelegate(treeItemDelegate);
for(int row = 0;row< maxRow;row++)
{
for(int col = 0;col< maxCol;col++)
{
QModelIndex index = treeModel->index(row,col,QModelIndex());
//int value = (row+1) * (col+1);
//treeModel->setData(index,QVariant(value),Qt::EditRole);
treeModel->setData(index,"Click to Edit",Qt::EditRole);
}
}
connect(treeModel,SIGNAL(itemChanged(QStandardItem*)),this,SLOT(OnTreeItemCBChanged(QStandardItem *)));
ui->logicSetupTableWidget->setColumnCount(8);
ui->logicSetupTableWidget->setRowCount(1);
ui->logicSetupTableWidget->setHorizontalHeaderLabels(QString("Input Condition;Val A;Comparison;Val B;Reaction;Output Action").split(";"));
methodIndex = 0;
addComboRow(ui->logicSetupTableWidget->rowCount()-1);
}
executeLogicSetupWindow::~executeLogicSetupWindow()
{
delete ui;
}
void executeLogicSetupWindow::OnTreeItemCBChanged(QStandardItem *testItem)
{
QComboBox* combo = qobject_cast<QComboBox*>(sender());
//QComboBox* combo = qobject_cast<QComboBox*>(testItem);
QModelIndex testIndex = testItem->index();
qDebug() << testItem->index();
int row = testItem->index().row();
int col = testItem->index().column();
QVariant value = testItem->data();
//qDebug(testItem);
if (combo)
{
qDebug("It worked");
}
else
{
qDebug("Guess its fucked");
}
}
这里是委托人classcontrolobjectdelegate.cpp
#include "controlobjectitemdelegate.h"
#include "QAbstractItemDelegate"
#include "QAbstractItemModel"
controlObjectItemDelegate::controlObjectItemDelegate(QObject *parent) :
QItemDelegate(parent)
{
}
QWidget* controlObjectItemDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
QComboBox *cellComboBox = new QComboBox(parent);
cellComboBox->addItems(QString("Test 1;Test 2;Test 3").split(";"));
return cellComboBox;
}
void controlObjectItemDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const
{
int value = index.model()->data(index,Qt::EditRole).toInt();
QComboBox *cellComboBox = static_cast<QComboBox*>(editor);
cellComboBox->setCurrentIndex(value);
}
void controlObjectItemDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const
{
QComboBox *cellComboBox = static_cast<QComboBox*>(editor);
QStringList value;
for(int i=0;i<cellComboBox->count();++i)
{
value.append(cellComboBox->itemText(i));
}
model->setData(index, cellComboBox->currentText(), Qt::EditRole);
}
void controlObjectItemDelegate::updateEditorGeometry(QWidget *editor,const QStyleOptionViewItem &option, const QModelIndex &index) const
{
editor->setGeometry(option.rect);
}
首先你必须更正你的委托代码,在方法setEditorData
中使用index.model()->data(index, Qt::EditRole)
时它包含一个不能转换为int的字符串,所以你总是将索引设置为0,因此当您想要 select 另一个选项时,第一项显示为 selected,您必须将该代码更改为以下内容:
void controlObjectItemDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const
{
QString value = index.model()->data(index,Qt::EditRole).toString();
QComboBox *cellComboBox = static_cast<QComboBox*>(editor);
cellComboBox->setCurrentText(value);
}
没有获取委托编辑小部件的方法,但如果我们可以获得它的值,我们可以将该值存储在新角色中:
void controlObjectItemDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const
{
QComboBox *cellComboBox = static_cast<QComboBox*>(editor);
model->setData(index, cellComboBox->currentText(), Qt::EditRole);
# save the index of the QComboBox in the role Qt::UserRole + 1
model->setData(index, cellComboBox->currentIndex(), Qt::UserRole+1);
}
然后在插槽中得到该值:
void executeLogicSetupWindow::OnTreeItemCBChanged(QStandardItem *testItem)
{
QVariant variant = testItem->data(Qt::UserRole+1);
if(variant.isValid()){
qDebug()<<variant.toInt();
}
}