Is there a way to add a mouse event to a thread? - qt

I have a suspicion that something is preventing my mouse event to be called in Qt. Therefore, I think it might help to add the event to a thread. Is there any way to do that? And if so how would the syntax look?

Qt standard mouse events come to QWidget objects. Those must exist in the main thread, always.
So no, you can't receive the normal mouse events in other threads.
However, you should perhaps install an event filter to your main window or to your qApp object, so you will see all the events. Look in the docs for how to use the event filter, but in short, you need to subclass QObject to override the eventFilter method, and then create instance of this class, and install that as event filter for another object.

Related

qt model/view: how qt knows when to run default signal handlers, if I've reimplemented event handlers?

I've got a general question on qt design.
Say, I created a custom classes, impelementing QAbstractTableModel and QTableView class. I've re-implemented event handlers in View, such as mousePressed, mouseRelease etc.
Still Qt's View manages to perform some of its default functionality: it still responds to mouse clicks and movements on cells by changing selection, thus it somehow fires selectionModel "built-in" signals, though I didn't ask it to. It still resizes columns, if I drag on cell borders etc. What's the mechanism that triggers those "buit-in, default slots" and how can I disable some parts of it? E.g. if I want to disable default behavior of selectionModel or default resize?
For the sake of comparison, in gtk+ there's a concept of default per-class signal handler, which is a function, by default connected to its signal and called prior or after your custom per-class or per-object signal handlers, depending on parameters you set. You can disable it from your custom slot, if you want to and thoroughly control behavior of e.g. resize or selection.
Is Qt opaque in this place and provides customization via its interface functions only? My question is particularly related to pyqt. Please ask for clarification, if I'm too vague.
The event handlers that you refer to are used to listen to events, not to filter them. You can't override any events in them, since they don't have a return value: there's no way to inform subsequent event processing that you don't wish it to run.
To filter events, you must reimplement the event method, and invoke the base class's implementation on events that you do not wish to filter.
In Qt, event handling is done per-object, and you can install external objects as event filters on any other object. An object receives the events in its event method. The QObject class implements this method and invokes the timerEvent method. The QWidget class reimplements this method and invokes the widget-specific xxxEvent methods. And so on. All of those classes still process some events internally. Those are the per-class handlers that you speak of.

How do I propagate a mousePressEvent() to a group of QGraphicsItems?

I'm writing a program that uses the Qt Graphics View framework. I have subclassed QGraphicsItem to a class that includes other QGraphicsItem (or other subclasses of it). This class is the parent of the included QGraphicsItem; the idea is to work with composite objects.
From the docs it seems to be a conflict in what I try to achieve:
Calling ignore() in mousePressEvent will make my object unmovable. I want to move it.
Calling accept() in mousePressEvent will prevent the event from being propagated to the child object. Some of the child objects should react to mouse events.
How can I make this work?
I think your interpretation of the documentation is incorrect.
Calling ignore() in mousePressEvent will make my object unmovable.
I don't believe that is true. To me it looks like calling ignore() is like the object saying "I have assessed this event. I have taken all actions I want to in response to this event. I have also decided it was not intended for me, so I will now pass it on to the next object underneath me". I can't find anything which suggests the ignore event will unset the QGraphicsItem::ItemIsMovable flag (which is what decides if the QGraphicsItem is movable or not).
I don't see why you couldn't make your object move and ignore() the event, but I would advise that this is not a sensible approach (in most instances: obviously you may have cause for it).
Calling accept() in mousePressEvent will prevent the event from being propagated to the child object.
I believe this is true, but the parent can still modify its children. My understanding is calling accept() is like the object saying "I have assessed this event. I have taken all actions I want to in response to this event (which may include modifying my children). I have also decided that the event was intended for me, so I will not be passing the event on".
In your parent QGraphicsItem, you might try to
MyObject::mousePressEvent ( QGraphicsSceneMouseEvent * event )
{
QGraphicsItem::mousePressEvent(event);
event->ignore();
}
This would allow normal processing of the mouse event (i.e. make your object moveable), but then ignoring it so that it is propagated.
The logic would need to be more robust, though, because there is a high risk of side effects if a parent and child respond to the same mouse event.
Send QCoreApplication::postEvent(child, mouseEvent) to child objects.

Post events without specifying target object in Qt

