Question

I have a QPushButton, and a slot connected to its "pressed" signal like that:

connect( &m_oBtnSnapshot, SIGNAL( pressed() ), this, 
    SLOT( SnapshotClicked() ) );

The Slot is implemented like that:

void
GUI::SnapshotClicked()
{
    m_oBtnSnapshot.blockSignals( true );
    m_oBtnSnapshot.setDisabled( true );

    m_oBtnBenchmark.repaint();
    m_oBtnBenchmark.update();


    emit( DoSnapshotWork() );

    m_oBtnSnapshot.setDisabled( false );
    m_oBtnSnapshot.blockSignals( false );
}

So as you can see, i disable the button when i click it, and re enable it when everything is done. Let's assume the DoSnapshotWork() function takes 5 seconds... While this 5 seconds the button is disabled, but if i click it, the SnapshotClicked() Slot will be called afterwards. Why does disabling a button not prevent me from clicking it?

i alread tried disconnecting the signal on entering the slot and reconnecting it afterwards, but nothing helped.

Was it helpful?

Solution

GUI::SnapshotClicked() is a part of GUI thread, which means, while it runs, your GUI is unaccessible. I assume, signal DoSnapshotWork() is connected with a slot, running in another thread with Qt::QueuedConnection (or Qt::AutoConnection). In that case emitting this signal is asynchronous, which means GUI::SnapshotClicked() is finished long before your slot is done. I guess you should do something like this:

gui.h

public slots:
    void onReleaseButton();

gui.cpp

void
GUI::SnapshotClicked()
{
    m_oBtnSnapshot.setDisabled( true );

    m_oBtnBenchmark.repaint();
    m_oBtnBenchmark.update();

    emit( DoSnapshotWork() );
}

void
GUI::onReleaseButton()
{
    m_oBtnSnapshot.setDisabled( false );
}

Somewhere else:

connect(shapshotWorker, SIGNAL(releaseButton()), gui, SLOT(onReleaseButton()));

...

DoSnapshotWork()
{
...

emit releaseButton();
}

P.S: You need a good reason to use QPushButton::pressed() signal. In most cases you would prefer QPushButton::clicked().

OTHER TIPS

Because the mouse press events are on placed onto the event loop, and wait until your SnapshotClicked() method is complete, by which time the button is enabled again.

A simple solution is to call QCoreApplication::processEvents() immediately after the emit, this will cause the press events to processed whilst the button is still disabled. Or you can have the DoSnapshotWork() method emit a signal when it's finished, and have that enable the button and unblock the signals.

Also,

m_oBtnBenchmark.repaint();
m_oBtnBenchmark.update();

repaint()redraws the widget forcibly, whilst update() calls repaint() via the event loop - do not call them both.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top