PDA

View Full Version : Custom selector widget



Strongoloid
17th July 2009, 17:41
Hello,

I'm pretty new to Qt, and I'm wondering if anyone can give me ideas or tips on how to implement the following:

I want to make some kind of selector widget that I can eventually add to a QTreeView (I'll worry about that later). The widget will basically be a horizontal array of maybe 16 or 32 small toggle-able buttons or boxes or something (maybe QPushButtons with setCheckable(true)). I want to be able to select or deselect an arbitrary amount of them, then be able to drag the selected ones and drop them into another QTreeView in the same window (at which point that sub-window will deal with the dropped items, which I'll also worry about later).

I guess I'm wondering if the PushButton way above is a good way to do it, or should I just make the thing from scratch (which would mean dealing with what each little box looks like selected and unselected, figuring out how to make them drag-and-droppable, etc.). I figured an array of PushButtons seemed to make sense because it already has most of that functionality and I shouldn't reinvent the wheel if I don't have to. I also don't want to run into problems when I have to make delegates for the thing to be displayed in the TreeView. Any advice would be appreciated.

wysota
17th July 2009, 18:48
Could you provide a graphical mockup of what you want?

Strongoloid
17th July 2009, 19:10
Sure thing, I attached a partial screen of what I have so far. The blue array of rectangles would be the things that are individually selectable. Ideally, I would like to be able to select things from multiple levels (e.g., boxes 1, 2, 3 in level 4-1 and 4-2 and 4-3) and be able to drag just the selected ones, like when you select multiple items in the QTreeView and drag them.

The model is already set up for the tree, so I'm just providing a different visualization at the lowest level, rather than just have the 32 items in that level lined up vertically. When I click on a rectangle, I want that small rectangle to be selected.

I used the Qt Star Delegate example as a reference. Basically I just have a rectangle and paint it 32 times. I guess my problem at this point is how to handle dealing with selecting individual boxes, and how to make them draggable. Also based on reading other threads in the forum, I'll probably run into problems later because I don't want to have to double click to trigger the edit event, then click once more to toggle the switch.

edit: I should probably say everything in the list is selectable and draggable already, and doing that essentially means "select this item, and everything below it in the tree". Every item's flag is Qt::ItemIsDragEnabled.

wysota
17th July 2009, 19:42
Selecting is easy. Override QAbstractItemDelegate::editorEvent(). Dragging will be much harder - you need to come up with an idea how to perform the drag itself.

There is another thing you could try - subclass both the view and the delegate. Make each box a separate item in the model. In the view modify proper methods so that they return proper rectangles for your items. The delegate for the lowest level would just paint a single box. Then the drag should be quite easy as well, you'd just drag every selected item. The hardest part would be to reimplement parts of the view.

Strongoloid
17th July 2009, 21:32
There is another thing you could try - subclass both the view and the delegate. Make each box a separate item in the model. In the view modify proper methods so that they return proper rectangles for your items. The delegate for the lowest level would just paint a single box. Then the drag should be quite easy as well, you'd just drag every selected item. The hardest part would be to reimplement parts of the view.

I'm a little confused on what you mean. Could you elaborate? Do you mean to have, for instance, each of the 32 items as a separate item, with a delegate for the item? What would I have to reimplement in the QTreeView?

wysota
17th July 2009, 21:49
Do you mean to have, for instance, each of the 32 items as a separate item, with a delegate for the item?
Yes.

What would I have to reimplement in the QTreeView?

Methods responsible for layout of items and their size (indexAt, visualRect, etc.). This is a bit of work and you have to think how you are going to implement it before you start.

Strongoloid
5th August 2009, 00:41
Sorry for the long gap, I've been away but now I'm back to working on this stuff.

Having each box be a separate item in the model is ok, and I understand that I will need to reimplement some methods like visualRect and indexAt to be able to select the correct boxes. However, I'm unsure how to get the boxes to show up in the same row in the first place.

If I subclass the view, I would basically maintain the same behavior as a normal QTreeView, except when it gets down to that lowest level. I guess I'm just confused as to how to get 32 rows to change to a row of 32 items. I'm not sure how to change the layout.

I'm guessing I would have to reimplement drawRow and paintEvent as one of the first things to do. Am I on the right track?

numbat
5th August 2009, 13:11
Excuse my denseness, but what is wrong with the default drag n drop behaviour?

Strongoloid
5th August 2009, 16:10
Excuse my denseness, but what is wrong with the default drag n drop behaviour?

Nothing. I want to maintain the default drag and drop behavior at all levels. My hang up is with how to subclass QTreeView to show (at the lowest level, or the leaves or whatever they'd be called) a row of individually selectable boxes. Each of those items on the row is basically a QStandardItem, just with a different visual representation (rather than have 32 rows under the parent node, I want 32 little boxes in one row under the parent node).