qt button to emit multiple signals - qt

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.

Related

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

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.

QT5 How to paint with two events?

I have a area shows waveform of a wave file.
I want that a line follow mouse moving like audio editor and this line's behavior is like progressbar when it is playing.
But there's only one paintEvent function, it works well when it is not playing, how to implement it?
Remember that the paintEvent isn't meant to react to user interaction directly. You should handle interaction in relevant mouse/keyboard event handlers, and modify a data structure that describes what's to be shown. Before returning from the event handler, queue an update using QWidget::update().
The paintEvent will be then called from the event loop, and should repaint the widget based on the updated data. Also don't forget that the paintEvent can be called at any time, and that you can paint on the widget only from within the paintEvent.

How to catch all and only button release events in Qt?

My team is developing an UI for an apparatus with touch screen and we would like it to emit a sound (from a buzzer) each time the user correctly presses a button (so using the release event). Notice that I don't want to play the sound after each click on the interface, but only when the click is over a button.
We use many types of button, sometimes QPushButton and most of the times customized buttons derived from QAbstractButton. In most cases these buttons get an objectName.
So I supposed in order to do that, I would have to catch the MouseButtonRelease event and since I'm already working with a subclass of QApplication to handle excetions, I decided to do this in the notify function.
I tried, then, some methods to recognized when the MouseButtonRelease was related to a button but none of them were successfull. The best one, verifying the receiver's objectName was still not good enought not only because not all buttons had an objectName (which, of course, can be handled), but specially because not always the event was caught for buttons with names set. In other words, sometimes I would click in a button and it recognizes the event and sometimes I would click in the same button and the event is not recognized.
I did some research and another method I found was to set an event filter in the MainWindow, but not all widgets have the MainWindow as their parent which means I would have to Ctrl+c / Ctrl+V the same code time after time when I obviously want something more localized (i.e. in only one spot).
So why it happens that the notify not always handles the events? And how could I do this? Any suggestions are appreciated specially one that is less heavier then handling the events globally.
As info, the other two ways I tried to catch the events with similar or even worst results inside notify were with receiver->inherits("...") and qobject_cast< QAbstractButton* >(receiver).

QAction Qt::Key_Return shortcut is triggered by user entering values in GUI

I have an issue with associating a keypress to a QAction. I'm mapping Enter to an action like this:
myAction->setShortcut(Qt::Key_Return);
The problem is that the QAction is also triggered when I type a value in a QSpinBox and then press Enter. I was expecting the spinbox to consume the event (so it's not caught by the mainwindow) but it's not working like that.
I've seen that I can add a context to my shortcut, I tried all values but this does not solve my issue.
#Matthew It is indeed rejecting the event:
case Qt::Key_Enter:
case Qt::Key_Return:
d->edit->d_func()->control->clearUndo();
d->interpret(d->keyboardTracking ? AlwaysEmit : EmitIfChanged);
selectAll();
event->ignore();
emit editingFinished();
return;
I find this behavior quite strange.
From my knowledge the QSpinBox default behavior does wait until you press return to accept the value. Technically the value is set/accepted as soon as you change it.
If you're looking to change that behaviour, i.e. when you hit return on your QSpinBox you the value is actually set/accepted, then you will most likely have to handle the associated key press event yourself on the QSpinBox and mark it as accepted (i.e. event->accepted() ).
Otherwise, this sounds like it is working as originally designed although not as you want.
I have exactly the same problem, only in PyQt and with QLineEdit
It may be that QActions are always considered menu actions, or global, and have a higher priority than Widget Default keys.
My "solution" was to create a global list of my actions with important keys (Return, Tab, Backspace etc.) as shortcuts.
Then I hook into QLineEdit focusInEvent and focusOutEvent. Each time the event happens I loop over the actions-list and deactivate them all on focusIn and activate them again on focusOut. Then I give the event to the original focus event handlers.
I really hope there is a better solution.

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.

Resources