从QStyledItemDelegate中的组合框中调用对话框
所以我在这里是QAbstractTableModel的委托代码。第二列(索引= 1)始终是一个组合框。该comboBox有我的模拟中给定单元可以执行的动作列表。点击构建或训练等特定动作后,我想要弹出一个对话框给用户一组选择。在做出选择之后,代表应该更新模型的数据并继续前进。从QStyledItemDelegate中的组合框中调用对话框
这里是我碰到的障碍。如果我尝试从setModelData(),setEditorData()调用对话框,那些函数是常量,所以我不能分配对话框的结果给任何东西。
我试图做的是从createEditor()中创建的QComboBox连接信号indexChanged(QString)。这至少允许我分配结果并仅在做出适当选择时调用对话框。但是我不断收到Seggy故障,并且QTCreator中的跟踪不会着陆在C代码上(33次调用程序集)。我不确定为什么我得到了那个seggy。
当我尝试这种方法时,对话框出现后,表格不再有组合框。它恢复到之前的状态,并且只要程序离开我为QComboBox :: indexChanged(QString)创建的插槽,就发生了seggy。
任何帮助将不胜感激,
JEC
DelegateAction.h
#ifndef DELEGATEACTION_H
#define DELEGATEACTION_H
#include <QVariant>
#include <QStyledItemDelegate>
#include <QString>
#include <QApplication>
#include <QWidget>
#include <QLabel>
#include <QComboBox>
#include <QProgressBar>
#include <QMouseEvent>
#include <JECMessageTable.h>
#include <UnitBase.h>
#include <ModelListUnit.h>
class DelegateAction : public QStyledItemDelegate
{
Q_OBJECT
public:
explicit DelegateAction(QObject *parent = 0);
~DelegateAction();
QWidget* createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const;
void setEditorData(QWidget *editor, const QModelIndex &index) const;
void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const;
void updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const;
QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const;
public slots:
void setUnits(QList<Unit*>* units);
protected:
void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const;
//bool editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option, const QModelIndex &index);
private slots:
void comboChanged(QString string);
void comboDestroyed();
private:
bool comboUpdated;
const UnitBase* selectedUnit;
ModelListUnit *model; // The model for the JECMessageTable.
QList<Unit*>* units; // The current list of units.
};
#endif // DELEGATEACTION_H
DelegateAction.cpp
#include "DelegateAction.h"
DelegateAction::DelegateAction(QObject *parent) :
QStyledItemDelegate(parent),
selectedUnit(0),
model(0)
{
}
DelegateAction::~DelegateAction()
{
delete model;
}
QWidget * DelegateAction::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
QWidget* editor = 0;
switch (index.column())
{
case 0:
default:
{
editor = new QLabel();
break;
}
case 1:
{
QComboBox* combo = new QComboBox(parent);
combo->addItem("Idle");
combo->addItem("Gather");
combo->addItem("Train");
combo->addItem("Build");
combo->addItem("Upgrade");
editor = combo;
// connect(combo, SIGNAL(currentIndexChanged(QString)), this, SLOT(comboChanged(QString)));
// connect(combo, SIGNAL(destroyed()), this, SLOT(comboDestroyed()));
break;
}
case 4:
{
editor = new QProgressBar(parent);
break;
}
}
editor->installEventFilter(const_cast<DelegateAction*>(this));
return editor;
}
void DelegateAction::setEditorData(QWidget *editor, const QModelIndex &index) const
{
QVariant value = index.model()->data(index, Qt::DisplayRole);
switch (index.column())
{
case 0:
default:
{
QLabel* label = static_cast<QLabel*>(editor);
label->setText(value.toString());
break;
}
case 1:
{
QComboBox* combo = static_cast<QComboBox*>(editor);
combo->setCurrentIndex(combo->findText(value.toString()));
break;
}
case 4:
{
QProgressBar* progress = static_cast<QProgressBar*>(editor);
progress->setValue(value.toInt());
break;
}
}
}
void DelegateAction::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const
{
QVariant value;
switch (index.column())
{
case 0:
default:
{
value = static_cast<QLabel*>(editor)->text();
break;
}
case 1:
{
QString string = static_cast<QComboBox*>(editor)->currentText();
switch (Action::getType(string))
{
case Action::INVALID:
{
return;
}
case Action::IDLE:
{
return;
}
case Action::GATHER:
{
return;
}
case Action::BUILD:
{
return;
}
case Action::TRAIN:
{
// Summon the build choice dialog.
if (units == 0)
{
return;
}
JECMessageTable messageBox(this->model, "Test");
messageBox.exec();
if (messageBox.result() == QDialog::Accepted)
{
//selectedUnit = this->model->getSelectedUnit();
}
else
{
//selectedUnit = 0;
}
return;
}
case Action::MORPH:
{
return;
}
case Action::UPGRADE:
{
}
}
break;
}
case 4:
{
value = static_cast<QProgressBar*>(editor)->value();
break;
}
}
model->setData(index, value);
}
void DelegateAction::updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
editor->setGeometry(option.rect);
}
QSize DelegateAction::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const
{
if (index.column() == 4)
{
return QSize(option.rect.width(), option.rect.height());
}
else
{
return QStyledItemDelegate::sizeHint(option, index);
}
}
void DelegateAction::paint(QPainter *painter, const QStyleOptionViewItem &item, const QModelIndex &index) const
{
if (index.column() == 4 && index.isValid() == true)
{
QStyleOptionProgressBarV2 progress;
progress.minimum = 0;
progress.maximum = 100;
progress.progress = index.data().toInt();
progress.rect = QRect(item.rect.x(), item.rect.y(), item.rect.width(), item.rect.height());
QApplication::style()->drawControl(QStyle::CE_ProgressBar, &progress, painter);
}
else
{
// Painting the cells normally.
QStyledItemDelegate::paint(painter, item, index);
}
}
void DelegateAction::setUnits(QList<Unit*> *units)
{
this->units = units;
if (units != 0)
{
if (units->length() > 0)
{
model = new ModelListUnit(&units->at(0)->getUnitBase()->getOptionUnit());
}
}
}
void DelegateAction::comboChanged(QString string)
{
// comboUpdated = true;
// switch (Action::getType(string))
// {
// case Action::INVALID:
// {
// return;
// }
// case Action::IDLE:
// {
// return;
// }
// case Action::GATHER:
// {
// return;
// }
// case Action::BUILD:
// {
// return;
// }
// case Action::TRAIN:
// {
// // Summon the build choice dialog.
// if (units == 0)
// {
// return;
// }
// JECMessageTable messageBox(model, "Test");
// messageBox.exec();
// if (messageBox.result() == QDialog::Accepted)
// {
// selectedUnit = model->getSelectedUnit();
// }
// else
// {
// selectedUnit = 0;
// }
// return;
// }
// case Action::MORPH:
// {
// return;
// }
// case Action::UPGRADE:
// {
// }
// }
}
void DelegateAction::comboDestroyed()
{
disconnect(this, SLOT(comboChanged(QString)));
disconnect(this, SLOT(comboDestroyed()));
}
//bool DelegateAction::editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option, const QModelIndex &index)
//{
// QStyledItemDelegate::editorEvent(event, model, option, index);
// if (comboUpdated == true && index.isValid() == true)
// {
// comboUpdated = false;
// if (selectedUnit != 0)
// {
// units->at(index.row());
// }
// }
//}
我想通了这一点。如果任何人都对类似的东西感兴趣,我可以分类为QTableView。
在QTableView中我使用QTableView :: setIndexWidget()来使用QComboBoxes和QProgressBars。基本上我的子类有两种类型的小部件的QList,它们与表中的特定行相对应。
- 获得ComboBoxEditor从QComboBox
- 保持Action对象中ComboBoxEditor(存储在模型索引数据)
- 当委托的comboChanged()被调用,您可以访问通过发送者(行动),这是ComboBoxEditor 。
请参考官方示例StarDelegate。
http://doc.qt.io/qt-5/qtwidgets-itemviews-stardelegate-example.html
你能发表这个子类的代码吗? – thestar