2013-10-31 91 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()来停止你的程序。