如何从任何地方完成Qt程序

How to finish Qt programm from any place?

本文关键字:Qt 程序 方完成 任何地      更新时间:2023-10-16

我的例子:

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"未显示,并且 cource close() 不起作用)。如何从任何代码位置完成应用程序?


整个代码:
主.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);
}

和连接表单 - 它只是一个带有一些GUI的QDialog,没有任何额外的代码。

看起来问题是在 QApplication 事件循环实际启动之前,您不允许调用QApplication::quit()QApplication::exit()。事件循环由 QApplication::exec() 启动,因此您调用 quit()/exit() 太早了,无法产生影响。

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

由于您"提前"启动对话框事件循环 - 这是阻塞的 - 因此您不会进入应用程序的事件循环。

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

如果要运行应用程序事件循环,则需要确保它在到达对话执行点之前运行。

快速解决方法是在应用程序事件循环启动之前QTimer启动单次拍摄,这将触发"start"方法调用。

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

并分别将开始更改为插槽。

但是,从长远来看

,您可能希望考虑使用按钮等来显示对话框。

事件循环有机会运行之前对方法调用进行排队的惯用方法是:

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