QComboBox in QTreeView
-
Hi,
after searching everywhere for how to implement combo boxes in a tree view, I have come up with a model and delegate (see code below). Columns 2 & 3 contain combo boxes. I have the following problems though:
1: When not having the paint method draw a combo box, I do see the correct current item in the combo box. But obviously I only see a combo box when clicking(editing) the cell. Hence having the paint method draw a combo box. But now the current item doesn't show, only a blank combo box. Only when I then click on the cell does the current item show again. Why?
2: The combo boxes in columns 2 & 3 and a progress bar in column 4 are drawn with a certain width. How can I change that width?
Thanks
ahenricloadfilemodel.h
@
class LoadFileModel : public QAbstractItemModel
{
Q_OBJECTpublic:
LoadFileModel(ConfigFileInterface *interface, QObject *parent = 0);QVariant data(const QModelIndex &index, int role) const; Qt::ItemFlags flags(const QModelIndex &index) const; QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const; QModelIndex parent(const QModelIndex &index) const; int rowCount(const QModelIndex &parent = QModelIndex()) const ; int columnCount(const QModelIndex &parent = QModelIndex()) const;
private:
ConfigFileInterface *confInterface;};
@loadfilemodel.cpp
@#include "loadfilemodel.h"int LoadFileModel::rowCount(const QModelIndex & /parent/) const
{
return confInterface->getNumItems();
}int LoadFileModel::columnCount(const QModelIndex & /parent/) const
{
return 6;
}QVariant LoadFileModel::data(const QModelIndex &index, int role) const
{
if(role == Qt::DisplayRole)
{
switch(index.column())
{
case 0:
return confInterface->getFilename(index.row());
case 1:
break;
case 2:
return confInterface->getSRU(index.row());
case 3:
case 4:
case 5:
break;
}
}return QVariant();
}
Qt::ItemFlags LoadFileModel::flags(const QModelIndex &index) const
{
if (!index.isValid())
return 0;if(index.column() == 2 || index.column() == 3) { return QAbstractItemModel::flags(index) | Qt::ItemIsEditable; } return QAbstractItemModel::flags(index);
}
QModelIndex LoadFileModel::index(int row, int column, const QModelIndex &parent) const
{
return createIndex(row, column);
}@loadfileviewdelegate.h
@class LoadFileViewDelegate: public QItemDelegate
{
Q_OBJECTpublic:
LoadFileViewDelegate(QObject *parent = 0);void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index ) const; 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;
};
@loadfileviewdelegate.cpp
@#include "loadfileviewdelegate.h"
void LoadFileViewDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option,
const QModelIndex &index) const
{
if(index.column() == 2 || index.column() == 3)
{
QStyleOptionComboBox comboBoxOption;
comboBoxOption.rect = option.rect;
comboBoxOption.state = QStyle::State_Active;
comboBoxOption.frame = true;
comboBoxOption.currentText = index.model()->data(index).toString();
QApplication::style()->drawComplexControl(QStyle::CC_ComboBox, &comboBoxOption, painter);
//QApplication::style()->drawControl(QStyle::CE_ComboBoxLabel, &comboBoxOption, painter);
}
else if(index.column() == 4)
{
//set up a QStyleOptionProgressBar to precisely mimic the environment of a progress bar
}
else
{
QItemDelegate::paint(painter, option, index);
}}
QWidget *LoadFileViewDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option,
const QModelIndex &index) const
{
QComboBox *editor = new QComboBox(parent);if(index.column() == 2) { QStringList availTargets; availTargets << "A" << "B" << "C" << "D"; editor->addItems(availTargets); } else if(index.column() == 3) { QStringList loadTypes; loadTypes << "Program" << "Verify" << "Prog/Verify"; editor->addItems(loadTypes); } else { return QItemDelegate::createEditor(parent, option, index); } return editor;
}
void LoadFileViewDelegate::setEditorData(QWidget *editor,
const QModelIndex &index) const
{
if(index.column() == 2 || index.column() == 3)
{
QString value = index.model()->data(index, Qt::DisplayRole).toString();
QComboBox comboBox = static_cast<QComboBox>(editor);//set the index of the combo box comboBox->setCurrentIndex(comboBox->findText(value, Qt::MatchExactly)); } else { QItemDelegate::setEditorData(editor, index); }
}
void LoadFileViewDelegate::setModelData(QWidget *editor, QAbstractItemModel *model,
const QModelIndex &index) const
{
if(index.column() == 2 || index.column() == 3)
{
QComboBox comboBox = static_cast<QComboBox>(editor);
model->setData(index, comboBox->currentText(), Qt::EditRole);
}
else
{
QItemDelegate::setModelData(editor, model, index);
}
}@ -
can you craete a short exanple that shows your problem and put it somewhere in the net as zip file?
perhaps also a picture that shows your problem.
That would make finding a solution easier.... -
To my question 1: the line in configfileviewdelegate.cpp that is commented out needs to be activated, then it works (draws the current label):
@
QApplication::style()->drawControl(QStyle::CE_ComboBoxLabel, &comboBoxOption, painter);
@
To my question 2: use QTreeView->setColumnWidth().