[Qt-interest] Custom model and delegate for QComboBox

wim.delvaux at adaptiveplanet.com wim.delvaux at adaptiveplanet.com
Thu Oct 29 00:16:25 CET 2009


I think you need to set the Delegate on the QDataWidgetMapper and not on the 
combobox.

W

On Wednesday 28 October 2009 16:53:16 Wolfgang Pausch wrote:
> Hello,
>
> sorry for asking again.  I´ve spent several hours trying to figure out
> where my mistake is, but I didn´t make it work yet :-(
>
> What do I have?
> - A QComboBox
> - A custom model for the QComboBox
> - A custom delegate implementing setEditorData for the QComboBox
> - Optionally a QDataWidgetMapper which maps the QComboBox and some other
> widgets.  (the problem doesn´t disappear if I remove the QComboBox from the
> mapper).
>
> Am I right that those objects should interact in the following way:
> - The QComboBox has some items
> - Each of them corresponds to one QModelIndex in my QComboBox-internal
> custom model - The setEditorData method in my QComboBox-internal custom
> delegate should translate the values from the custom model into the values
> displayed by the QComboBox - The mapping enforced by the QDataWidgetMapper
> at each time only knows about the current item, mapping it to some
> QModelIndex entry of the model of the widget containing my QComboBox
>
> Problem:
> - I see the entries of my custom model 1:1 in the QComboBox, i.e. I see 1,
> 2, 3. - My custom delegates setEditorData would translate 1,2,3 into some
> human readable strings FOO, BAR, etc. - But it is not called, and I have no
> idea why not.
>
> What I could debug:
> - After setting the delegate, it actually is being set.
> - The only setEditorData methods in any *Delegate classes are called from
> my QDataWidgetMapper during toFirst(). - However, my problem doesn´t
> disappear if I remove my QComboBox from the mapper.
>
> Does anyone have some hint for me?
>
> Thanks,
>
> Wolfgang
>
> On Fri, 23 Oct 2009 15:03:50 +0200
>
> Wolfgang Pausch <wolfgang.pausch at uibk.ac.at> wrote:
> > 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(DatabaseCon
> >text *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;
> > 	}
> > }
> >
> >
> > _______________________________________________
> > Qt-interest mailing list
> > Qt-interest at trolltech.com
> > http://lists.trolltech.com/mailman/listinfo/qt-interest
>
> _______________________________________________
> Qt-interest mailing list
> Qt-interest at trolltech.com
> http://lists.trolltech.com/mailman/listinfo/qt-interest






More information about the Qt-interest-old mailing list