Qt关闭QMainWindow后如何防止崩溃?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Qt关闭QMainWindow后如何防止崩溃?相关的知识,希望对你有一定的参考价值。
我有一个错误,在关闭我的应用程序后,我收到一条错误消息,说它已意外停止。我达到了这个:
但是,在关闭窗口后,我收到此错误:
该计划意外完成。这个过程有力地结束了。
我的项目结构是:
我的代码是:
main.cpp中
#include "mainwindow.h"
#include <QApplication>
#include <windows/login.h>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Login w;
w.show();
return a.exec();
}
util_window.h
#ifndef UTIL_H
#define UTIL_H
#include <QObject>
#include <QMainWindow>
class UtilWindow : QObject
{
public:
// vars
// methods
util();
void setCenterWindow(QMainWindow* w);
};
#endif // UTIL_H
util_window.cpp
#include "util_window.h"
#include <QDesktopWidget>
UtilWindow::util()
{
}
void UtilWindow::setCenterWindow(QMainWindow *w) {
int width = w->frameGeometry().width();
int height = w->frameGeometry().height();
QDesktopWidget wid;
int screenWidth = wid.screen()->width();
int screenHeight = wid.screen()->height();
w->setGeometry((screenWidth/2)-(width/2),(screenHeight/2)-(height/2),width,height);
w->show();
}
login.h
#ifndef LOGIN_H
#define LOGIN_H
#include <QMainWindow>
#include <QObject>
#include <QWidget>
#include "util/util_window.h"
#include <QGroupBox>
#include <QLabel>
#include <QLineEdit>
#include <QFormLayout>
class Login : public QMainWindow
{
Q_OBJECT
public:
// vars
UtilWindow* util;
// widgets
// labels
QLabel* lblHost;
QLabel* lblPort;
QLabel* lblUser;
QLabel* lblPass;
// textbox
QLineEdit* leHost;
QLineEdit* lePass;
QLineEdit* leUser;
QLineEdit* lePort;
// layouts
QFormLayout* layout;
QWidget* central;
QVBoxLayout* mainLayout;
QGroupBox* gbCredentials;
// methods
void initLabels();
void initTextBoxes();
void initUI();
explicit Login(QWidget *parent = nullptr);
~Login();
signals:
public slots:
};
#endif // LOGIN_H
login.cpp
#include "login.h"
Login::Login(QWidget *parent) : QMainWindow(parent)
{
this->util = new UtilWindow();
this->initUI();
}
Login::~Login() {
delete this->lblHost;
delete this->lblPass;
delete this->lblPort;
delete this->lblUser;
delete this->leHost;
delete this->lePass;
delete this->lePort;
delete this->leUser;
delete this->layout;
delete this->central;
delete this->mainLayout;
delete this->gbCredentials;
delete this->util;
}
void Login::initUI() {
this->setFixedSize(400,400);
this->setWindowTitle(tr("Inicio de sesión"));
this->util->setCenterWindow(this);
this->initLabels();
this->initTextBoxes();
this->layout = new QFormLayout();
this->layout->addRow(this->lblHost, this->leHost);
this->layout->addRow(this->lblPort, this->lePort);
this->layout->addRow(this->lblUser, this->leUser);
this->layout->addRow(this->lblPass, this->lePass);
this->gbCredentials = new QGroupBox();
this->gbCredentials->setTitle(tr("Datos de conexión"));
this->gbCredentials->setLayout(layout);
this->mainLayout = new QVBoxLayout();
this->mainLayout->addWidget(gbCredentials);
this->central = new QWidget();
this->central->setParent(this);
this->central->setLayout(this->mainLayout);
this->setCentralWidget(this->central);
}
void Login::initLabels() {
this->lblHost = new QLabel();
this->lblPass = new QLabel();
this->lblPort = new QLabel();
this->lblUser = new QLabel();
this->lblHost->setText(tr("Host: "));
this->lblPass->setText(tr("Contraseña: "));
this->lblPort->setText(tr("Puerto: "));
this->lblUser->setText(tr("Usuario: "));
}
void Login::initTextBoxes() {
this->leHost = new QLineEdit();
this->lePass = new QLineEdit();
this->lePort = new QLineEdit();
this->leUser = new QLineEdit();
this->leHost->setPlaceholderText(tr("Host de mysql"));
this->lePass->setPlaceholderText(tr("Ingrese su contraseña"));
this->leUser->setPlaceholderText(tr("Ingrese su nombre de usuario"));
this->lePort->setPlaceholderText(tr("Ingrese el número de puerto"));
this->leHost->setToolTip(this->leHost->placeholderText());
this->leUser->setToolTip(this->leUser->placeholderText());
this->lePass->setToolTip(this->lePass->placeholderText());
this->lePort->setToolTip(this->lePort->placeholderText());
}
提前致谢!
将小部件添加到布局时,例如
this->layout.addRow(&(this->lblHost), &(this->leHost));
你正在将它们添加到布局的小部件中,在这种情况下是你的Login主窗口,当调用父小部件析构函数时,所有子小部件都将是delete
'd。您的代码中发生的事情是:子项(行编辑和标签)未使用new
实例化,因此对它们调用delete将导致应用程序崩溃。您应该使用指针替换窗口小部件标头中的子声明,这样:
QLabel * lblHost;
// ...
QLineEdit * leHost;
// etc
并在将它们添加到布局之前实例化它们:
this->lblHost = new QLabel();
this->leHost = new QLineEdit();
this->layout.addRow(this->lblHost, this->leHost);
//etc
这适用于具有父级(即中央Qwidget)的所有布局和小部件。
另外:不需要在子节点上明确调用delete
,因为父析构函数会处理它,这也适用于central widget:
QMainWindow获取小部件指针的所有权并在适当的时候删除它
正如thuga在评论中指出的那样,在堆栈中实例化子进程没有任何内在错误,只要他们的析构函数在其父级之前被调用,因此它们会自动从父级子列表中删除,并且父析构函数不会在它们上调用delete
。
正如here所解释的那样,这是合法的:
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QWidget widget;
QLabel label(&widget);
widget.show();
return a.exec();
}
因为label
将在widget
之前超出范围。
更改两个对象创建顺序将导致应用程序在退出时崩溃:
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QLabel label;
QWidget widget;
label.setParent(&widget);
widget.show();
return a.exec();
}
以上是关于Qt关闭QMainWindow后如何防止崩溃?的主要内容,如果未能解决你的问题,请参考以下文章