Qt MainWindow崩溃了

时间:2014-04-04 12:54:14

标签: c++ qt qtgui qmainwindow qt-signals

编辑:我从插槽中删除了析构函数。但现在我有内存泄漏问题。我打开的每个新窗口占用一些内存,当我关闭它时,内存保持占用

当我执行程序并打开新窗口时,它们会正常打开。当我关闭它们中的任何一个时,整个应用程序崩溃(不仅是那个特定的窗口),我得到了崩溃错误。

我做错了什么?

mainWindow.h:

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
class QHBoxLayout;
class QTextEdit;
class QWidget;
class QDialog;
namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();
public slots:
    void closeWindow();
    void newWindow();

private:
    Ui::MainWindow *ui;
    MainWindow *tempMainWindow;
    QHBoxLayout * mainLyt;
    QTextEdit *txtEdit;
    QWidget *mainWidget;
};

#endif // MAINWINDOW_H

mainWindow.cpp:

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QWidget>
#include <QHBoxLayout>
#include <QTextEdit>

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    mainWidget=new QWidget();
    mainLyt=new QHBoxLayout();
    txtEdit=new QTextEdit();
    mainLyt->addWidget(txtEdit);
    mainWidget->setLayout(mainLyt);
    setCentralWidget(mainWidget);
    connect(ui->actionExit,SIGNAL(triggered()),this,SLOT(closeWindow()));
    connect(ui->actionNew,SIGNAL(triggered()),this,SLOT(newWindow()));
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::closeWindow()
{
    this->close();
    delete txtEdit;
    delete mainLyt;
    delete mainWidget;
    this->~MainWindow();
}

void MainWindow::newWindow()
{
    tempMainWindow=new MainWindow(this);
    tempMainWindow->show();
}

3 个答案:

答案 0 :(得分:1)

如果您转到QWidget()QHBoxLayout()QTextEdit()this(这是父母),在MainWindow Qt的选择中将删除ui以及在委托人中定义的所有其他小部件。这样您就可以避免调用closeWindow()方法。

delete ui也没有必要。

ui->setupUi(this);
mainWidget = new QWidget(this);
mainLyt = new QHBoxLayout(this);
txtEdit = new QTextEdit(this);

答案 1 :(得分:1)

  

我尝试制作基本的文本编辑器,当触发New时,它应该为新的文本文档打开一个新窗口。有没有更好的方法来做到这一点?

是。它被称为factory,它可以是静态方法,因为它不对任何对象进行操作。当然,你可以从一个插槽中调用它。

我想你需要将文件名传递给新创建的窗口 - 这可能是工厂方法和工厂插槽的参数。如果&#34;新&#34;窗口是空的,那么这不是问题。

其他问题:

  1. 没有理由保留mainWidget成员:它始终以centralWidget()的形式提供。

  2. 还没有理由让ui以外的成员作为指针。这实际上是一种过早的悲观 - 它会浪费更多的堆内存。

  3. 如果没有子窗口小部件,您不需要中央窗口小部件的布局。 QTextEdit实例本身可以是中心小部件。

  4. 应使用智能指针保留ui实例。这使得析构函数完全由编译器生成(它有一个空体)。

  5. 您在closeWindow广告位中不需要任何想象力。只需删除实例!

  6. class MainWindow : public QMainWindow
    {
      Q_OBJECT
    public:
      explicit MainWindow(QWidget *parent = 0);
      ~MainWindow();
      static MainWindow * createWindow();
      void setFileName(const QString & fileName);
    public slots:
      void closeWindow();
      void newWindow();
    private:
      QScopedPointer<Ui::MainWindow> const ui;
      QTextEdit m_txtEdit;
    };
    
    void MainWindow::newWindow() {
       createWindow()->show();
    }
    
    void MainWindow::closeWindow() {
      deleteLater();
    }
    
    MainWindow * MainWindow::createWindow(QWidget * parent) {
      return new MainWindow(parent);
    }
    
    MainWindow::MainWindow(QWidget *parent) :
        QMainWindow(parent),
        ui(new Ui::MainWindow)
    {
      ui->setupUi(this);
      setCentralWidget(&m_txtEdit);
      connect(ui->actionExit, SIGNAL(triggered()), SLOT(closeWindow()));
      connect(ui->actionNew, SIGNAL(triggered()), SLOT(newWindow()));
    }
    
    MainWindow::~MainWindow()
    {}
    

答案 2 :(得分:0)

让我们看看您的代码:

this->close();
delete txtEdit;
delete mainLyt;
delete mainWidget;
this->~MainWindow();

你正试图摧毁它们,而对于下一次打开你几乎以同样的方式分配它们。

你在这里取得的成就基本上是性能损失。我建议隐藏,修改等不需要的项目。