1

我的例子:

main.cpp:
    QApplication a(argc, argv);
    MainWindow w;
    w.start();
    return a.exec();


w.start():
    if (cf.exec()){
        this->show();
    } else {
        qDebug()<<"Need exit";
        //here should be exit
    }

在评论处,我尝试这样做: qApp->exit() 和 qApp->quit() 和 this->close() (但未显示“this”,并且当然 close() 不起作用)。如何从任何代码位置完成应用程序?


完整代码:
main.cpp

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

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

    return a.exec();
}


主窗口.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include "CadrForm.h"
#include "TeacherForm.h"
#include "DepartmentForm.h"
#include "CategoriesForm.h"
#include "PostForm.h"
#include "RanksAndDegreesForm.h"
#include "TeachersRankAndDegreeForm.h"
#include "ConnectionForm.h"

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = 0);
    void start();
    ~MainWindow();
signals:
    void widgetChanged(QWidget*);
private slots:
    void on_actionCadr_triggered();
    void resetMainLayout(QWidget* w);
    void on_actionTeacher_triggered();

    void on_actionDepartment_triggered();

    void on_actionPost_triggered();

    void on_actionCategories_triggered();

    void on_actionRanksAndDegrees_triggered();

    void on_actionTeachersRD_triggered();

private:
    ConnectionForm cf;
    CadrForm *cadrForm;
    TeacherForm *teacherForm;
    DepartmentForm *departmentForm;
    CategoriesForm *categoriesForm;
    PostForm *postForm;
    RanksAndDegreesForm *ranksAndDegreesForm;
    TeachersRankAndDegreeForm *teachersRankAndDegreeForm;
    QWidget *current;
    Ui::MainWindow *ui;

    void addWidgetToMainLayout(QWidget *w);
};

#endif // MAINWINDOW_H


主窗口.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDebug>

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    connect(this, SIGNAL(widgetChanged(QWidget*)), this, SLOT(resetMainLayout(QWidget*)));

    ui->setupUi(this);
    cadrForm = new CadrForm(this);
    teacherForm = new TeacherForm(this);
    departmentForm = new DepartmentForm(this);
    categoriesForm = new CategoriesForm(this);
    postForm = new PostForm(this);
    ranksAndDegreesForm = new RanksAndDegreesForm(this);
    teachersRankAndDegreeForm = new TeachersRankAndDegreeForm(this);

    addWidgetToMainLayout(cadrForm);
    addWidgetToMainLayout(teacherForm);
    addWidgetToMainLayout(departmentForm);
    addWidgetToMainLayout(categoriesForm);
    addWidgetToMainLayout(postForm);
    addWidgetToMainLayout(ranksAndDegreesForm);
    addWidgetToMainLayout(teachersRankAndDegreeForm);
}

void MainWindow::start()
{
    if (cf.exec()){
        this->show();
    } else {
        qDebug()<<"Need exit";
        qApp->quit();
        qDebug()<<"still working";
    }
}

void MainWindow::addWidgetToMainLayout(QWidget *w)
{
    ui->mainLayout->insertWidget(0, w);
    ui->mainLayout->itemAt(0)->widget()->hide();
}

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

void MainWindow::resetMainLayout(QWidget *w)
{
    int index;
    if (current)
    {
        index = ui->mainLayout->indexOf(current);
        ui->mainLayout->itemAt(index)->widget()->hide();
    }
    index = ui->mainLayout->indexOf(w);
    if (index != -1) ui->mainLayout->itemAt(index)->widget()->show();
    else {
        addWidgetToMainLayout(w);
        resetMainLayout(w);
    }
    current = w;
    setWindowTitle(current->windowTitle());
}

void MainWindow::on_actionCadr_triggered()
{
    emit widgetChanged(cadrForm);
}

void MainWindow::on_actionTeacher_triggered()
{
    emit widgetChanged(teacherForm);
}

void MainWindow::on_actionDepartment_triggered()
{
    emit widgetChanged(departmentForm);
}

void MainWindow::on_actionPost_triggered()
{
    emit widgetChanged(postForm);
}

void MainWindow::on_actionCategories_triggered()
{
    emit widgetChanged(categoriesForm);
}

void MainWindow::on_actionRanksAndDegrees_triggered()
{
    emit widgetChanged(ranksAndDegreesForm);
}

void MainWindow::on_actionTeachersRD_triggered()
{
    emit widgetChanged(teachersRankAndDegreeForm);
}

和 ConnectionForm - 它只是一个带有一些 GUI 并且没有任何额外代码的 QDialog。

4

3 回答 3

2

看起来问题是您不允许调用QApplication::quit()QApplication::exit()直到 QApplication 事件循环实际开始。事件循环开始于QApplication::exec(),所以你调用quit()/exit()太早了,它没有效果。

您可以通过移动quit()/exit()调用使其位于事件循环中(例如,通过将MainWindow::start()代码移动到QMainWindow::showEvent()插槽)来解决此问题,或者通过更改您MainWindow::start()的返回值、检查该值main并退出(不调用 QApplication:: exec()`) 如果它是一个表明你的进程应该提前退出的值。

于 2014-04-07T01:49:17.423 回答
1

将方法调用排队直到事件循环有机会运行的惯用方式是:

QMetaObject::invokeMethod(&w, "start", Qt::QueuedConnection);

因此,您main将成为:

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MainWindow w;
    QMetaObject::invokeMethod(&w, "start", Qt::QueuedConnection);
    return a.exec();
}
于 2014-04-07T13:12:50.347 回答
1

由于您“提前”启动了对话框事件循环(即阻塞),因此您不会进入应用程序的事件循环。

如果这是有意设计,您最好调用 exit(3) 并删除应用程序事件循环。

如果您想让应用程序事件循环运行,那么您需要确保它您到达对话执行点之前运行。

QTimer快速解决方法是在应用程序事件循环开始之前开始单次拍摄,这将触发您的“开始”方法调用。

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MainWindow w;
    w.start();
    QTimer::singleShot(200, w, SLOT(start()));
    return a.exec();
}

并将起点分别更改为插槽。

但是,从长远来看,您可能希望考虑使用按钮等来弹出对话框。

于 2014-04-07T01:57:02.980 回答