如何从任何地方完成Qt程序
How to finish Qt programm from any place?
我的例子:
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();
}
- 为什么我的Qt程序在断言失败后继续运行?
- 使用MSVC编译的Qt程序在app.exec()上崩溃
- 如何设置一个简单的CGAL+Qt程序
- C++Qt程序设计问题
- 我的Qt程序可以编译,但是当我在声明中使用ifstream时崩溃
- 如何在Qt程序中实现IDv3标签
- 我如何将OpenSSL包含在Linux上的Qt程序中
- 我的QT程序显示带有标题的空白窗口
- 如何使用QT程序中的默认应用程序打开使用相对路径的PDF
- QT程序使用插入时会崩溃
- Qt程序读取文本只看到多行文件中的一行
- 当我尝试使用 makefile 编译我的 qt 程序时,它不起作用
- 使用现有C程序编写Qt程序时未找到的符号
- 使用Qt程序构建加密++时发生链接器错误
- 尝试实例化 QWidget 时 QT 程序出现段错误
- 为什么我的QT程序被卡住了
- 使QT/C 程序显示其文件类型,如Windows上已知
- QT程序无法编译/具有运行时错误(IDE:CodeBlocks/QTCreator)
- 如果对象父对象是窗口,则Qt程序运行缓慢
- Qt程序每次都冻结