In my QTreeWidget,
When I single click -> Single click Action has to be performed
When I double click -> double click action has to be performed (it is ok to perform single click action along with it).
But what happens is every time, double click is performed apart from the double click action, two times single click's slot is called.
I don't think this is a desirable behaviour of QTreeWidget in any case.
Can anyone suggest me how to workaround this, hopefully in a short, simple and clean way.
Depending on what you do in case itemClicked is received, you might want to use currentItemChanged as a workaround instead. This might even be helpful for keyboard users. But this really depends on what you want to do after receiving itemClicked.
Related
I have a QDoubleSpinBox in my GUI. The problem is the valueChanged is always called while the user is typing his input in it. This will run the valueChanged everytime and user is not able to write the values he wants to. Is there any way to get rid of this behavior and call valueChanged right after the value is completely changed?
See https://forum.qt.io/topic/1688/solved-qspinbox-how-to-signal-only-when-editing-finished/2
Summary: turn off keyboard tracking
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).
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.
In more than one of my Qt applications I've noticed that, whenever the menu bar is clicked, the last signal to have been sent from a widget within the GUI is re-sent before the menu action is invoked. Most of the time this doesn't matter; but on some occasions it matters very much.
In a few cases where the widget's signal is connected to one of its own slots, it's straightforward to begin the slot with a
if (hasFocus())
{
// ...
}
...block so that such spurious signals, not generated by the user actually clicking on the widget, can be ignored.
However, I've recently identified that this behaviour is responsible for several related bugs where the spurious signals are passed on through several layers of the program before being acted upon, so simply checking whether a particular widget has focus is not trivial to implement.
My question, therefore, is:
why on earth does clicking on a menu item cause a signal to be emitted from a widget elsewhere on the screen? I can't find this behaviour documented anywhere?
how do I stop it?
Many thanks,
Stephen.
As you deduced yourself, the QLineEdit::editingFinished signal can be emitted twice if the user press enter and the QLineEdit loses the focus later. An old bug was created but behaviour has not been changed : https://bugreports.qt.io/browse/QTBUG-40.
Your solution is fine : overload QLineEdit and check if the value has changed before triggering the signal. You can use the flag QLineEdit::isModified for the check : it has a default value of false and is changed to true whenever the user changes the line edit's contents. It has to be manually reset to false when you emit the signal.
You can also do that check in the receiver object, just checking if the value has a meaning (is different from the last recorded value for example) and process it or not.
Therefore the polluting signals would not be a problem. It is in my opinion the cleanest solution, then you have a robust model. Because the user could also hit enter a few times with the same text value and you have to handle this anyway.
You can also use QLineEdit::returnPressed but this requires the user to always press enter to validate a value. Not always intuitive but forces the user to explicitly validate the inputs.
Looking through the documentation, it seems that the new advanced gestures API doesn't determine the direction of a swipe beyond the basic { left, right, up, down }.
I need the start point of the swipe and the direction.
Is there anyway to retrieve this other than coding my own advanced gesture library from scratch out the basic gestures?
And if this is my only option, could anyone point me to some open source code that does this?
Got it! Documentation is here, under 'Creating Custom Gesture Recognizers' at the bottom.
Basically the six gestures Apple provides all derive from UIGestureRecognizer, and you can make your own gesture recogniser in the same way.
then, inside your view's init, you hook up your recogniser. and just the act of hooking it up automatically reroutes incoming touch events.
Actually, the default behaviour is to make your recogniser an Observer of these events. Which means your view gets them as it used to, and in addition if your recogniser spots a gesture it will trigger your myCustomEventHandler method inside your view (you passed its selector when you hooked up your recogniser).
But sometimes you want to prevent the original touch events from reaching the view, and you can fiddle around in your recogniser to do that. so it's a bit misleading to think of it as an ' observer '.
There is one other scenario, where one gesture needs to eat another. Like you can't just send back a single click if your view is also primed to receive double clicks. You have to wait for the double-click recogniser to report failure. and if it is successful, you need to fail the single click -- obviously you don't want to send both back!