c++ - 在 QTreeview 中使用 QCombobox 委托(delegate)项

标签 c++ qt model-view-controller qtreeview qcombobox

我一直在尝试利用 Qt 的 MVC 类型编程来解决我要解决的特定问题。本质上,我想要一个 QTree,它的单元格中填充了各种 QComboBoxes。

我已经创建了我的委托(delegate)类并且 Comboboxes 似乎被正确填充,此外我正在使用一个自定义槽在组合框索引更改时被调用但是我无法将发件人对象转换为组合框或找到我可以确定在组合框中选择的索引的另一种方法。

如果有人能提供帮助,我将不胜感激,我刚刚开始使用 Qt 的 MVC,我觉得我已经很接近了,但我就是想不通这一点。

这是主窗口类 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");
}
}

这里是委托(delegate)类controlobjectdelegate.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) this包含一个无法转换为 int 的字符串,因此您始终将 as index 设置为 0,因此当您要选择另一个选项时,第一个项目显示为已选中,您必须将该代码更改为以下代码:

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);
}

没有获取委托(delegate)编辑小部件的方法,但如果我们可以获得它的值,我们可以将该值存储在一个新角色中:

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();
    }
}

关于c++ - 在 QTreeview 中使用 QCombobox 委托(delegate)项,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48892319/

相关文章:

c++ - 如何在 Xcode 中传递命令行参数

c++ - 从另一个线程调用函数

python - 指向函数不工作的 Django 模型变量

java - Spring @ResponseBody View 解析

C++ 与 Eclipse 没有工具链?

string.size() 的 C++ 输出不正确

c++ - 自动更新 QDateTimeEdit 以显示当前系统日期和时间

javascript - 将 AngularJS 与 SpringMVC 结合使用 - 为什么以及如何?

c++ - C++ 中是否有实际的 8 位整数数据类型

c++ - 使用 Qt 获取页面内容