Re: [Interest] Most direct path to using a QComboBox to edit a cell in a QTableView?
Hello Tony! Thanks for your pointers on how to hook the delegates and views together. At the moment it looks like things are working the way I want. On Tue, Jun 26, 2012 at 10:06 PM, Tony Rietwyk t...@rightsoft.com.au wrote: Hi Frank, ... And how, specifically, do I associate a delegate with a view (or a specific part of a view)? Search the docs for 'delegate' in QtAssisstant! You will find the 3 flavours of setItemDelegate. Yes indeed. In my case I want: void QAbstractItemView::setItemDelegateForColumn ( int column, QAbstractItemDelegate * delegate ) (inherited by QTableView). The view holds reference(s) to the delegate(s), and uses it to paint and edit the associated cells. Simplest way in your case, is to create a separate instance of the delegate class for each column that needs it. Yes, that's what I'm doing, and it all makes good sense. I implemented a custom delegate derived from QStyledItemDelegate (along the lines of the TSpinBoxDelegate example you posted earlier) that overrides createEditor to return a (pointer to a) QComboBox. I populate the QComboBox by connecting it (setModel) to a QSqlTableModel. The one additional thing I had to do was override setModelData. This is because the default behavior of setModelData is to set the model data to the currentIndex property of the QComboBox, and I want to set the model data to the QCombBox's currentText. One additional step, but all in all, not so bad. (I do agree that it doesn't seem like the approach of using QItemEditorFactor / QItemEditorCreatorBase could be made to work because, as you noted, it doesn't seem like that approach gives you the hooks to associate a custom editor with specific columns or rows or cells of the QTableView.) Tony. Thanks again for your help. I appreciate it. Things look good for the moment. Best. K. Frank ___ Interest mailing list Interest@qt-project.org http://lists.qt-project.org/mailman/listinfo/interest
Re: [Interest] Most direct path to using a QComboBox to edit a cell in a QTableView?
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 t...@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
Re: [Interest] Most direct path to using a QComboBox to edit a cell in a QTableView?
Hello Tony! Thanks again. I do have some follow-up questions. On Tue, Jun 26, 2012 at 12:28 PM, Tony Rietwyk t...@rightsoft.com.au wrote: Hi Frank, I haven't used QItemEditorFactory. My reading of the docs suggests this only applies if all of your strings are to be edited via the same combo. None of the interfaces include a QModelIndex, so logically it can't be used to provide different editors for different columns. Yes, I was kind of worried about that. In my case my views and models are associated with one another one to one. (That is, I don't have more than one view connected to the same model.) All of the fields in a given column of a view will use the same list of items in the combo box, but different columns will have different lists of items. So whether I do it with an editor or a delegate, I need to be able to have the editor and/or delegate depend on the column. I think that means you will need to provide a QStyledItemDelegate override. For a given view, you can use just one item delegate for all non-standard columns, or have separate delegates for different columns (or rows). In this scheme I would have different (instances of the) delegates for different columns. Makes sense. I suggest that you load up the strings from the database only once, and store them in the delegate. Then you override createEditor to create the combo box, and add the pre-loaded items. This part I think I understand. Note that delegates don't have to be specific to a particular view. Here's where I don't understand how things work. Is a delegate associated with a view or a model? I would think with the view because delegates seem to do view kinds of things -- display and UI interaction, rather than model things -- data. In my specific case of a QTableView, is a delegate associated with the view, with a cell in the view, or with a row or column of the view? Is the delegate that is associated with the view (or some part thereof) a specific instance of a delegate class, or is it a class (i.e., not an instance) that the machinery under the hood somehow instantiates automatically, as needed? And how, specifically, do I associate a delegate with a view (or a specific part of a view)? Let's say I derive my custom combo-box delegate from QStyledDelegate (along the lines of your TSpinBoxDelegate example, below). Then I instantiate my custom delegate and load up that specific instance with the desired items for its combo box. How to I attach that instance of that delegate to a specific column of one of my QTableViews? That's the part I'm fuzzy on. Here is one that I use whenever I have a column of ints with a range: class TSpinBoxDelegate : public QStyledItemDelegate { Q_OBJECT private: int minValue; int maxValue; public: TSpinBoxDelegate(int min, int max, QObject *parent = 0); QWidget *createEditor( QWidget *parent, const QStyleOptionViewItem option, const QModelIndex index) const; }; TSpinBoxDelegate::TSpinBoxDelegate(int min, int max, QObject *parent) : QStyledItemDelegate(parent) { minValue = min; maxValue = max; } QWidget *TSpinBoxDelegate::createEditor( QWidget *parent, const QStyleOptionViewItem option, const QModelIndex index) const { Q_UNUSED( option ); Q_UNUSED( index ); QSpinBox *editor = new QSpinBox(parent); editor-setMinimum( minValue ); editor-setMaximum( maxValue ); return editor; } This makes sense. I think I'm clear on how to implement a custom delegate -- I just don't know what to do with it after I have it. Hope that helps, Yes, thank you. Tony. Best. K. Frank ___ Interest mailing list Interest@qt-project.org http://lists.qt-project.org/mailman/listinfo/interest
[Interest] Most direct path to using a QComboBox to edit a cell in a QTableView?
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 ___ Interest mailing list Interest@qt-project.org http://lists.qt-project.org/mailman/listinfo/interest
Re: [Interest] Most direct path to using a QComboBox to edit a cell in a QTableView?
Hi Frank, What does the standard delegate do for your model/view at the moment? 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. For example, you include 'insert' as an action. But what does this mean? If a user types an entry not already in the list, what do you expect to happen? Which table would the new entry be inserted into? Where should the combo box get its values from? Yes I agree that the model view classes take a while to grok. Tony. 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 ___ Interest mailing list Interest@qt-project.org http://lists.qt-project.org/mailman/listinfo/interest