2014-02-20 12 views
0

我想顯示除主GUI之外的「生成圖像...」類型的模式對話框。這個「生成圖像...」對話框應該是臨時的,並且在沒有用戶干預的情況下顯示並消失。Qt調試指針在第二次和連續迭代中沒有遵循預期流程

爲了顯示這個對話框,Qt代碼應該檢查PC硬盤中特定位置是否存在.txt文件。如果.txt文件存在,則彈出對話框。

爲了使該對話框消失,Qt代碼應檢查該.txt文件是否在第一行包含字符串「OK」。對話框只有在找到「OK」後纔會消失,直到此時它應該繼續顯示「正在生成圖像...」

一個很好的方法是使用信號插槽機制。我想知道,在這兩種情況下,顯示和刪除對話框都應該使用什麼函數作爲信號。到目前爲止,我可以管理一個簡單的代碼,使用信號插槽機制來說明一個「生成圖像...」,但是使用setValue()並按下一個按鈕(即涉及用戶干預),而不是通過檢查.txt文件或該.txt文件中的「OK」字符串(用戶不干預)。

請告訴我,我的邏輯是否可以實現?如果是,如何?另外,應該使用什麼信號?

** * ** * ** * ** * ** * ** * ** * ** *已更新部分(截至2014年2月24日): ** * ** * ** * ** * ** * ** * ** * ** * ** * ** * ** * ** * ** * ** * ** * ** * ** * *

我已根據德米特里薩佐諾夫的建議修改了代碼。無論何時在指定目錄中創建/刪除新文件,我都可以顯示加載GIF。現在我想關閉這個加載qDialog,當usbResponse.txt文件裏面有「ok」的時候。我試過使用信號插槽來實現hide(),但無法得到它。

我沒有收到錯誤,但qDialog窗口未按預期關閉。我嘗試了secDialog.close()和secDialog.hide(),但窗口沒有關閉。也許是因爲secDialog對象在兩個SLOT中都不相同。所以,我也做了secDialog,一個全球性的對象,但我如下收到錯誤: -

QWidget: Must construct a QApplication before a QWidget 

我看着它:https://qt-project.org/forums/viewthread/12838

改變了構建模式,因此,但這並沒有幫助。請告訴我如何關閉我的qDialogs,當我在usbResponse.txt文件中找到「ok」時。

** * ** * ** * ** * ** * ** * ** * ** *已更新部分(截至2014年3月14日): ** * ** * ** * ** * ** * ** * ** * ** * ** * ** * ** * ** * ** * ** * ** * ** * ** * *

我可以使用hide()關閉包含GIF的qDialog。我已經完成了代碼的全面改革。如上所述,只要名爲usbResponse.txt的文本文件存在於指定位置,就應該出現包含GIF的qDialog。同時採取@Dmitry Sazonov的建議,只要使用FileSystemWatcher修改了txt文件,即usbResponse.txt,我就可以關閉GIF。

我不斷使用線程掃描.txt的存在。當我找到該文件時,顯示加載GIF。當.txt被修改時,GIF應該消失。這對於第一次迭代,即,當 (下面是調試後的觀察結果)工作正常

  1. 的usbResponse.txt存在=> GIF顯示

  2. 當usbResponse.txt被修改=> GIF被隱藏& .txt被刪除。

該問題,在下一iteraiton,(即第一畢竟迭代)

  1. 的usbResponse.txt創建=>被顯示在GIF。

  2. 當usbResponse。TXT被修改,調試指針繼續留在

    afterFileHasBeenFound()

,而應該在

closeModified(const QString &str) 

什麼是我的錯在這裏都到哪裏去了? 這裏是我的代碼:

mainwindow.h

#ifndef MAINWINDOW_H 
    #define MAINWINDOW_H 

    #include <QMainWindow> 
    #include <QFile> 
    #include <QDebug> 
    #include <QFileSystemWatcher> 
    #include "dialog.h" 
    #include "mythread.h" 

    namespace Ui { 
    class MainWindow; 
    } 

    class MainWindow : public QMainWindow 
    { 
     Q_OBJECT 

    public: 
     explicit MainWindow(QWidget *parent = 0); 
     ~MainWindow(); 


    public slots: 
     void afterFileHasBeenFound(); 
     void closeModified(const QString &str); 

    private slots: 

    private: 
     Ui::MainWindow *ui; 
     Dialog *pDialog; 
     MyThread *mThread; 
    }; 

#endif // MAINWINDOW_H 

dialog.h

#ifndef DIALOG_H 
#define DIALOG_H 

#include <QDialog> 
#include <QMovie> 
#include <QLabel> 

#define GIF_PATH "E:\\QT1\\timeStampPopUp\\timeStampPopUp\\loading.gif" 
namespace Ui { 
class Dialog; 
} 

class Dialog : public QDialog 
{ 
    Q_OBJECT 

public: 
    explicit Dialog(QWidget *parent = 0); 
    ~Dialog(); 
    void displayLoadingGif(); 

private: 
    Ui::Dialog *ui; 
}; 

#endif // DIALOG_H 

mythread.h

