2013-10-31 76 views
0

在我的項目中,我有一個顯示有兩個按鈕的對話框。如果有人按下「是」,那麼我希望程序關閉。但我似乎無法讓它工作。無法關閉GUI程序

我試過所有這些。

qApp->exit(); 
qApp->quit(); 
QApplication::exit(); 
QApplication::quit(); 
QCoreApplication::exit(); 
QCoreApplication::quit(); 

而這些都沒有關閉程序。我試着將它們移動到我的main.cpp中,我嘗試了第二個函數只是爲了關閉,沒有任何效果。

它會與我的事件循環更早檢查更新有什麼關係嗎?如果是這樣,我會發布它。

編輯:

這是我的main.cpp和,我想我的程序關閉功能:

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

int main(int argc, char *argv[]) 
{ 
    Q_INIT_RESOURCE(icons); 
    QApplication a(argc, argv); 
    MainWindow w; 
    w.show(); 
    w.checkVersion(); 

    return a.exec(); 
} 

功能:

void MainWindow::checkVersion() 
{ 
    if((version != "1.0.0") && (version != ""))//version is a string that is filled when the mainwindow first opens. 
    { 
     QMessageBox::StandardButton reply; 
     reply = QMessageBox::question(this, "Update", "Version " + version + " is now available. Would you like to update now?\n\nOr visit http://www.youtube.com/oPryzeLP to download manually.", QMessageBox::Yes | QMessageBox::No); 

     if(reply == QMessageBox::Yes) 
     { 
     } 
     QApplication::exit();//moved out of reply just to test closing 
    } 
} 

這是包含的功能事件循環:

void MainWindow::downloadFile(const QString &url, const QString &aPathInClient) 
{ 
    QNetworkAccessManager* m_NetworkMngr = new QNetworkAccessManager(this); 
    QNetworkReply *reply = m_NetworkMngr->get(QNetworkRequest(QUrl(url))); 
    QEventLoop loop; 
    connect(reply, SIGNAL(finished()), &loop, SLOT(quit())); 
    loop.exec(); 
    QUrl aUrl(url); 
    QFileInfo fileInfo=aUrl.path(); 

    QFile file(aPathInClient+"\\"+fileInfo.fileName()); 
    file.open(QIODevice::WriteOnly); 
    file.write(reply->readAll()); 
    delete reply; 
    loop.quit(); 
} 

這是調用downloadFile()函數:你列出退出了Qt事件循環

MainWindow::MainWindow(QWidget *parent) : 
    QMainWindow(parent), 
    ui(new Ui::MainWindow) 
{ 
    ui->setupUi(this); 
    downloadFile("link", "stuff"); 
    QFile info("stuff\\info.txt"); 
    if(info.open(QIODevice::ReadOnly)) 
    { 
     QTextStream in(&info); 
     while(!in.atEnd()) 
     { 
      version = in.readLine(); 
      versionLink = in.readLine(); 
      vidLink = in.readLine(); 
     } 
    } 
    info.close(); 

    setCentralWidget(ui->tabWidget); 
    ui->creativeFlag->setEnabled(false); 
    ui->structures->setEnabled(false); 
    ui->raining->setEnabled(false); 
    ui->thundering->setEnabled(false); 
    ui->hardcore->setEnabled(false); 
    AddSlotsToGroup(); 
    AddBlocksToGroup(); 
    QPalette palette = ui->blockFrame->palette(); 
    palette.setColor(backgroundRole(), QColor(139, 139, 139)); 
    ui->blockFrame->setPalette(palette); 
    ui->blockFrame->setAutoFillBackground(true); 
    QPixmap map_bg(":/images/mapbg.png"); 
    ui->mapBgLabel->setPixmap(map_bg.scaled(224, 224, Qt::IgnoreAspectRatio, Qt::FastTransformation)); 
    QShortcut *returnShortcut = new QShortcut(QKeySequence("Return"), ui->tab_4); 
    QObject::connect(returnShortcut, SIGNAL(activated()), ui->blockFind, SLOT(click())); 
} 
+0

