I have QToolButton:
btn_ = new QToolButton(this);
btn_->setFocusPolicy(Qt::NoFocus);
btn_->setAutoRepeat(false);
connect(btn_, SIGNAL(pressed()), this, SLOT(btnPressed()));
and my slot called twice per on appreciable press on touchpad.
During debug of my program I can see that the first one call from QAbstractButton::mousePressEvent
and the second one QAbstractButton::mouseMoveEvent.
If I press touchpad with one instantaneous and then remove hand from
touchpad, then I got only one call of btnPressed from QAbstractButton::mousePressEvent.
Any idea how to fix this issue? So I have not remove hands from notebook's touchpad
for pressing. I think about timer to measure time from one btnPressed to another,
but have no idea of value of timeout to prevent this. I can of course choose timeout for my notebook, but what if on another notebook it will be too small,
or if choose big one, then users start complains about not responsible interface.
linux/x11/qt4.8/amd64
Try using clicked() instead of pressed(), as it reflects the behaviour the user expect from a single button press/click. In general, if you're not sure you really want the slot called instantly at pressing the button (and handle the special cases that may come with that), you should use clicked().
Related
I need a wait cursor to be loaded when the second page OnWizardNext of a property sheet is clicked .This is how I had done.Actually I designed a property sheet and now when I Click on the Next button I had activated the hourglass ,till this point everything works fine ,here arises the actual problem i.e,during that wait cursor period if I click again on Next button the dialog is getting dismissed .So,my intention is even if I click Next during the wait cursor it should not react to the click event.
LResult OnWizardNext()
{
CWaitCursor wait_cursor();
Sleep(10000);
return CPropertyPage::OnWizardNext()
}
if I remove Sleep then no wait cursor is getting loaded.What I need is even though if click on any button anything the event for that button should not get triggered until unless i am out of sleep time.
Can anyone please let me know how to achieve this.
I think you have a problem with the design of your wizard. You should not be using "Sleep" as it will suspend the thread. Moreover, the wait cursor is nothing more than a UI mechanism to indicate to the user that the code is still active. You seem to want to use that as a determinant for when your code can continue. Take a look at using OnSetCursor to provide visual feedback. Depending on what it is you're waiting on, you may want to look at using a timer, or, perhaps a series of "flags" to indicate a "continue" condition.
Problem
Windows has a system setting that will cause the mouse pointer to jump (move) to a new focus element automatically, e.g. the default button of a dialog that pops up. While the advantage is an increase in speed and a reduction of mouse movements, it has a disadvantage:
If this happens just when before the user clicks on another element, the user is unable to abort his/her action in time and will immediately accept the dialogs default button because the focus is moved by the system. Usually this may entail cumbersome work to retrace the steps up to this point (think a file chooser dialog that forgot the very long path you input previously) but it could also mean triggering an irreversible process (e.g. file deletion).
Aim
Essentially I would like to disable the dialog's inputs for a small amount of time, just enough to prevent an inadvertant mouse click or keyboard button press.
Question
It comes down to a C++ question, namely how to access the base classes' objects (GUI widgets) from the inheriting class, i.e.
disable the button widgets of a QMessageBox
start a single shot QTimer and connect it to a slot that
enables the previously disabled widgets
(As alternative, I probably could reimplement input event handlers that suppress all input for a specific amount of time, but although I intend to keep that time very short (e.g. 100 ms), the user is not informed of the disabled input using that method.)
A simple class derived from QDialogBox can be found at http://www.qtforum.org/article/24342/messagebox-auto-close-mouse-event-close.html.
Do you need to use one of the "native"-ish message boxes provided by the QMessageBox static functions?
Otherwise, that's pretty simple to achieve, by building a QMessageBox and adding standard buttons to it:
QMessageBox *messageBox = new QMessageBox;
QPushButton *okButton = messageBox->addButton(QMessageBox::Ok);
okButton->setEnabled(false);
// use a QTimer to add logic to reenable the button
// use QCursor to move the mouse cursor on the button
// add a nice countdown in the button's label, like Firefox does
// add other nice UX touches as wanted
Last points are left as an exercise to the reader :)
To en/disable the buttons in QMessagebox one would need access to them.
qmessagebox.cpp uses buttonBox = new QDialogButtonBox; and the addButton() method
d->buttonBox->addButton(button, (QDialogButtonBox::ButtonRole)role);
d->customButtonList.append(button);
But I don't understand Qt internals and am unable to find these in qmessagebox.h and thus fail to find out if there is a chance to access the buttons..
I have a PySide application that connects a number of buttons to a function call that spins off a bunch of external processes (this isn't ideal, but it is necessary).
The function call takes less than a quarter of a second to run, but it still presents a chance for the user to outrun my code, causing lag, freezing, or crashing.
This leads me to a few questions...
What exactly does it mean for a callable to be connected to a signal? Suppose button A's click signal is connected a Python function f. If A is clicked, and then clicked again before f exits, does PySide simply queue another call to f, or does it do something fancier?
One possible solution is to make f disconnect itself from the signal and then reconnect before it exits. Before I go off rewriting things to try this, does anyone know if this is at all efficient, or if there is a more elegant solution?
I'm guessing it does exactly what every other GUI toolkit does, which is try to execute that function for every button press. If you don't want that, then there are several approaches you can take:
Disable the button until the function finishes
Use a sentinel value, like self.running, and add a check to see if it is True. If so, return. Otherwise, set it to True and execute. Just remember to set it back to False at the end of the function
Do what you mentioned and disconnect the function from the signal
Those are the main ones. I'm sure there are some more esoteric solutions out there too though.
I have a QAbstractItemView that needs to react to single and double click events. The actions are different depending on whether it was single clicked or double clicked. The problem that is occurring is that the single click event is received prior to the double click event.
Is there a recommended way/best practice for distinguishing between the two? I don't want to perform the single click action when the user has actually double clicked.
I am using Qt 4.6
It's a good UI design to make sure your single-clicks and double-clicks are conceptually related:
Single-Click: select icon
Double-Click: select icon and open it
Single-Click: select color
Double-Click: select color and open palette editor
Notice how in these examples the single-click action is actually a subset of the double-click. This means you can go ahead and do your single-click action normally and just do the additional action if the double-click comes in.
If your user interface does something like:
Single-Click: select icon
Double-Click: close window
Then you are setting your users up to fail. Even if they remember what single-clicking does versus double-clicking all the time, it's very easy to accidentally move your mouse too far while double-clicking or wait too long.
Edit:
I'm sorry to hear that.
In that case, I found these two articles useful:
Logical consequences of the way
Windows converts single-clicks into
double-clicks
Implementing
higher-order clicks
You can find answer in the thread titled Double Click Capturing on QtCentre forum;
You could have a timer. Start the
timer in the releaseEvent handler and
make sure the timeout is long enough
to handle the double click first.
Then, in the double click event
handler you can stop the timer and
prevent it from firing. If a double
click handler is not triggered, the
timer will timeout and call a slot of
your choice, where you can handle the
single click. This is of course a
nasty hack, but has a chance to work.
wysota
Using PySide which is the Python binding of Qt 4.8 I saw that single clicks deliver a QEvent.MouseButtonPress event and double clicks deliver a single QEvent.MouseButtonPress event closely followed by a QEvent.MouseButtonDblClick. The delay is approximately about 100ms on Windows. That means you still have a problem if you need to differentiate between single and double clicks.
The solution needs another QTimer with a slightly higher delay than the inbuilt delay (adding some overhead). If you observe a QEvent.MouseButtonPress event you start your own timer, in case of timeout it is a single click. In case of a QEvent.MouseButtonDblClick it is a double click and you stop the timer to avoid counting as single click.
Hey guys ... Well I'm experiencing this silly problem that whenever I perform a double click event, two mousePressed events are also triggered, meaning that mousePressed event code is also executed twice for no reason .. How can I configure the event such that first the clicks are checked for doubleClick event, and only if this is NOT true, they move on to mousePressed events .. ? Is this possible ?
Before you spend too much time trying to figure this out, consider what Raymond Chen has said about the "Logical consequences of the way Windows converts single-clicks into double-clicks". The techniques he talks about should be easily adaptable to Qt. But also the UI consequences of the "dubious design of having the double-click action be unrelated to the single-click action" - you may be trying to do something that will be confusing to your users (on the other hand - you might trying to prevent something from confusing your users).
Also, the related article, "Why doesn't double-right-click bring up the Properties dialog?" might be of interest.
I'm going to assume you mean for the same widget. The quick and dirty way would be to move the mouse press code into a private method, have the mouse press event set a timer to go off after the expire timer for a possible double click. In the double click code be sure to turn off the timer if it gets called. This will prevent the mouse press event from running twice. In the timer code, have it call the private method.