QComboBox in a QTableView
I'm making an app for Maemo & Symbian.
In the app you can do stuff (not important).
At the end you get an overview in a QTableView.
I want the user to be able to edit the data of the overview.
In one column the user can select stuff from a QComboBox.
In the delegate I want to remove the QComboBox from the QTableView when the user moves to another field (in the QTableView or else where) and loses focus.
The question is how do I do this, removing? The QComboBox doesn't seem to emit a signal when it loses focus...according to the documentation.
Theo Kromhout van der Meer
Maybe this will help you: http://doc.trolltech.com/4.7.old/model-view-programming.html
The standard QItemDelegate class informs the view when it has finished editing by emitting the closeEditor() signal. The view ensures that the editor widget is closed and destroyed. In this example, we only provide simple editing facilities, so we need never emit this signal.
Subclass QItemDelegate, reimplement QWidget * QItemDelegate::createEditor()
Also you might want to have a look at QItemEditorFactory class
Better go with "QStyledItemDelegate":http://doc.qt.nokia.com/4.7/qstyleditemdelegate.html as a base class to inherit from, instead of QItemDelegate. The former is the default anyways, so no surprises.
You must reimplement the following virtual methods:
virtual QWidget *createEditor( QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index ) const;
virtual void setEditorData ( QWidget *editor, const QModelIndex &index ) const;
virtual void setModelData ( QWidget *editor, QAbstractItemModel *model, const QModelIndex &index ) const;
In all three functions, first check if you are handling an index that needs a combo box. If no, then call the base class' functions (functions of QStyledItemDelegate with the same name) and return their value, if any.
In createEditor() create and populate the combo box.
In setEditorData() you select the right choice in the combo box according to the already available data of the index (if any). Call index.data(role) to get the data.
In setModelData() get the selected value of your combo box and call model->setData(index, value, role) to save it in the model.
The editor pointer is your combo box. You can cast it to QComboBox using qobject_cast. Check the casted pointer!
I've got 'C++ GUI Programming with Qt 4 2nd edition' here.
Apparently I was steered the wrong direction by the book.
In the last piece of chapter 10 'Implementing Custom Delegates'
in the createEditor function:
connect(timeEdit, SIGNAL(editingFinished()), this, SLOT(commitAndCloseEditor()));
the private method:
QTimeEdit* editor = qobject_cast<QTimeEdit*>(sender());
I thought that I had to do this for all the editors that I create.
But if the book is wrong, that can happen.
[edit: code highlighted / Denis Kormalev]
Theo Kromhout van der Meer, please use @ tags around your code. It will increase readability a lot.
Could you please add @ tags around the connect statement, the arugments are missing.
I don't know the book nor how they implement it and which base class they inherit from. I only use QStyledItemDelegate as a base class for my own delegates. Reimplementing the said methods do the trick for me. I do not reimplement more methods. One should consider updateEditorGeometry(), too to get the combo boxes' sizes done right.
I'll create a wiki article with some working code.
I would bet that the connect statement generates a warning about a non-existing signal on runtime. editingFinished() is a signal of QLineEdit (but we're talking about combo boxes) or of QAbstractSpinBox (e.g. used by a QTimeEdit, also not a combo box).
If you want to go this way, you would have to connect signal QComboBox::activated() to your slot; this is emitted when the user has choosen an item.
Above, I just rewrote the example whats in the book. The example there used a QTimeEdit field as an editor. That is why I asked my question. I want to use a QComboBox but I saw that doesn't work that way, because it doesn't have a similar editingFinished signal.
I just wanted to know how to solve this.
But I am all for it to leave the above code out and give it a try.
My N900 is running Qt 4.6. I have to do some coding and then I will run it in the simulator and then on the N900 and I will just test it.
I just added the wiki article "Combo Boxes in Item Views ":http://developer.qt.nokia.com/wiki/Combo_Boxes_in_Item_Views. You can use this sample code as a starting point.