I need help to understand to use QEvents in QT, this is driving me crazy.
I am writting an application using custom events, but as in QApplication::postEvent function, it's necesary to specify the target object.
As I understand, it's possible to post events to Qt's event loop with
QApplication::postEvent(obj_target, QEvent myevent);
This means that I'm trying to catch "myevent" event in obj_target an do some stuff.
But I need to post events without specify a target object, as QMouseEvent or QKeyEvent do
I mean, when clicking in a QMainWindow with a lot of buttons, how is that I can click
any button and that button is pressed?
What is the target object when the click event is posted?
It's possible to register objects to "listen" for a specific event?
I'm really confused, it's possible to post an event without specifying a target object?
Thank you very much in advance
There is no trivial way to post events "globally", as Dan has said. All of the event dispatching of native events is done by private Qt implementation code.
The important distinction is:
There are native messages/events, delivered by the operating system, usually received by a window-specific event loop.
There are QEvents.
Internally, Qt keeps track of the top-level Widgets (windows, really), so when it receives an event from the OS, it knows which window it should go to - it can match it using the platform window id, for example.
QEvent delivery makes no sense without a receiving object, since sending an event to an object really only means that QObject::event(QEvent*) method is called on that object. It's impossible to call this method without having an object instance!
If you want to synthesize a global key press or mouse click event, then you have to figure out what object the event goes to. Namely:
Identify what top-level window (widget) the event should go to. You can enumerate top level widgets via qApp->topLevelWidgets().
Identify the child widget the event should go to. If it's a keyboard event, then sending the event to currently focused widget via qApp->focusWidget() is sufficient. You need to enumerate the child widgets to find the deepest one in the tree that overlaps the mouse coordinates.
Send the correct QEvent subclass to the widget you've just identified. Events delivered to top-level widgets will be routed to the correct child widget.
When sending mouse events, you also need to synthesize relevant enter and leave events, or you risk leaving the widgets in an invalid state. The application.cpp source file should give you some ideas there.
This doesn't give you access to native graphical items, such as menus on OS X.
Please tell us exactly what you're trying to do. Why do you want to post a broadcast event? Who receives it? Since your own QObject-derived classes will receive those broadcasts, I presume, it's easy enough to use signal-slot mechanism. You'd simply connect(...) those receiver classes to some global broadcaster QObject's signal(s).
For this purpose, I have a specific singleton class which I call GuiSignalHub. It regroups all the application-wide signals.
Objects that want to trigger an application-level action (such as opening context help) just connect their signal to the GuiSignalHub signal. Receivers just connect the GuiSignalHub to their slot.

qt button to emit multiple signals

is there a Qt (I use Qt 4.7.1) widget that emit signals (not just one at the first time) while it is pressed and stops when the user releases the mouse? something like mousedown events in standard intervals?
or do I have to implement this with a qtimer?
thanks
Check out QAbstractButton::autoRepeat and autoRepeatInterval. It should be exactly what you need and is available for all buttons.
You have to implement something that fire the event until the user release the mouse.
I suggest you to create an handler class connected to the button event that fires custom events as you like to its observers.
As far as I know there is no such button widget.The QPushButton's autoRepeat should do just what you want. But would not the QPushButton::pressed() and QPushButton::released() signals be enought for your needs?
Anyway, what you are describing would be quite easy (and redundant, since it already exists) to implement, connect the QTimer::timeout() signal to the signal you want and then just start the timer on pressed() signal and stop it on released() signal :)
Edit: As pointed out in comments, there is an inbuild solution and that is setting property autoRepeat inherited from QAbstractButton to true.
You can customise the initial delay and interval by adjusting autoRepeatDelay and autoRepeatInterval.

event handler in QML through QWidget class

I have some problem with handle QML event on touch notebook, events onPressed, onPressAndHold not work, no debug message. I trying event handle through Qt class, but i have failure (connect QML and Qt using QDeclarativeView).
How i can write global event handler whitch register QML touch event on noutbook.
Thanks.
You can use an event filter from C++. E.g. if you reimplement QApplication::notify in a QApplication subclass you should be able to hook into anything. Might be useful to check that your App works on other (mouse-based) platforms. QML's MouseArea uses Mouse Events and not touch. If your platform only uses touch events, and doesn't fake mouse events - you might need to look at the gesturearea research QML plugin; http://qt.gitorious.org/qt-labs/qml-gesturearea

Resources