I have more QGraphicsItems on top of each other. How can I make hover event available for all items? Only the last added item (the one on the top) accepts hover events.
Thanks
You could simulate those events, you "just" have to:
reimplement mouseMoveEvent in a QGraphicsView or QGraphicsScene derived class,
use QGraphicsView::items(QPointF) get the item list below the mouse
create and send events, with QGraphicsScene::sendEvent whenever an item is added or removed from the list for all items but the one at the top of the stack (which is already handled).
Related
I wish to make a custom graphics item to follow the cursor without needing to be clicked on. My view has setMouseTracking(true), my graphics item has setFlag(ItemIsMovable, true); setAcceptHoverEvents(true);, but it doesn't track the cursor, I have to click and drag it. What is the proper way to make a QGraphicsItem follow the cursor?
You can only capture mouse event on an item if your cursor pass above it. For example, instead of clicking on the item, you can react on mouseMove events.
But you seem to want a more global behaviour. You could track mouseMoveEvent directly on your QGraphicsView (or on your QGraphicsScene if you have multiple views) (see mouseMoveEvent). After that, just keep a reference on your item and make it move each time you intercept an event
In a customized wxScrolledWindow, there are many nodes and edges which are displayed.
When mouse rolls over some kinds of the nodes, I can calculate which node is covered by the mouse and want to show a tooltip about the information of the nodes.
How to do it?
wxWidgets has a wxTipWindow class that you can use for this. Define an EVT_ENTER_WINDOW mouse event handler. The handler will get called when the mouse cursor is inside one of your nodes. Inside of the handling function you can create a new wxTipWindow to show extra info for your nodes.
I've created an object Chartblock that implements QGraphicsItem. My goal is to create a grid of these objects, and when the mouse button is pressed (and held) and is drug over each block, perform something on each block as the cursor enters it.
Since a QGraphicsItem grabs the mouse events when it is clicked within it, other Items will not fire for the mouseMoveEvent. I then created an object based on the QGraphicsItemGroup to handle all the mouse events, but then I would need some way to pass mousePressEvent/mouseReleaseEvent as well as mouseMoveEvent to each child that the cursor is over.
Am I overthinking how to do this? It seems like such a simple action shouldn't be that difficult to create, but with QGraphicsItems holding onto the mouse events for itself, I'm not sure how to get around it. I've read similar situations, but nothing seems to give a straightforward answer.
Edit: I suppose a way to do this would keep track of the coordinates/sizes of every single QGraphicsItem I create in an array, then get the position of the cursor in the Group mouseMoveEvent, and see if there's a hit..
I was able to pull together a few similar answers to create a solution; I dropped the idea of placing all my QGraphicItem's in a Group, and placed them directly on a scene. With the scene grabbing all mouse events, I have the mouseMoveEvent check to see if the current position is on top of a QGraphicsItem - if so, perform something.
I still need to try and get itemAt() to work for my own classes that implement QGraphicsItem, as itemAt returns only QGraphicsItem's, but I'm sure some cast should get it working.
void ChartScene::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
{
QPointF mousePosition = event->scenePos();
QGraphicsItem* pItem = this->itemAt(mousePosition.x(), mousePosition.y());
}
I need an event for detecting if an user has moved the scrollbar position to another one.
In other words, if the user does scroll up/down, would it be possible to catch a signal so I can know the scroll has been changed its position?
I think it's not important, but the scrollbar I refer to is inside a QGraphicsView.
Regards.
Edit:
QGraphicsView is for displaying items in the screen, and if those items are too big it shows the scrollbars I refer to. What I need is to know when the user changes the position of those scrollbars.
Sliders have a sliderMoved(int value) signal, where value is the new position of slider.
If you need to get notified when the scroll bar position is changed, you need to subclass the QGraphicsView and reimplement the QWidget::mouseMoveEvent(QMouseEvent*). For this you also need to enable mouse tracking. Here is Qt 4.7 QGraphicsView reference.
I'm trying to create a popup menu like control that contains custom widgets. I need to capture the mouse, but I need to have the children in the widget still get their mouse messages. It appears the grabMouse sends events only to the widget that grabbed the mouse, not its children.
The popup is simply a series of buttons (using a QGridLayout). The control should work that the user presses the right-mouse button, the popup appears, they move to an item and release the mouse button. Optimally it would work exactly like a QMenu popup but with custom widgets and a custom layout.
How can I achieve this?
It appears that simply specifying attribute Qt::Popup is enough to get the fundamental behaviour required.
Installing an event filter on all children is also necessary. All mouse events, enter/leave/hover events must be captured. QT has a defect with grabMouse so that won't work -- the filter must be used to get expected behaviour.