0

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

我已经尝试了所有这些。

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

2 回答 2

0

The exit functions you list exit the Qt event loop. In MainWindow::checkVersion() you call the exit before the event loop has been started. Even if you already had the loop running, you could start it again (which your code does).

Solution: make it so that the MainWindow::checkVersion() returns result code or just a bool, then start Qt event loop only if it is ok.

Code (remember to change the prototypes to match):

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

And then main() function to match:

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
    }
}

Note that your question code seems to have 3 event loops (hard to be sure with partial code), run one after the other.

  1. The local event loop in MainWindow constructor, which runs during loop.exec() call, and returns when QNAM sends it the signal to exit.

  2. The event loop started by QMessageBox::question() method, which shows the dialog and exits and returns with result when dialog is closed (I'm not sure if MainWindow is drawn on screen by this event loop or not, since you show it before this).

  3. The application main event loop, which you enter with a.exec(), and then return it's return value as program exit code when it exits (usually this is automatically triggered by last window being closed).

Note that w.show() just basically sets a flag that w should be visible and sends some event. It does not draw anything yet, and no Qt events get delivered anywhere, until event loop delivers them (duh). Something happens only, when you start the event loop to deliver events.

Another note: MainWindow consturctor is a totally wrong place to do something like that. Ideally an QWidget constructor should just set up the widget, nothing else (no user interaction, no network access). Typical pattern is to just set up the visible stuff there, then have extra initialization method, which you run once the window is actually visible (for example with a single-shot timer, or from overriden showEvent()). I suspect this is what you actually want to use for your code.

于 2013-10-31T21:11:21.097 回答
0

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

于 2013-11-01T07:42:31.013 回答