Search code examples
c++qtqt4

QPushButton: How to know whether a "released" signal will be followed by a "clicked" signal?


In my application, there are a few QPushButtons that I need to handle "invalid release" and "click" differently.

By "invalid release" I mean a release that happens outside the button (following a press within the button).

So I'm trying to inherit from QPushButton and implement my own signal void released(bool validClick);.

I'm thinking about using mouseReleaseEvent to check whether it's in the button's rect() to infer if a clicked() signal will follow the released() signal. Is this a good way to do it?

Update::background:

I have a group of three buttons, each of which can start the same action to the backend (with different configurations). However the backend can not handle multiple successive start commands without already started ones being cleaned up, so I have to prevent such a case in the button group.

This application is multi-touch, which makes it very easy to click all three buttons at the same time.

What I want to do:

1) When one of the buttons is pressed, disable others. This is essential because this is a multi touch GUI and multiple buttons being clicked at the same time is the first thing I need to avoid.

2) When the backend informs the button group that all previously started services has been closed and cleaned up and it's ready for next button click, button group unlocks all buttons.

3) If the user triggers a invalid release (press on the button, release outside it), all buttons should be unlocked immediately.

4) If the user triggers a valid release (click), the button group should also disable the button that the user has clicked so that it can not be clicked again until allowed by the backend.

If I can not differentiate between valid and invalid release, then I would have to treat case 4) and case 2) the same way as case 3). This is not desirable.


Solution

  • You don't care about presses nor releases, only about clicks and indications that tasks are done by the backend. You have two states: idle and busy. When idle, buttons are enabled. When any button is clicked() you transition to the busy state until the backend signals that it's not busy anymore. This is trivial to implement using the state machine framework.

    You could also have three states to make failure handling easier: idle, pending, and busy. When any button is clicked() you transition to the pending state and request the work by the backend. When the backend signals that it has accepted the request, transition to busy, until the backend has signaled that it has done processing the request, whereas you transition to idle.