2013-08-03 81 views
0

我在我的主线程上有一个QDialog,并且我在某个单独的线程上发生了一些逻辑。当逻辑开始时,发出的信号连接到对话框上的show()。当逻辑结束时,会发出一个信号,该信号连接到对话框上的hide()。当逻辑实际上工作时,对话框正确显示/隐藏。如果逻辑没有“没有”并且信号只是按顺序发射,则对话并不总是正确显示/隐藏。QT QDialog快速显示/隐藏时不能正确隐藏

我的连接是由与此类似:

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)发出信号后show()对话框。我不喜欢这个解决方案,但似乎没有其他工作。睡眠(1)允许对话框在隐藏之前一路向上。我也能够得到这个与QThread :: msleep(10)一起工作,但仍然导致鬼影对话大约每6次尝试一次。

我试图在对话逻辑中使用成员QMutex,无论何时我调用show()或hide(),但这不起作用。

我改变了所有使用Qt :: BlockingQueuedConnection和Qt :: QueuedConnection的跨线程连接,并且都没有成功。

我尝试将对话框中的插槽连接移动到设置连接然后直接调用插槽的对象,但这也未证明是成功的。

回答

0

我的猜测是问题发生是因为“显示”和“隐藏”调用交错。要验证这一点,请使用信号量 - 锁定对象直到显示完成,然后等待隐藏。另请看这里最受欢迎的答案,以寻找另一种可能(或许更好)的解决方案:connecting signal/slot across different threads between QObjects

+0

使用QMutex在Show()/ Hide()函数中设置锁定,以在操作前后锁定/解锁;没有成功。我还通读了链接解决方案并尝试了所有逻辑连接类型,问题仍然存在。 –

0

使用Qt::BlockingQueuedConnection将信号连接到插槽。确保主线程的事件循环没有被阻塞。另外,如果您的工作线程使用大量的CPU时间 - 您可以拨打QThread::yeldCurrentThread()电话。