[Interest] Most direct path to using a QComboBox to edit a cell in a QTableView?

K. Frank kfrank29.c at gmail.com
Tue Jun 26 16:39:11 CEST 2012


Hi Tony!

Thanks for your follow-up questions.  I've tried to answer them
in line, below.

Before I do, please let me quickly summarize what I think my
question is.

I think I have to get my hands on the appropriate existing delegate.
(I don't actually know whether the delegate is associated primarily
with the view (QTableView) or the model (QSqlTableModel).  Then
I think I have to get my hands on the delegate's QItemEditorFactory.
Then I think I have to register with the QItemEditorFactory a subclass
of QItemEditorCreatorBase that will create instances of QComboBox
that are populated with the correct items.  I think that I can use
the template class QStandardItemEditorCreator specialized on
QComboBox for this, but I am a little hazy on how I would then
populate the QComboBox with the appropriate items.

Assuming that this is all on the right track, what I don't know how
to do is get my hands on the right delegate and QItemEditorFactory.

(I don't think that I have to implement a custom delegate or a
custom editor.  I think that all I have to do is provide an appropriate
instance of a QComboBox to the existing delegate using the
QItemEditorFactory machinery.  But I don't know how.)

On Tue, Jun 26, 2012 at 1:04 AM, Tony Rietwyk <tony at rightsoft.com.au> wrote:
> Hi Frank,
>
> What does the standard delegate do for your model/view at the moment?

Right now, if I have an existing row in my QTableView, I can click
in a cell and edit it.  If it's a string, I just edit it.  If it's a number,
what appears to be a QDoubleSpinBox pops up in place, and I
can edit it either by typing or by using the spin-box arrows.

(This is all fine, and basically good enough.  But I want to get
"fancy" and select my strings from a combo-box, rather than
type them in by hand.)

If I programmatically add a new row (QSqlTableModel::insertRows()),
a row with blank cells appears in my QTableView, and I can enter new
data essentially as describe above.

I get this behavior "for free" in that I am using only Qt-provided
classes:  QTableView and QSqlTableModel.  I don't do anything
directly with delegates, but I believe that QTableView is using a
QStyledItemDelegate under the hood.

Specifically, what I believe is happening (from the documentation)
is that QTableView is using QStyledItemDelegate to display and
manage its cells.  I'm guessing that QStyledItemDelegate is
using QItemEditorFactory::defaultFactory() to get the editors
it uses for editing the cells.  According to the QItemEditorFactory
documentation. "the standard factory implementation provides
editors for a variety of data types."  Indeed, the accompanying
table shows that a QLineEdit is used to edit a QString and that
a QDoubleSpinBox is used to edit a double.  (As you mention
below, a QComboBox is used to edit a bool, but I don't see this
myself, as my tables don't have any bools in them.)

> I
> can't recall the specifics, but it certainly uses combo boxes at the moment
> - eg, for boolean fields (which I think is painful, but anyway).
>
> I think you need to give more information about what you are expecting.

What I want to have happen is almost exactly the same as what
is happening now.  I can edit existing rows as describe above,
and if I programmatically add a row, I can edit its initially blank
cells to enter the new data.  The only thing I want to be different
is that QString cells are to be edited by selecting an item from a
QComboBox, rather than typing into what appears to be a
QLineEdit.

> For
> example, you include 'insert' as an action.  But what does this mean?

By "insert" I mean adding a new row to the QTableView.  I do so
by adding a row to the underlying QSqlTableModel, and a blank
row then shows up in the QTableView.  (If I type "legal" data into
the new row, QSqlTableModel inserts it into my database table.)

But at the delegate / editor level, I don't think inserting a new row
is any different that editing an existing one.

> If a
> user types an entry not already in the list, what do you expect to happen?

I believe this can be prevented by setting the QComboBox::editable
property to false.  (If a user did manage to do this, my database
wouldn't let QSqlTableModel insert or update the row because of
constraints, so there would be no real problem, but it would be
confusing for the user.)

> Which table would the new entry be inserted into?

I call QSqlTableModel::insertRows on a specific instance of a
QSqlTableModel.  The QSqlTableModel is connected on the front
end to a specific instance of a QTableView, and on the back end to
a specific table in a database.  The QTableView that is connected
to the QSqlTableModel gets a blank row added to it, and when
(legal) data is type into this blank row, QSqlTableModel finds
out and inserts the data into the database table to which it is
connected.

>
> Where should the combo box get its values from?

The QComboBox will have its entries populated programmatically.
(In fact, its entries will come from a table in the database, so I
expect that I will populate the QComboBox by calling
QComboBox:::setModel() with a QSqlTableModel connected to
the database table in question.)

> Yes I agree that the model view classes take a while to grok.

Yes, there are so many layers.  I can't figure out where and how
I am supposed to "inject" my QComboBox to be used as an
editor (or even if I'm on the right track here).

> Tony.

Thanks for your help.


K. Frank


>> Sent: Tuesday, 26 June 2012 2:36 PM
>>
>> Hello List!
>>
>> I have a QTableView and I would like to use a QComboBox to insert and
>> modify its entries.  I'm looking for the simplest way to do this that uses
> as
>> much unmodified Qt functionality as possible.
>>
>> At the moment I am thinking that I can use the class template
>> QStandardItemEditorCreator specialized on QComboBox as the most direct
>> way to do this.  Two questions:
>>
>> Am I on the right track here?
>>
>> What specifically do I need to do to make this work?  I don't really see
> the full
>> end-to-end logic (i.e., starting with a specific instance of a
>> QTableView) of how to hook all of the plumbing together.
>>
>> (The model backing the QTableView happens to be a QSqlTableModel,
>> although -- and please correct me if I'm wrong -- this should be
> irrelevant.)
>>
>> I've looked at a number of examples in the Qt documentation but the ones
>> I've found seemed to be concerned with writing custom delegates and
>> editors, rather than using existing delegate and editor classes already
>> provided by Qt.  Although I do believe I could achieve my end goal with a
>> custom delegate, I think using one would be more complicated than
>> necessary.  For example, as I understand it, QTableView uses QItemDelegate
>> as its default delegate, and that I can achieve my goal without changing
> this.
>>
>> Assuming that I am on the right track, concrete details would be greatly
>> appreciated.  I'm lost in the multiple layers of the documentation at the
>> moment.
>>
>> Thanks for any suggestions.
>>
>> K. Frank



More information about the Interest mailing list