Как закончить программу Qt из любого места?

Мой пример:

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

mainwindow.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

mainwindow.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 — это просто QDialog с некоторым GUI и без какого-либо дополнительного кода.

1

Решение

Похоже, проблема в том, что вам нельзя звонить QApplication::quit() или же QApplication::exit() пока цикл событий QApplication фактически не начался. Цикл событий запускается QApplication::exec()так ты звонишь quit()/exit() слишком рано, чтобы это дало эффект.

Вы можете исправить это, переместив quit()/exit() вызовите, чтобы он был в цикле событий (например, перемещая MainWindow::start() код для QMainWindow::showEvent() слот), или изменив MainWindow::start() чтобы вернуть значение, проверьте это значение в mainи завершите работу (без вызова QApplication :: exec () `), если это значение указывает, что ваш процесс должен завершиться досрочно.

2

Другие решения

Поскольку вы запускаете цикл событий диалога «рано» — который блокирует — вы не попадаете в цикл событий приложения.

Если это намеренный дизайн, лучше вызвать 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();
}

и измените начало на слот, соответственно.

В конечном счете, вы можете рассмотреть вопрос о кнопке и т. Д., Чтобы открыть диалог.

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();
}
1
По вопросам рекламы [email protected]