无法关闭GUI程序

时间:2013-10-31 20:32:55

标签: c++ qt user-interface exit

在我的项目中,我有一个显示有两个按钮的对话框。如果有人按下“是”,那么我希望程序关闭。但我似乎无法让它发挥作用。

我尝试了所有这些。

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()的函数:

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()));
}

2 个答案:

答案 0 :(得分:0)

您列出的退出函数退出Qt事件循环。在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()方法启动的事件循环,显示对话框并退出并在对话框关闭时返回结果(我不确定是否通过此事件循环在屏幕上绘制MainWindow ,因为你之前show。)

  3. 应用程序主事件循环,您使用a.exec()输入,然后在退出时将其返回值作为程序退出代码返回(通常这是由关闭的最后一个窗口自动触发)。

  4. 请注意w.show()基本上只设置w应该可见的标志并发送一些事件。它还没有绘制任何东西,并且没有Qt事件可以在任何地方传递,直到事件循环传递它们(duh)。当你启动事件循环来传递事件时,只会发生一些事情。

    另一个注意事项:MainWindow consturctor是一个完全错误的地方做这样的事情。理想情况下,QWidget构造函数应该只设置窗口小部件,没有别的(没有用户交互,没有网络访问)。典型的模式是在那里设置可见的东西,然后有额外的初始化方法,一旦窗口实际可见就会运行(例如使用单次定时器,或来自覆盖showEvent())。我怀疑这是您实际想要用于代码的内容。

答案 1 :(得分:0)

您是否尝试在尚未启动时退出QEventLoop。 在这种情况下,使用std :: exit()来停止你的程序。