Discarting QPushButton clicked events on ARM



  • Hello forum.

    I have a Qt 4.7.4 application running on ARM and framebuffer. A QPushButton is connected to a slot doAction(). When doAction() is a time consuming function, I want to discard clicked events once the button is clicked until doAction() has finished. If not, after the slot doAction() is finished, event clicked is handled again, and doAction() is executed once more (this is not the expected behavior).

    I have tried three different approaches to try to solve this issue:

    = Option 1: Using setEnabled true/false and disconnecting the slot =

    @void Test::doAction()
    {
    button.setEnabled(false);
    disconnect(button, SIGNAL(clicked()), this, SLOT(doAction());

    sleep(10); // just to test

    connect(button, SIGNAL(clicked()), this, SLOT(doAction());
    button.setEnabled(true);
    }@

    QPushButton is clicked three times. First time is clicked, doAction() is called. But meanwhile the process is busy (sleeping 10s), I don't understand why, but all 'clicked' events are enqueued into the event queue. After 10 seconds, the slot doAction() is called two times more. That is not the expected. How is this possible? The button is disabled and the clicked signal, disconnected. Can some of you explain this issue?

    = Option 2: Subclassing QPushButton and installing and eventFilter that removes posted events on event queue when the button is released =

    @bool CustomButton::eventFilter(QObject *obj, QEvent *event)
    {
    if (obj == button && event->type == MouseButtonRelease) {
    QCoreApplication::removePostedEvents(button);
    return true;
    }
    return QObject::eventFilter(obj, event);
    }@

    This does not work as expected, it behaves similar to the option 1, handling all different clicked events. Also, related with the QCoreApplication::removePostedEvents(), the documentation says "you should never need to call this function". So, I think this is not the proper solution at all.

    = Option 3: Solution based on installing/removing an event filter =

    I have tried this:

    @bool Test::eventFilter(QObject *obj, QEvent *event)
    {
    if (( obj == button) && (event->type() == QEvent::MouseButtonPress))
    return true;
    else
    return false;
    }

    void Test::doAction()
    {
    button.setEnabled(false);
    QCoreApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
    button.installEventFilter(this);

    sleep(10); // just to test

    button.setEnabled(false);
    QCoreApplication::processEvents(QEventLoop::AllEvents);
    button.removeEventFilter(this);
    }@

    This solution seems to work fine with Qt 4.7.4 running on X11 (x86), configured as this:

    @./configure -prefix@

    handling first clicked event, and discarting the received events meanwhile the method doAction() is executed.

    But it does not work as expected when running on framebuffer (ARM), configured as this:

    @./configure -prefix -embedded arm -xplatform qws/linux-arm-g++ -qt-gfx-linuxfb@

    because in this case, it filters some events, but not all of them. This wrong behaviour was already notified in "an old post of July, 2007, ":http://www.qtcentre.org/threads/7907-How-to-ignore-Button-Events-in-Qtopia, still with no answer, so I don't know if this is a broken feature still not fixed, not supported, or maybe I am doing something wrong.

    Does some of you know a better/proper solution for this problem?

    Thanks a lot in advance!

    Best regards,
    -- Ivan


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.