我有一个错误,在关闭我的应用程序后,我收到一条错误消息,说它已意外停止。我达到了这个目的:
但是,关闭窗口后,我收到此错误:
该程序意外完成。这个过程结束了 用力。
我的项目结构是:
我的代码是:
的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());
}
提前致谢!
答案 0 :(得分:5)
将小部件添加到布局时,例如
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();
}
之前的范围。
更改两个对象创建顺序将导致应用程序在退出时崩溃:
data: {
labels: chart_label,
datasets: [{
label: '# of Votes',
data: chart_data,
backgroundColor: [
'rgba(255, 99, 132, 0.2)',
'rgba(54, 162, 235, 0.2)',
'rgba(255, 206, 86, 0.2)',
'rgba(75, 192, 192, 0.2)',
'rgba(153, 102, 255, 0.2)',
'rgba(255, 159, 64, 0.2)'
],
borderColor: [
'rgba(255,99,132,1)',
'rgba(54, 162, 235, 1)',
'rgba(255, 206, 86, 1)',
'rgba(75, 192, 192, 1)',
'rgba(153, 102, 255, 1)',
'rgba(255, 159, 64, 1)'
],
borderWidth: 1
}]
},
答案 1 :(得分:0)
您已自己删除了QMainWindow
个元素:
delete this->lblHost;
当QObject
继承的对象与父对象一起在堆上创建时,您不应该自己删除它。因为QObject
树将负责内存的内存管理。
所以将两次删除。