發佈重現問題的最小測試用例。將所有代碼放入一個文件(main.cpp,用於類聲明和實現)。如果你有任何'Q_OBJECT'宏,你可以'#include「main.moc」'。 –

+0

在dialog.exec()之前調用app.exec(),還是直接在main()中打開對話框? –

+0

我將用我的main.cpp和我要關閉的函數更新這篇文章。 – mrg95

回答

0

退出功能。在MainWindow::checkVersion()中,您在事件循環啓動之前調用退出。即使你已經有循環運行,你可以再次啓動它(你的代碼是這樣做的)。

解決方案:使其成爲MainWindow::checkVersion()返回結果代碼或僅返回結果代碼bool,然後只有在正常時才啓動Qt事件循環。

代碼(記得更改原型匹配):

bool MainWindow::checkVersion() 
{ 
    //version is a string that is filled IN MAINWINDOW CONSTRUCTOR, IT SEEMS 
    if((version != "1.0.0") && (version != "")) 
    { 
     QMessageBox::StandardButton reply; 
     reply = QMessageBox::question(this, "Update", "Version " + version + " is now available. Would you like to update now?\n\nOr visit http://www.youtube.com/oPryzeLP to download manually.", QMessageBox::Yes | QMessageBox::No); 

     // return true if current version is ok 
     return !(reply == QMessageBox::Yes); 
    } 
    else { 
     // version is either 1.0.0 or empty 
     return true; 
} 

然後main()功能匹配:

int main(int argc, char *argv[]) 
{ 
    Q_INIT_RESOURCE(icons); 
    QApplication a(argc, argv); 
    MainWindow w; 
    w.show(); 

    if (w.checkVersion()) { 
     // version is ok, start the main event loop 
     return a.exec(); 
    } else { 
     // user wants to upgrade, do something, or just exit? 
     return 0; // or whatever exit code you want 
    } 
} 

需要注意的是你的問題的代碼似乎有3個事件循環(很難確定部分代碼),依次運行。

  1. MainWindow構造函數,它loop.exec()通話過程中運行,返回時QNAM將其發送的信號,退出本地事件循環。

  2. 事件循環由QMessageBox::question()方法,它顯示了結果對話框,然後退出並返回時關閉對話框啓動(我不知道如果主窗口繪製在屏幕上通過此事件循環或沒有,因爲你show它在這之前)。

  3. 應用程序主事件循環,與a.exec()一起輸入,然後在退出時將其返回值作爲程序退出代碼返回(通常這是由最後一個窗口關閉時自動觸發的)。

注意w.show()基本上只是設置一個w應該是可見的一個標誌,併發送一些事件。它沒有畫任何東西,也沒有Qt事件在任何地方傳遞,直到事件循環傳遞它們(杜)。當您啓動事件循環來傳遞事件時,只會發生某些事情。

另一個說明:MainWindow consturctor是一個完全錯誤的地方做類似的事情。理想情況下,一個QWidget構造函數應該只設置這個小部件,沒有別的(沒有用戶交互,沒有網絡訪問)。典型的模式是在那裏設置可見的東西,然後有額外的初始化方法,一旦窗口實際可見(例如使用單次計時器,或從覆蓋showEvent())運行。我懷疑這是你真正想要用於你的代碼。

+0

哪個函數應該返回結果代碼? Qt事件循環在checkVersion函數之前運行。事件循環用於下載一個txt文件,從那裏checkVersion檢查txt文件。 – mrg95

+0

事件循環在關閉功能之前啓動。它必須或者checkVersion函數不知道要顯示什麼(它顯示事件循環的結果) – mrg95

+0

我在w.show()中啓動事件循環;事件循環將文件下載到磁盤,並將其讀入字符串。然後checkVersion將顯示該字符串。如果事件循環發生在checkVersion之後,它如何顯示字符串? – mrg95

0

您是否試圖在QEventLoop尚未啓動時退出? 在這種情況下使用std :: exit()來停止你的程序。