[Qt-interest] Custom model and delegate for QComboBox
Wolfgang Pausch
wolfgang.pausch at uibk.ac.at
Fri Oct 23 15:03:50 CEST 2009
Hello,
I am trying to implement a custom model and a custom delegate for a QComboBox. What I want to do is:
- the model contains some codes loaded from a datamodel
- the delegate transforms them into human-readable strings
However, my implementation so far simply doesn´t call setModelData. It seems to ignore the delegate.
Can anyone, based on the code snippets below, give me a hint regarding what is my mistake?
Especially: I don´t want to edit anything in my ComboBox, just choose one of several choices. Am I correct that I only need to overwrite setEditorData?
Do I have to do something special in order to use this delegate? Do I have to take care about the view? Is my assumption correct that once the model is set, it should call the delegate itself, so I don´t have to call some dataChanged signals etc. explicitely in the code below (e.g. in addChoice)?
I once became problems because I missed a const keyword when overwriting some model method, but as far as I see, the signature of ComboBoxDelegate::setEditorData is correct. Do you see any problem here? (if this method would be called anything would be fine).
Thanks,
Wolfgang
Where I set things up:
QComboBox* MitgliedAttributeWidgetFactory::constructMitgliedsartComboBox(DatabaseContext *databaseContext) {
CodeManager *codeManager = databaseContext->getCodeManager();
ComboBoxModel *model = new ComboBoxModel();
model->addChoice(codeManager, "LANDESVERBAND_ORDENTLICH");
model->addChoice(codeManager, "LANDESVERBAND_AUSSERORDENTLICH");
model->addChoice(codeManager, "LANDESVERBAND_VEREINSMITGLIED");
ComboBoxDelegate *delegate = new ComboBoxDelegate(databaseContext);
QComboBox* mitgliedsartComboBox = new QComboBox();
mitgliedsartComboBox->setItemDelegate(delegate);
mitgliedsartComboBox->setModel(model);
return mitgliedsartComboBox;
}
The model:
class ComboBoxModel : public QAbstractListModel {
public:
ComboBoxModel();
~ComboBoxModel();
void addChoice(CodeManager *codeManager, QString name);
int rowCount(const QModelIndex &parent) const;
QVariant data(const QModelIndex &index, int role) const;
private:
std::vector<CodeValue*> choices;
};
ComboBoxModel::ComboBoxModel() {
choices = std::vector<CodeValue*>();
}
ComboBoxModel::~ComboBoxModel() {
for (std::vector<CodeValue*>::const_iterator it = choices.begin(); it != choices.end(); it++) {
CodeValue* choice = *it;
delete choice;
}
}
void ComboBoxModel::addChoice(CodeManager *codeManager, QString name) {
CodeValue* choice = codeManager->getCodeValueByName(name);
choices.push_back(choice);
}
int ComboBoxModel::rowCount(const QModelIndex &parent) const {
return choices.size();
}
QVariant ComboBoxModel::data(const QModelIndex &index, int role) const {
if (!index.isValid()) {
return QVariant();
}
if (role == Qt::TextAlignmentRole) {
return int(Qt::AlignRight | Qt::AlignVCenter);
} else if (role == Qt::DisplayRole || role == Qt::EditRole) {
int row = index.row();
CodeValue *choice = choices[row];
int choiceId = choice->getId();
return QVariant(choiceId);
} else {
return QVariant();
}
}
The delegate:
class ComboBoxDelegate : public QItemDelegate {
Q_OBJECT
public:
ComboBoxDelegate(DatabaseContext *ndatabaseContext);
void setEditorData(QWidget *editor, const QModelIndex &index ) const;
void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index ) const;
private:
DatabaseContext *databaseContext;
};
ComboBoxDelegate::ComboBoxDelegate(DatabaseContext *ndatabaseContext) {
databaseContext = ndatabaseContext;
}
void ComboBoxDelegate::setEditorData(QWidget *editor, const QModelIndex &index ) const {
std::cout << "called setEditorData" << std::endl;
QComboBox *comboBox = qobject_cast<QComboBox*>(editor);
const QAbstractItemModel *model = index.model();
QVariant data = model->data(index, Qt::DisplayRole);
bool transformOk;
int codeBehindCombobox = data.toInt(&transformOk);
if (comboBox == NULL) {
std::cerr << "ComboBoxDelegate::setEditorData says: comboBox is NULL. Maybe this is a bug." << std::endl;
} else if (!transformOk) {
std::cerr << "ComboBoxDelegate::setEditorData says: Value behind comboBox is not an int. Maybe this is a bug." << std::endl;
} else {
CodeManager *codeManager = databaseContext->getCodeManager();
CodeValue *codeValue = codeManager->getCodeValueById(codeBehindCombobox);
int row = index.row();
int column = index.column();
std::cout << "ComboBoxDelegate::setEditorData called for row " << row << " and column " << column << std::endl;
comboBox->setItemText(row, codeValue->getKurzText());
delete codeValue;
}
}
More information about the Qt-interest-old
mailing list