我必须向继承的复杂面板编辑器中添加功能。基本的VSP编辑器面板类根据标准VMC范例进行初始化。目前,它支持创建QDoubleSpinBox类型的单元格(或项目)编辑器(用于ints,doubles等);用于布尔的QComboBox;还有一个QLineEdit框,用于其他所有内容。我需要添加一种情况,为某些语言QString枚举(例如“英语”,“法语”)创建特定的QComboBox。当我这样做时,我似乎永远无法选择下拉菜单中的任何文本项,并且该文本项会不断恢复为默认值。我在做什么错了,我该如何解决?
// cfgEdVSP.cpp
bool CfgEdVSP::init()
{
delete m_viewLayout;
delete m_view;
delete m_model;
// Setup GUI Model
m_model = new VSPTreeModel(m_schemaFile, m_nodes, this);
// Setup GUI View
m_view = new QTreeView(this);
m_view->setSelectionBehavior(QAbstractItemView::SelectRows);
m_view->setSelectionMode(QAbstractItemView::SingleSelection);
// Attach the Model to the View
m_view->setModel(m_model);
// Setup GUI Model-View Delegate
m_view->setItemDelegate(new VSPItemDelegate(this));
m_view->header()->resizeSection(1, 240);
m_view->header()->setResizeMode(0, QHeaderView::ResizeToContents);
m_view->header()->setResizeMode(1, QHeaderView::ResizeToContents);
m_view->header()->resizeSection(1, 140);
m_view->header()->setResizeMode(2, QHeaderView::ResizeToContents);
m_view->header()->resizeSection(2, 80);
m_view->header()->setResizeMode(3, QHeaderView::ResizeToContents);
m_view->header()->resizeSection(3, 80);
m_view->header()->setResizeMode(4, QHeaderView::Stretch);
m_view->header()->resizeSection(4, 80);
m_view->expandToDepth(0);
// The view will take the form of a QHBoxLayout (i.e. widgets lined up horizontally)
m_viewLayout = new QHBoxLayout();
m_viewLayout->addWidget(m_view, 1);
addMainLayout(m_viewLayout);
...
// setup context menu used for editing (similar to CfgEdADG <R-CLK>, copy/paste, etc )
createActions();
// [1] set property Qt:CustomContextMenu so that the view will emit a
// customContextMenuRequested() signal (see below).
m_view->setContextMenuPolicy(Qt::CustomContextMenu);
m_valPopup = new QMenu(m_view);
...
// [2] Ensure that we have a SLOT to match the customContextMenuRequested signal
connect(m_view, SIGNAL(customContextMenuRequested(const QPoint &)),
SLOT(vspTableContextMenuRequested(const QPoint &)));
return true;
}
// VSPTreeModel.h
class VSPTreeModel : public QAbstractItemModel
{
Q_OBJECT
public:
VSPTreeModel(const QString& schemaFile,
const QVector<VSPConfigNode>& nodes,
QObject *parent = 0);
~VSPTreeModel();
...
bool setData(const QModelIndex &index, const QVariant &value,
int role = Qt::EditRole);
}
// VSPTreeModel.cpp
bool VSPTreeModel::setData(const QModelIndex &index, const QVariant &value,
int role)
{
QString strValue = value.toString();
if (role != Qt::EditRole)
return false;
VSPTreeItem *item = getItem(index); //Note if index is invalid will return rootItem
bool result = item ? item->setData(index.column(), value) : false;
if (result)
emit dataChanged(index, index);
return result;
}
// VSPItemDelegate.h
class VSPItemDelegate : public QStyledItemDelegate {
Q_OBJECT
public:
VSPItemDelegate(QObject* parent = 0) : QStyledItemDelegate(parent){} m_logger(Logger::getInstance("VSP")){}
QWidget* createComboBoxEditor(QWidget *parent,
const QStyleOptionViewItem & option,
const QModelIndex & index ) const;
QWidget* enumEditor(QWidget* parent, const QStyleOptionViewItem
& option, const QModelIndex & index) const;
private:
Logger *m_logger;
};
// VSPItemDelegate.cpp
QWidget * VSPItemDelegate::createEditor ( QWidget * parent, const QStyleOptionViewItem & option, const QModelIndex & index ) const
{
VSPTreeItem* item = reinterpret_cast<VSPTreeItem*> (index.internalPointer());
ConfigTableDataset* data = item->getData();
// We're going to call the PARENT CLASS createEditor method...
// This returns the widget used for editing the data item specified by
// the index value given, UNLESS...
// If data is an ENUM or BOOL then ensure a QComboBox is created
QWidget *editor = NULL;
// CODE I ADDED START ##########################################
if ( (data->type() == CfgNode::ENUM) )
{
editor = ((QComboBox *)enumEditor(parent, option, index));
return editor;
}
// CODE I ADDED END ###########################################
else
{
editor = QStyledItemDelegate::createEditor(parent, option, index);
}
if (!index.internalPointer())
return editor;
if(QDoubleSpinBox* sbox = dynamic_cast<QDoubleSpinBox*>(editor))
{
...
}
else if(QComboBox* cbox = dynamic_cast<QComboBox*>(editor))
{
if(data->type() == CfgNode::BOOL) {
cbox->setItemText(0, cbox->itemText(0).toLower());
cbox->setItemText(1, cbox->itemText(1).toLower());
}
}
else if (QLineEdit* editBox = dynamic_cast<QLineEdit*>(editor))
{
...
}
else
{
// UNKNOWN TYPE OF EDITOR
...
}
return editor;
}
// CODE I ADDED START ##########################################
QWidget * VSPItemDelegate::enumEditor(QWidget* parent, const QStyleOptionViewItem & option, const QModelIndex & index) const
{
QComboBox* cbox = new QComboBox(parent);
QStringList languageList;
languageList << "english" << "french";
cbox->insertItems(0, languageList);
return cbox;
}
// CODE I ADDED END ###########################################
无论是否进行了更改,数值,布尔值和文本编辑的预期结果都可以正常工作并包含正确的值,然后到了VSPTreeModel :: setData()将新值放入模型的时间。面板屏幕也已正确刷新。请注意,这似乎是QStyledTemDelegate的“默认”行为,因为没有显式的VSPItemDelegate :: SetModelData()方法。但是,对于其他枚举QComboBox情况,在执行VSPTreeModel :: setData()时,该值为INCORRECT(例如,当其应为“ french”且面板始终刷新时,将返回“ english”,并返回到默认值:“ english”) 。此外,我发现VSPItemDelegate :: createEditor()方法被称为AT ALL感到很奇怪,因为我为此找不到任何SIGNAL / SLOT连接链接。我对Qt很陌生,所以不知道这种默认行为吗?!