Question

My example:

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
    }

At comment place, I tried to do: qApp->exit() and qApp->quit() and this->close() (but 'this' not shown and of cource close() is not working). How can I finish app from any place of code?


Whole code:
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);
}

And ConnectionForm - it's just a QDialog with some GUI and without any additional code.

Was it helpful?

Solution

It looks like the problem is you're not allowed to call QApplication::quit() or QApplication::exit() until the QApplication event loop has actually started. The event loop gets started by QApplication::exec(), so you're calling quit()/exit() too soon for it to have an effect.

You can fix this either by moving the quit()/exit() call so that it's in the event loop (e.g. by moving your MainWindow::start() code to the QMainWindow::showEvent() slot), or by changing your MainWindow::start() to return a value, inspect that value in main, and exit (without calling QApplication::exec()`) if it's a value that indicates your process should exit early.

OTHER TIPS

Since you start the dialog event loop "early" - which is blocking -, you do not get to the event loop of the application.

If this is an intentional design, you better call exit(3) and remove the application event loop.

If you want to have the application event loop running, then you will need to make sure that it runs before you get to the point of your dialog execution.

The quick fix would be to start a single shot QTimer right just before the application event loop is started and that would trigger your "start" method call.

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

and change the start to a slot, respectively.

In the long run, you may wish to consider a button and so on for bringing your dialog up, however.

The idiomatic way of queuing a method call until the event loop gets a chance to run is:

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

Thus, your main would become:

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MainWindow w;
    QMetaObject::invokeMethod(&w, "start", Qt::QueuedConnection);
    return a.exec();
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top