How to use QTableWidget::setCellWidget() to set a widget such as a QComboBox and do the further handling?
-
@VRonin said in How to use QTableWidget::setCellWidget() to set a widget such as a QComboBox and do the further handling?:
Views
I m leaning the table widget. Firstly , I use the sellWidget to try it out, since it's very simple. After this, I will try to use the delegate model view method, and see which one suits most. I think its the most complicate part in QT. -
-
@ailika said in How to use QTableWidget::setCellWidget() to set a widget such as a QComboBox and do the further handling?:
I have to double click the item then the combox shows.
Have a look at your setting for editTriggers. If your behaviour is QAbstractItemView::DoubleClicked only you can change that.
-
@ailika
That is correct. The code you copied which @VRonin referred you to produces a combobox only when the user wishes to edit a cell. Otherwise the cell just shows the current value. Little point in showing a combobox when you're not editing something. When you have 10,000 rows in your table view @VRonin is trying to save you from having 10,000 comboboxes present all the time, which is "expensive/inefficient". -
I haven't think of this problem. If I have 10000 combox, I will have to create 10000 objects which will "swallow" the RAM. This indeed is a problem. So this is his really purpose, not a defect?
In fact, I don't use the table to do some data process which may contain thousands of data. I need only 250 rows and need it to be displayed.
Currently, I think the createEdit method can't work. I think I should use 'QStyleOptionComboBox' instead, am I right? But this really difficult, I haven't seen any complete example in the network. Currently I can only display a text in the combox item, but it can't popup. It seems that I should study QStyle function first and see whether I can solve my problem. -
@ailika
Even 250 comboboxes is quite a lot.Anyway, I don't know what doesn't work for you. If you follow the code in @VRonin's Combo Boxes in Item Views you should find:
- Initially all items are displayed with their current values, no comboboxes.
- Then you click or double-click in a cell and it turns into a combobox.
- Then you click on the combobox to get the popup and do the editing.
- Then you click away or whatever and it reverts to the text value.
-
@JonB
250is quite alot? I have seen other similar application who has 250 combox. But they ard made by MFC and c#. so it's not unreasonable quantity.
I have used the code and it works like you said.
But what I need is to to display them initially not display on edit. The display on edit way just don't fit into the application. If I cant solve it even by QStyle, I will use the setCellWidget way or just do not use the combobox. Just use a dialog to edit the date and use the table to dislpay text(the dialog is destined to be used what ever method I use.) -
@ailika
In that case: either it's possible to have a delegate for normal, non-edit viewing which "looks like" a combobox --- I don't know if you can do that, as you say maybeQStyleOption
something --- and then it has to change into a real combobox on click. Or, also as you say, go back to your preferredsetCellWidget()
. In which case I showed earlier how you can access the row/column, or the actual combobox, in the slot, which is what you originally asked for. -
@ailika
@VRonin is the one who guided you away fromsetCellWidget()
/setIndexWidget()
. Look at his signature! :)I backed him up, pointing out to you one disadvantage of memory/efficiency.
He is generally correct. However, I am not necessarily on the crusade he is on! :) I answered your question initially for the
setCellWidget()
you asked about. For 250 comboboxes I personally would use his styled item delegate. But I am not going to die in a ditch if you are aware of this but still wish to usesetCellWidget()
in your own code. Just don't tell him I said this to you.... ;-) -
@JonB I have been studying the QStyle's help documentation theses days. It really makes me angry that I find the sentence "The list that pops up when the user clicks on the combo box is drawn by a delegate, which we do not cover in this overview. " How to display the important popup menu is not described!! And I have alreay displayed the others quite well.
Do I need to write the hard code for the whole popup window all my self? I don't see it very necessary, since qt has alreay paint the combo box. I think it will be a repeated work if I write the paint code myself. -
@ailika
Hi
Its important to read about the delegates and understand how they work.When not in edit mode the delegate draws the widget using pure QPainter/Qstyle calls. This is very fast so scrolling works good.
Then when you trigger edit event for a cell the delegate createEditor
creates a real Widget. in your case a combobox and handling the
editing of the cell value.So the delegate get it speed improvements from not using a full widgets all the time.
-
@mrjj I'm reading 'Model/View programming' documentation. But first I don't quite under stand the edit role. Usually, when I double click the item, it will enter the "edit" state, isn't it? But in combox of spinbox, I don't use double click, I just click the spiral area of combox, and it will popup. Is this calling a "edit" state? If it is seen as a edit state, it is not a normal "edit", is it?
Maybe after I go through the 'Model/View programming' documentation, I can understand this, since I have seen " To allow flexible handling of user input, we introduce the concept of the delegate. The advantage of having a delegate in this framework is that it allows the way items of data are rendered and edited to be customized." Maybe the operation I said above is seen as a customized edit. -
Hi
The "edit state" talked about is in regards to the View. (like TableView/widget)
Normally one has to double click to make the view go into edit mode. However the
EditTriggers setting can alter this to allow other ways.- Usually, when I double click the item, it will enter the "edit" state, isn't it?
yes.
In regards to your combobox. When using a delegate, when you trigger edit mode, the view tells the delegate and
it creates a real combobox. so when it's a real combo, it's also in editmode.The delegate is then responsible to load and save data as the View dont know to handle say a combobox.
However, when you use setCellWidget, you just float a widget on top of the cells.
It does know to align the Widget with the cell but that is about it. There is no real concept of edit mode
here as the Widget (combo) will cover up the cell so you dont get to click it.You must then use combobox signals etc to handle saving and loading data.
a basic delegate is not so bad.
https://wiki.qt.io/Combo_Boxes_in_Item_Views - Usually, when I double click the item, it will enter the "edit" state, isn't it?
-
@mrjj Hi, I've already used this mode, and I need to at least single click in order to enter edit state, which I don't like. I'd like to display the combox as soon as the table shows up, like the setCellWidget, And need to be able to popup when I click the arrow part of the combobox. So it's hard to acomplish this. I've already read half the documentation ,which seems there is no complex example of it. It seems I won't be able to find the solution directly.
Currently ,I have used the following code in the delegate's paint function, it can paint a combox and show, but the popup menu won't show up. There need more handling which I haven't find the way yet. I think I have to handle the key event in the delegate, which I think will be very complex.QStyleOptionComboBox comboBoxOption; comboBoxOption.rect = option.rect; comboBoxOption.state = option.state; comboBoxOption.state |= QStyle::State_Enabled; comboBoxOption.editable = false; comboBoxOption.popupRect = option.rect; comboBoxOption.popupRect.setHeight(option.rect.height()); comboBoxOption.currentText = "CCC"; // This doesn't show up. QApplication::style()->drawComplexControl(QStyle::CC_ComboBox, &comboBoxOption, painter); QApplication::style()->drawControl(QStyle::CE_ComboBoxLabel, &comboBoxOption, painter);
-
@ailika said in How to use QTableWidget::setCellWidget() to set a widget such as a QComboBox and do the further handling?:
So it's hard to acomplish this. I've already read half the documentation ,which seems there is no complex example of it. It seems I won't be able to find the solution directly.
It's not that hard, have a look at https://forum.qt.io/post/422423
need to be able to popup when I click the arrow part of the combobox
This is straightforward, at the end of
ComboBoxDelegate::setEditorData
callqobject_cast<QComboBox*>(editor)->showPopup()
and make sureQAbstractItemView::CurrentChanged
is set as an edit trigger -
@VRonin Thank you very much. A simple function 'openPersistentEditor' will do! (Because I have already generate the compbox/spinbox, the question is how to display it on creation of the table). But I just didn't know there was such a function!!! I thought it would be very non-sense to draw a combox/spinbox on my self since the system alreay knows how to draw it.
But as you said, it may still generate lot of combox object, which consumes lots of system resources. Your method still genterate QCombox when editing. Though I can set cbOption.currentText = "..." to display the initial value, it still has problem when I double click(it first become blank if I do not select anything). And the
'openPersistentEditor' method seems working well, but it need to generate all the combox at once.
I think there is some method that only use paint and mouse event and never generate combox at all. Maybe I need to look into the source code of combox. But currently I can't see the source code. And it is said the source code can't be seen after QT 5, do I need to install QT 4 instead? Can I install it without interfering the current installed QT 5?