How to set a Slot receiving every Widget action in Qt - qt

Suppose I've a Qt app based on QWidget, in which I'd like to obtain a "feedback" everytime I press a QPushButton, I rotate a QDial, I press a mouse button. My question is: how can I set a slot that informs me everytime something happened inside my app built for a touchscreen, in which I need to know when user does something on it.
MousePressEvent partially solves my problem; so when user touches the screen, MousePressEvent warns me about it. Problem is related to widgets as QPushButtons or QDials.
At the moment, I've already arranged my widgets with a lot of subwidgets; number of pushbutton is about 300. How can obtain triggering signal when one of them is pressed without re-edit every single button?

You can use an "event filter" that is installed on QApplication instance. This filter will receive all the events in your application, afterwards you can check event type and object type to pick the events you are interested in. See my answer to another question here for details.

Related

How can i change QStackWidget page index with button in Qt Designer?

I am currently working in Qt Designer and i am trying to make button change the index of QStackWidget with click signal.
I entered signal editor mode and connected Button to QStackWidget, This is what i got:
As you see in the picture, setCurrentIndex(int) is grayed out, If i choose any signal from QPushButton, there is nothing associated with changing page.
Sorted Question:
How can i change the page in QStackedWidget using a button? (In Qt Designer).
That is not possible directly with Qt Designer, because QButton click signal doesn't send any index or argument, and setCurrentIndex(int) need an argument to chose change the index.
You have to do it using signal/slot in C++ code, or use an other widget like QSpinBox which emit a signal with an integer argument.

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).

qt create dialog

I've made my first qt window. Now I'd like to make my first dialog, using qt. I have just finished creating the dialog, which is basically made of a QDialogButtonBox, and now I'd like to connect it to the window. I have two beginner's questions:
How can I retrieve how the dialog was closed (ok pressed or cancel pressed) from the window.cpp, which creates a new dialog, and then calls dialog->show() ?
Where and how to destroy the dialog pointer ?
If you use dialog->show() then I assume it's non-modal dialog.
If you have created QDialogButtonBox and connected its signals with accept() and reject() slots of your dialog as documentation shows, then your dialog will emit finished(int) and additionally accepted() or rejected() signals by which you can determine how it was closed.
If you need more customized behavior, then you can reimplement closeEvent(QCloseEvent *event) or create your own singnals.
If you need to delete your dialog you can use setAttribute(Qt::WA_DeleteOnClose, true);, which will delete instance on close.
you can use one flag, and signal and slot.
when put OK flag=1 , and when put cancel then flag=-1; and then use signal.
in in the window.h write code how to handle that flags with 1 simple slot.
for destroying the pointer you can use signal and slot in your Dialog and tell when user push
Ok, or Cancel , or exit (up- right (red cross)) go to slot in call the Destructer of dialog
and also you that you better set parent of dialog to window.
First Question:
When you want to show the dialog,just construct it,using myDialog *d = new myDialog(this)(the this pointer will make sure that you havn't to delete the pointer you created 'cause Qt will handle this if you specified the dialog's parent). And use d->exec() if you need a modal dialog, or d->show() to make it non-modal;
Second Question:
Once your specified the dialog's parent object, all u need is just use it and leave alone the memory managent,Qt will do this for you. Also you can use d->setAttribute(Qt::WA_DeleteOnClose,true) to make it destroy itself when it is closed.
Remember to link the QDialogButtonBox to your dialog's actions.

Qt : keyboard focus

I am writing a program in Qt that looks like this:
The main window is my class Window : QWidget, it has a QGridLayout containing four other widgets (Input_Menu : QWidget and Output_Menu : QWidget, and then two Canvas : QWidget)
I would like to trigger certain events when the user strikes a key. The problem is, the Window sometimes loses focus (it goes, say to Input_Menu, or maybe a button in Input_Menu...)
I have tried the following solutions, but they seem unsatisfactory (and dirty):
Give Window the focus whenever it loses it.
Tell each widget who could have the focus to trigger Window's KeyPressEvent function (or a clone of it) whenever it receives a keyboard event.
Ideally, I would like that if a widget receives an event (say a keyboard event) and doesn't know what to do with it, it should automatically call its parent's event handler. I would have hoped this to be a default feature of Qt but it doesn't look like it. On the other hand I am really confused about the whole focus thing, I don't really get what's going on. Can someone explain this to me: I have included a std::cout << "key pressed" << std::endl; in my Window::KeyPressEvent function. When I first run my program, it seems the focus is on the top QComboBox in Input_Menu: if I hit the Up/Down keys, I navigate in that box and no "key pressed" is showed in my console. If I hit most letters, nothing happens. But if I hit Left/Right keys, I do get a "key pressed" in my console!?
Thanks a lot in advance for your insights.
You can install an event filter on QApplication to filter the relevant QEvent::KeyPress events globally. From the Qt documentation:
It is also possible to filter all events for the entire application,
by installing an event filter on the QApplication or QCoreApplication
object. Such global event filters are called before the
object-specific filters. This is very powerful, but it also slows down
event delivery of every single event in the entire application; the
other techniques discussed should generally be used instead.
Besides the performance considerations, remember to check if your window currently has the focus before you filter the key event, or you might break popup dialogs or input into other windows.
Actually, I found that for keys that are modifiers (such as Shift, Control), Qt supports finding out whether they are pressed.
Eg : if(QApplication::keyboardModifiers() == Qt::ShiftModifier) ...
This is good enough.

QTableView: Best way to change activation-trigger to double-click

In my application, I have one tableview of items, and a side-panel "preview":ing the latest selected item.
I want clicking on an item to change the selection, and double-clicking to cause a "run"-action to be performed. More specifically, I want the "run"-action (including key-navigation and pressing enter) to be bound to the "activation" of the item in the table-row.
My problem is; single-clicks does not only change the selection, but fires the "activated" signal on the item. I would like to tweak it such that:
Navigation Keys, Single Mouse Click: Selection-change, update preview-panel
Enter Key, Double Mouse Click: Activate/run/open action triggered.
Is there a nice clean way to do it, or are overriding the onclick/doubleclick events my best option? Or is there some other tabular list-widget better suiting my needs?
I would connect the slot for the preview action to the currentChanged() signal of the table view's selectionModel(). This covers single clicks and key navigation.
Then there's two options for the double clicks and Enter key presses:
Subclass your tableview, override doubleClickEvent() and keyPressEvent() and fire your custom signal in there, with maybe the model index or something else as an argument. Then just connect your run method to your own signal as you have full control over when it is fired.
If you don't want to subclass, you can use the installEventFilter() mechanism.
Either I'm getting your approach wrong or I'm too tired, but if you want to trigger a run event you should avoid the activated signal completely. Set the signal slot mechanism so that your double click and Enter key press event trigger your run() function, and then the single click/nav buttons should trigger the 'activated' slot which will return your index in the tableview.
I'm pretty certain Qt wants you to be explicit about which signal points to which slot or it'll ignore it or point to a default.

Resources