2013-03-28 2 views
2

У меня есть QPushButton и слот, подключенный к его «нажато» сигнал так:Qt слот кнопочный вызывается дважды, хотя инвалиды

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

Слот реализован так:

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); 
} 

Итак, как вы можете видеть, я отключу кнопку, когда я ее нажму, и включите ее, когда все будет сделано. Предположим, что функция DoSnapshotWork() занимает 5 секунд ... Хотя это 5 секунд, кнопка отключена, но если я ее нажму, слот SnapshotClicked() будет вызываться потом. Почему отключение кнопки не мешает мне щелкнуть ее?

i alread попытался отключить сигнал при входе в слот и снова подключить его, но ничего не помогло.

ответ

1

GUI::SnapshotClicked() является частью потока графического интерфейса пользователя, что означает, что при его запуске ваш графический интерфейс недоступен. Я предполагаю, что сигнал DoSnapshotWork() связан с слотом, работающим в другом потоке с Qt::QueuedConnection (или Qt::AutoConnection). В этом случае излучение этого сигнала является асинхронным, что означает, что GUI::SnapshotClicked() закончен задолго до того, как ваш слот будет выполнен. Я думаю, вы должны сделать что-то вроде этого:

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); 
} 

Где-то еще:

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

... 

DoSnapshotWork() 
{ 
... 

emit releaseButton(); 
} 

PS: Вам нужна хорошая причина для использования сигнала QPushButton :: press(). В большинстве случаев вы предпочитаете QPushButton :: clicked().

+0

Почему? существует ли разница между нажатием и нажатием? я сделал это точно так же, как вы сказали, но пока кнопка отключена, я все еще могу «щелкнуть» ее. Он отключен, но выдается сигнал DoSnapshotWork(). – Hafnernuss

+0

Я понял это сейчас. как-то я пропустил флаг Qt :: QueuedConnection при подключении слота DoSnapshotWork() к другому потоку (где графический интерфейс и нажатие кнопки). Я не знаю почему, но это почему-то вызвало вызов слота дважды. Спасибо за подсказку! – Hafnernuss

+0

'press()' пропускается, когда вы нажимаете левую кнопку мыши в области кнопок (и каждый раз вы вводите эту область позже, не отпуская кнопку мыши). 'clicked()' высвобождается, когда вы отпускаете левую кнопку мыши в области кнопки, после нажатия левой кнопки в нее. Вы можете написать простое приложение, чтобы почувствовать разницу. P.S: вас очень приветствуют :) – Amartel

1

Поскольку события нажатия мыши включены в цикл событий и ждут завершения вашего метода SnapshotClicked(), и к этому моменту кнопка снова будет включена.

Простым решением является вызов QCoreApplication::processEvents() сразу после emit, это приведет к обработке событий печати, пока кнопка все еще отключена. Или вы можете заставить метод DoSnapshotWork() излучать сигнал, когда он закончен, и активировать эту кнопку и разблокировать сигналы.

Кроме того,

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

repaint() перерисовывает виджет принудительно, в то время как update() вызовов repaint() через цикл обработки событий - не называть их обоих.

+0

Я попытался использовать метод processEvents(), прямо за emit DoSnapshotWork() и ничего не изменил. Но спасибо за подсказку с перерисовкой и обновлением. – Hafnernuss

Смежные вопросы