Why does all selected QGraphicsItem not receive mouseMove event? - qt

I have several QGraphicsItem objects on my custom GraphicsScene. They have different custom types, so some of them have to handle MouseMove event in one way, and other in different way.
When I select some of them and then move selected items only the item that is under the mouse cursor receive MouseMove event but other items does not. I have to make some additional actions in MyCustomItemClass::mouseMoveEvent when moving is started.
So why does the other items not receive the event?

From your description I would not handle these actions in MyCustomItemClass::mouseMoveEvent because this is only executed when the mouse moves on top of that particular item as you already stated.
Instead I'd subclass the mouseMoveEvent in the scene to check which items are selected and execute the related method in these items. Of course you have to be careful to only move them relatively to their original position according to the relative mouse movement.

If you want to select a group of items and then move them all at once, you can add them to a QGraphicsItemGroup during the select and then move the group as a single object, which will move all the items in the group.

Related

Qt Event process order in scene items model

I custom my own item, which inherits from QGraphicsItem, override the mousePressEvent function, then I add it into QGraphicScene.
When I debug, I move mouse onto my item, then press down, I find that the QGraphicScene's event processing function is called first(I install a event processing filter on QGraphicScene), then mousePressEvent of my custom item is called, is this correct?
How can I made my custom item earlier receiver than QGraphicScene?
The behavior you describe is correct and by design. The item will never receive the event before the scene does; it is - after all - the scene's job to route the event to the correct item. The scene maintains spatial index of the items and uses it to route the event. What you can do instead is to filter the event on the item itself, not on the scene: use QGraphicsItem::installSceneEventFilter.

Reordering Qt Listview via drag'n'drop

I have tried the approach described in http://agateau.com/2016/reordering-a-listview-via-dragndrop-3/ to implement drag'n'drop support in a listview.
However, when the amount of items in the list grow there is a problem when scrolling while dragging.
To reproduce the problem, download project from https://github.com/agateau/listviewdragitem/tree/3-placeholders. Triple the amount of items in the list, and try to drag an item (all but first) to the end of the list. The dragged tem will dissapear when the list has scrolled for some time. I have not noticed any signals beeing emitted indicating that the drag has completed.
The first item can be moved correctly for some reason.
Do you have any suggestions what may cause this behavior?
The reason, that the first Item does not disappear is, that it is the currentItem which is protected from deletion.
The reason that the other Items suddenly disappear is, that the ListView instantiates and destroyes the Items as it thinks they are visible. This means: As they would be visible on their original position.
Set the currentIndex to the index of the Item that is being dragged, to prevent it from being destroyed.
Also you could use a DelegateModel and add relevant Items to the persistent group, to prevent destruction.

Qt: How to click and drag in a QGraphicsView to rubber band select items that accept mouse clicks?

According to the QGraphicsView docs, dragMode's behavior "only affects mouse clicks that are not handled by any item." It then says "You can define a custom behavior by creating a subclass of QGraphicsView."
In my case I'd like clicks on an item that accepts mouse clicks to call the item's mouse clicks as normal. And I'd like clicks not on those items to start a rubber band drag (also as normal). However, I'd like to be able to ctrl-click the view, and have that start a rubber band drag selection rather than call the item's mouse event methods.
I know how to assess whether or not ctrl is associated with a mouse click event:
if (event->modifiers().testFlag(Qt::ControlModifier))
However, I don't know what to do with this condition, or where exactly to put it. Should I put it in QGraphicsItem, QGraphicsScene, or QGraphicsView? QGraphicsView seems most likely, as the docs somewhat hint.
You need to put the condition to QGraphicsItem like this:
if (event->modifiers().testFlag(Qt::ControlModifier))
{event->setAccepted(false); return;}
Now You can handle the event in Your QGraphicsView.

Qt: How to be notified when a row is hovered in a QFormLayout?

I have a QFormLayout where the left widgets are QLabels and the right widgets are of various types. I want to get notified when the mouse enters any part of a form-row, so I can display an explanation of that row in my statusbar.
Currently I have a QLabel subclass called HoverableLabel which exposes "mouseEntered" and "mouseLeft" signals (emitted in my reimplementations of enterEvent and leaveEvent). This works, but:
The margins between the rows don't trigger the signals
The space on the left of the (right-aligned) labels doesn't trigger the signal
The widgets on the right don't trigger the signal because I haven't bothered to subclass all of them
What's the Qt-blessed approach to this kind of problem?
Some things I can think of:
Make the formlayout's parent a widget that filters all mousemove events (mouse tracking?) and checks if the mouse has entered some row.
Change the formlayout into a QVBoxLayout, and make the rows into some custom widget like FormRowWidget which handles both hover events and the form-alignment stuff.
Neither is very nice.
I ended up using the first of the two solutions. Good enough, and with some work it can be isolated into a reusable subclass of QFormLayout.

How to loop QListView item selection

How can I make QListView item selection loop from bottom item to top (by pressing navigation key, down) and from top item to bottom (by pressing navigation key, up)? Is there a flag to be defined or some other way? My listview is in IconMode I wanted the selection to go to next row's 1st item when I've reached the end of a row.
Thanks
Its Default behavior provided by the list view for iconic mode.
in order to achieve your requirement, you need to handle it manually.
i.e you will be having the count of items in a row, once you reach the last item handle the right navigation key press event, then focus it back to the first element of the same row..
to get the navigation keypress event, either you install event filter or ovveride the keypress event function.

Resources