2014-08-28 47 views
0

在我的Qt應用程序按下按鈕後,我想隱藏那個按鈕並開始相當長的過程。當這個進程運行時,PushButton不應該是可見的,但它似乎在等待執行的進程以及隱藏按鈕之後。看起來QWidget在按鈕插槽功能結束後刷新。這是我的簡化的代碼:Qt控件元素不想隱藏

void MainWindow::on_pushButton_clicked() 
{ 
    ui->progressBar->setVisible(true); 
    ui->pushButton->setVisible(false); 

    while(x<1000000) x++; //e.g of my long time function 
} 

當該函數(()on_pushButton_clicked - 小鼠 - 通過產生>>去時隙)結束了我的「視圖」被更新和按鈕dissappear。 是否有任何功能來刷新我的小部件或maby我忘了什麼?

在此先感謝

回答

1

爲了使按鈕更改狀態,它需要返回到事件循環中的處理事件。

爲了解決這個問題,你可以在while循環之前調用QApplication::processEvents,儘管在啓動長時間函數之前,通過調用函數作爲QueuedConnection自然返回到事件循環會更好。

或者,更好的方法是在一個單獨的線程通過創建一個對象來封裝功能來運行的功能,這將使您的GUI中的「長函數」

開始的處理過程中保持活性這將做的工作: -

class Worker : public QObject { 
    Q_OBJECT 

public: 
    Worker(); 
    ~Worker(); 

public slots: 
    void process(); // This is where your long function will process 

signals: 
    void finished(); 
    void error(QString err);  
}; 

void Worker::process() 
{ 
    while(x<1000000) x++; //e.g of my long time function 

    emit finished(); 
} 

創建一個新的線程,並啓動按鈕被點擊

void MainWindow::on_pushButton_clicked() 
{ 
    // change button visibility 
    ui->progressBar->setVisible(true); 
    ui->pushButton->setVisible(false); 

    // create the new thread and start the long function 
    QThread* thread = new QThread; 

    Worker* worker = new Worker(); 
    worker->moveToThread(thread); 

    connect(worker, SIGNAL(error(QString)), this, SLOT(errorString(QString))); 
    connect(thread, SIGNAL(started()), worker, SLOT(process())); 

    //ensure the objects are cleared up when the work is done 
    connect(worker, SIGNAL(finished()), thread, SLOT(quit())); 
    connect(worker, SIGNAL(finished()), worker, SLOT(deleteLater())); 
    connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater())); 

    //start the thread and the long function processing 
    thread->start();   
} 
+0

創建一個全新的類,所有的鍋爐都是矯枉過正的。將長期運行的代碼分離成一個私有函數並獲得'QtConcurrent'來完成所有線程設置和執行會更好。 – RobbieE 2014-08-29 05:53:17

+0

@RobbieE是的,這是很多代碼,但我會避免QtConcurrent:http://comments.gmane.org/gmane.comp.lib.qt.devel/7942 – TheDarkKnight 2014-08-29 07:42:26

2

變化到GUI AR時直到程序有機會重繪本身,直到你回來纔會發生。

你需要以某種方式推遲代碼的執行:

void MainWindow::on_pushButton_clicked() 
{ 
    ui->progressBar->setVisible(true); 
    ui->pushButton->setVisible(false); 

    QMetaObject::invokeMethod(this, &MainWindow::longFunction, Qt::QueuedConnection); 
} 

void MainWindow::longFunction() 
{ 
    while(x<1000000) x++; //e.g of my long time function 
} 

這將返回到事件循環,然後運行longFunction,但它仍然會阻塞和進度條將不會顯示任何更新,直到完成。

爲了解決這個問題,您需要將執行過程移至新線程或將功能拆分爲較短部分,然後依次使用QMetaObject::invokeMethodQueuedConnection調用它們。