PDA

View Full Version : Adding custom widget to a Model-View table



srbs
15th July 2015, 23:46
Hello Qt folks,

I'm working in PyQt, but I would be just as happy to have a C++ or general answer as well.

I have a tree view with an underlying model which is working fine. However, in one of the columns of the tree view, I want to add a group of push buttons that I want to control in my view/controller. Optimally, I would want to update the buttons based on the underlying model data. I have created the widget with these buttons in them, but I'm hoping somebody can help me understand how to set these buttons into the cells of a tree column.

From my understanding, this is done through delegates, but all I can manage to do is have these buttons pop up when the tree view cell is clicked for edit (via the createEditor function). I want the buttons to always be in the cell.

From the two delegate examples in the PyQt package:
- The SpinBoxDelagate example switches a number in a cell to a spin box widget when edited, which is not what I'm looking for (as mentioned above).
- The PyQt StarDelegate example does something similar to what I want but even in that example a QTableWidget is used, not a QTableView, and the StarRating widget is set explicitly in a setData call (something I don't have when using model-view).

Is there any way in the delegate (or otherwise) to specify that I don't want to only show the buttons on edit, but rather always?

Hope that makes sense and any help is much appreciated!

d_stranz
16th July 2015, 00:21
Well, there's QAbstractItemView::setIndexWidget(). Unfortunately, these widgets aren't connected to the model in any way. However, I think if you derive a delegate of you own and override the QAbstractItemDelegate::paint() method, you can draw whatever you want in the cell and it will be visible whether it is being edited or not.

srbs
16th July 2015, 15:00
Thanks for the response. I'll try and work with the QAbstractItemDelegate -- I've never had to paint and existing QWidget (like the group of QPushButtons that I have) but I assume that I can just call its paint function or something along those lines.

I suppose I could also make the setItemWidget work, but that would imply that my model owns the majority of the data in the tree aside from one column so if it does work, it would be a sort of hybrid between the TreeView and the TreeWidget.

d_stranz
16th July 2015, 16:01
I assume that I can just call its paint function or something along those lines.

Well, no. You are inserting a delegate, not a widget, and since the paintEvent method for a QWidget is protected, you can't call the QPushButton's paintEvent() from an unrelated class. Look into QProxyStyle::drawControl() and QStyleOption::initFrom(). These are ways to draw something that looks like a widget but isn't (and are the way Qt draws actual widgets).