我的主线程上有一个 QDialog,我有一些逻辑发生在一个单独的线程上。当逻辑开始时,会发出一个连接到对话框上的 show() 的信号。当逻辑结束时,会发出一个连接到对话框上的 hide() 的信号。当逻辑确实起作用时,对话框会正确显示/隐藏。如果逻辑“什么都不做”并且信号只是按顺序发出,则对话框并不总是正确显示/隐藏。
我的连接与此类似:
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget* parent = 0) :
Ui(new Ui::MainWindowUi),
Transferer(new DataTransferer()),
TransferProgress(this),
TransferThread()
{
Ui->setupUi();
connect(&Transferer, SIGNAL(Begin()), &TransferProgress, SLOT(show()));
connect(&Transferer, SIGNAL(End()), &TransferProgress, SLOT(hide()));
Transferer.moveToThread(&TransferThread);
TransferThread.start();
Transferer.DoStuff(true);
}
virtual ~MainWindow()
{
TransferThread.quit();
TransferThread.wait(1000);
delete Ui;
Ui = NULL;
}
private:
Ui::MainWindowUi* Ui;
DataTransferer Transferer;
TransferProgressDialog TransferProgress;
QThread TransferThread;
}
逻辑看起来类似于:
class DataTransferer : public QObject
{
Q_OBJECT
public:
DataTransferer(QObject *parent) : QObject(parent) {}
virtual ~DataTransferer() {}
void DoStuff(bool dontDoStuff)
{
emit Start();
if (!dontDoStuff)
{
QThread::sleep(1);
}
emit End();
}
}
当 DataTransferer 做事时,一切正常。当对话框快速连续显示和隐藏时,我大约每隔一次调用 DoStuff() 就会得到一个幽灵对话框。
我使用了 QThread::currentThreadId() 并验证了对话框和逻辑在不同的线程上运行。
在这种情况下,为什么我的对话框不能正确隐藏?我是否应该强制我的逻辑始终运行至少几百毫秒(该解决方案很糟糕)?有没有办法让我的对话框在尝试隐藏之前确保它已完全加载?我应该以不同的方式处理这些信号/插槽吗?
编辑:我目前已经辞职,只是在我发出信号显示()对话框后放置一个 QThread::sleep(1) 。我不喜欢这个解决方案,但似乎没有其他方法有效。sleep(1) 允许对话框在隐藏之前一直出现。我也能够让它与 QThread::msleep(10) 一起工作,但这仍然导致大约 6 次尝试中的 1 次出现幽灵对话框。
每当我调用 show() 或 hide() 时,我都尝试在对话框逻辑中使用成员 QMutex,但这不起作用。
我将所有跨线程连接更改为使用 Qt::BlockingQueuedConnection 和 Qt::QueuedConnection ,但都没有成功。
我尝试将插槽连接从对话框移动到设置连接的对象,然后直接调用插槽,但这也没有证明是成功的。