[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