我有一个QPushButton对pressed()released()信号执行冗长的操作。在执行buttonPressed()插槽中的 Action 之前,如何确保已完成buttonReleased()插槽中的所有 Action ?

我已经尝试过使用QMutex,但是当互斥锁仍被buttonPressed()函数锁定时,尝试锁定按钮释放时,该程序似乎陷入了无限循环:

mymainwindow.h:

#include <QMutex>

// ...

QMutex mutex;

mymainwindow.cpp:
#include <QEventLoop>
#include <QTimer>

// ...

// In the main window constructor:
connect(myButton, SIGNAL(pressed()), this, SLOT(buttonPressed()));
connect(myButton, SIGNAL(released()), this, SLOT(buttonReleased()));

// ...

void MyMainWindow::buttonPressed()
{
    mutex.lock();

    // Here, I do the lengthy stuff, which is simulated by a loop
    // that waits some time.
    QEventLoop loop;
    QTimer::singleShot(1000, &loop, SLOT(quit()));
    loop.exec();

    mutex.unlock();
}

void MyMainWindow::buttonReleased()
{
    mutex.lock();

    // ... (some stuff)

    mutex.unlock();
}

最佳答案

通常,使用互斥锁是线程同步机制,在这里您不需要线程同步,因为您处于同一线程中。否则,我建议使用QWaitCondition等待标志/互斥体更改(即表示现在可以处理您的情况了)。

在您的情况下,您只需在完成“buttonPressed”操作(即计时器何时结束?)后就发出信号。如果buttonPressed()函数的结尾是您要执行buttonRelease()函数的时间,那么您可以简单地使用Qt::QueuedConnection来确保事件的正确顺序(我一般不喜欢直接连接,因为它们的行为类似于函数调用(甚至是中断-就像我认为发生在您身上的事情)。因此,以下更改可能会以一种简单的方式为您解决:

// In the main window constructor:
connect(myButton, SIGNAL(pressed()), this, SLOT(buttonPressed()), Qt::QueuedConnection);
connect(myButton, SIGNAL(released()), this, SLOT(buttonReleased()), Qt::QueuedConnection);

我不确定执行事件循环来“模拟”您的“长时间”是否可以工作....但是,如果您像以下那样做更多事情来模拟您的长时间执行,则:
QElapsedTimer elapsedTime;
elapsedTime.start();
while (elapsedTime.elapsed() < 1000) // millisecs
{
    // wait....
}

如果这不起作用,则只需在buttonPressed()的末尾发出信号,然后在buttonReleased()中设置一个标志,即可:
void MyMainWindow::buttonPressed()
{
    // actions here
    emit buttonPressedDone();
}

void MyMainWindow::buttonReleased()
{
    btnReleased = true;
}

void MyMainWindow::buttonPressedCompleted()
{
    if (btnReleased )
    {
        // Do button released actions here
        btnReleased  = false;
    }
    // I am assuming that if the flag is not set then you don't want to do anything... but up to you...
}

并连接buttonPressedDone-> buttonPressedCompleted

有更多的加载选项...这些只是您的更多选择...

09-06 04:31