#ifndef MYTHREAD_H 
#define MYTHREAD_H 

#include <QThread> 
#include <QtCore> 
#include <QDebug> 

#define FILE_PATH "E:\\QT1\\dialogClose2\\dialogClose2\\usbResponse.txt" 

class MyThread : public QThread 
{ 
    Q_OBJECT 
public: 
    explicit MyThread(QObject *parent = 0); 
    void run(); 
    QString name; 
    int exec(); 
    void checkFile(); 

signals: 
    void testSignal(QString message); 
    void fileFoundDisplayGif(); 

public slots: 

}; 

#endif // MYTHREAD_H 

dialog.cpp

#include "dialog.h" 
#include "ui_dialog.h" 

Dialog::Dialog(QWidget *parent) : 
    QDialog(parent), 
    ui(new Ui::Dialog) 
{ 
    ui->setupUi(this); 
    displayLoadingGif(); 
} 

Dialog::~Dialog() 
{ 
    delete ui; 
} 

void Dialog::displayLoadingGif() 
{ 
    QMovie *pMovie = new QMovie(GIF_PATH); 
    ui->loadingGifLabel->setMovie(pMovie); 
    pMovie->start(); 
} 

mythread.cpp

#include "mythread.h" 

MyThread::MyThread(QObject *parent) : 
    QThread(parent) 
{ 
} 

void MyThread::run() 
{ 
    exec(); 
} 

int MyThread::exec() 
{ 
    while(1) 
    { 
     checkFile(); 
     emit(testSignal("hello world!!")); 
     sleep(1); 
    } 
} 

void MyThread::checkFile() 
{ 
    QFile file(FILE_PATH); 
    if(file.exists()) 
    { 
     qDebug()<<"exists"; 
     emit(fileFoundDisplayGif()); 
    } 
    else 
     qDebug()<<"doesn't exist"; 
} 

mainwindow.cpp

#include "mainwindow.h" 
    #include "ui_mainwindow.h" 

    MainWindow::MainWindow(QWidget *parent) : 
     QMainWindow(parent), 
     ui(new Ui::MainWindow) 
    { 
     ui->setupUi(this); 
     mThread = new MyThread(this); 
     mThread->name = "mThread"; 
     connect(mThread, SIGNAL(fileFoundDisplayGif()), this, SLOT(afterFileHasBeenFound()), Qt::QueuedConnection); 
     mThread->start(); 
    } 

    MainWindow::~MainWindow() 
    { 
     delete ui; 
    } 

    void MainWindow::afterFileHasBeenFound() 
{ 
    if(pDialog != NULL) 
     return; 
    pDialog = new Dialog(); 
    pDialog->setModal(true); 
    pDialog->show(); 
} 

void MainWindow::closeModified(const QString &str) 
{ 
    Q_UNUSED(str) 
    if(pDialog != NULL) 
    { 
     pDialog->hide(); 
    } 
    QFile file(FILE_PATH); 
    file.remove(); 
    pDialog = NULL; 
} 

的main.cpp

#include "mainwindow.h" 
#include <QApplication> 

int main(int argc, char *argv[]) 
{ 
    QApplication a(argc, argv); 
    QFileSystemWatcher fileWatcher; 
    fileWatcher.addPath(FILE_PATH); 
    QStringList fileList = fileWatcher.files(); 
    Q_FOREACH(QString file, fileList) 
     qDebug() << "File name " << file; 
    MainWindow* mc = new MainWindow; 
    QObject::connect(&fileWatcher, SIGNAL(fileChanged(QString)), mc, SLOT(closeModified(QString))); 
    mc->show(); 


    return a.exec(); 
} 
+0

我想我會分開你的計時器或線程(來檢查文件)從QProgressDialog的視覺反饋。在你的主窗口中,我會啓動一個線程或計時器來永久檢查你的文件是否正在被創建,或者你的「OK」字符串沒有被創建。如果不是,我會通過dialog-> show()顯示一個額外的進度對話框。如果是,我會通過dialog-> close()關閉對話框。沒有信號/插槽。 – MichaelXanadu

+0

好@MichaelXanadu,我會試試看。 –

+0

在您的對話框中調用exec而不是show。在另一個線程中進行處理,並在線程完成時發出連接到對話框的拒絕插槽的信號。 – cppguy

回答

0

不要使用定時器檢查文件。使用QFileSystemWatcher進行文件修改。

實現一個插槽,用於檢查修改時的文件內容。當你的「OK」文本出現時,調用hide()方法。

恕我直言:你的解決方案是混亂。處理之間還有很多其他的同步機制。你能修改生成圖像的工具代碼嗎?它是否應該成爲另一個過程?

+0

嗨@Dmitry Sazonov,我根據你的建議更新了這個問題。 –

+0

在QWidget構造函數上放置一個斷點,並在QApplication之前查看它在哪裏創建它。你嘗試過調試器嗎? –

+0

嗨,@Dmitry Sazonov,當調試器沒有解決時,我改變了一下代碼。正如你所提到的那樣,這個缺陷是邏輯上的。所以我簡化了一下,但面臨一些困難。 –

相關問題