Question

Edit: I removed the destructor from the slot. But now I have memory leaking problems. Each new window that I open occupies some memory,and when I close it,the memory stays occupied

When I execute the program,and open new windows, they are opened normally. When I close any of them, the whole application crashes (not only that specific window),and I get the crash error.

What am I doing wrong?

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();
}
Was it helpful?

Solution 3

Let us see your code:

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

You are trying to destroy them and for the next open you allocate them almost the same way.

What you achieve here is basically performance penalty. I would suggest to hide, modify, and so on the unwanted items instead.

OTHER TIPS

If you pass to QWidget(), QHBoxLayout() and QTextEdit() also this (which is the parent), at the delection of the MainWindow Qt will delete for you the ui and all the additional widgets yur defined in the construstor. In this way you can avoid to call closeWindow() method.

delete ui is also not necessary.

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

I'm trying to make basic text editor,and when New is triggered, it should open a new window for new text document. Is there some better way to do this?

Yes. It's called a factory, and it can be a static method as it doesn't operate on any object. You can call it from a slot, of course.

I imagine you'll need to pass a file name to the newly created window - that could be an argument to the factory method and the factory slot. If the "new" window is empty, then this is not an issue.

Other issues:

  1. There is no reason to keep the mainWidget member: it is always available as centralWidget().

  2. There's also no reason to have the members other than ui as pointers. It is actually a premature pessimization - it will waste a bit more heap memory.

  3. You don't need a layout for the central widget if it has no child widgets. The QTextEdit instance itself can be the central widget.

  4. The ui instance should be retained using a smart pointer. This makes the destructor completely compiler-generated (it has an empty body).

  5. You don't need anything fancy in the closeWindow slot. Simply delete the instance!

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()
{}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top