gpt4 book ai didi

c++ - 在 Qt 中关闭 QMainWindow 后如何防止崩溃?

转载 作者:搜寻专家 更新时间:2023-10-31 00:27:43 26 4
gpt4 key购买 nike

我有一个错误,就在关闭我的应用程序后,我收到一条错误消息,指出它已意外停止。我达到了这个:

enter image description here

但是,在我关闭窗口后,出现了这个错误:

The program has unexpectedly finished. The process was ended forcefully.

我的项目结构是:

enter image description here

我的代码是:

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

登录.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

登录.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));

您将它们作为布局小部件的父级,在本例中为您的登录主窗口,当调用父小部件析构函数时,所有子小部件都将被删除。您的代码中发生的情况是:子项(行编辑和标签)使用new 实例化,因此对它们调用 delete 会使您的应用程序崩溃。您应该用指针替换小部件 header 中的子声明,这样:

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 takes ownership of the widget pointer and deletes it at the appropriate time

正如 thuga 在评论中指出的那样,在堆栈上实例化子项本身并没有错,只要它们的析构函数在其父项的析构函数之前被调用,因此它们会自动从父项的子项列表中删除并且父项的析构函数不会调用删除它们。

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

关于c++ - 在 Qt 中关闭 QMainWindow 后如何防止崩溃?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47988560/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com