I have Created a simple QT application for my university assignment. What i have done is pop up a new QManinWindow from a Above QMainWindow. When i click a button from the main ui it will pop up a new QMainWindow object (Note Pad)
Note pad is also a QMainWindow object
My Problem is when I'm creating the object it takes some memory from the ram but when I'm closing it (pop up window) memory is not releasing. When each time I'm pressing a button memory is allocated but application does not relese the memory when im closing it. Please check the main screen of the app.
i just want to know how to release that memory. I have tried so many things but nothing worked well.
I have set the closeEvent public on NotePad class and I listen the close event from main object when its get triggered i have deleted the poped up object. But it cause ad unexpected stop.
void MainWindow::on_notePadBtn_clicked()
{
NotePad *notePad = new NotePad(this);
notePad->raise();
notePad->activateWindow();
notePad->show();
}
NotePad::NotePad(QWidget *parent) :QMainWindow(parent),ui(new Ui::NotePad) {
ui->setupUi(this);
this->setWindowTitle("Note Pad");
}
You don't really need to override closeEvent, Qt has Qt::WA_DeleteOnClose attribute, that does exactly what you want, you can use it like this:
//...
NotePad *notePad = new NotePad(this);
notePad->setAttribute(Qt::WA_DeleteOnClose);
notePad->raise();
notePad->activateWindow();
notePad->show();
//...
I'm not familiar with Qt.
But to my understanding if you use the operator new
you must use delete (in a scope where you have access to the pointer created with new).
Object *foo = new Object();
// Do stuff with foo...
delete foo;
// DO NOT use foo from now on.
Hope that helps a bit, maybe. Like I said I'm not familiar with Qt
so if you have doubts about how some features are implemented you should look at the their docs.
(cf: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3797.pdf §3.7.4p63)
Related
Writing a school project in c++ and qt. It is supposed to be a block editor (like draw.io). I generate blocks as a buttons and setting them to a grid. Each button is supposed to have own menu to be able to get edited, deleted, etc. (image example:
We are encountering a problem, that our action won't connect to a slot. Function akceAkce is supposed only to print 1 onto output (via qInfo). But when I click on the menu button, it does nothing. Any suggestions appreciated. Thanks!
void BlockItem::createButton() {
this->button = new QPushButton("+");
this->buttonMenu = new QMenu(this->button);
this->connectBlocks = new QAction(tr("Connect"), this->buttonMenu);
connect(this->connectBlocks, &QAction::triggered, this, &BlockItem::akceAkce);
this->buttonMenu->addAction(this->connectBlocks);
this->button->setMenu(this->buttonMenu);
}
void BlockItem::akceAkce() {
qInfo("1");
}
I would suggest a possible explanation: you put the BlockItem instance on the stack, and it's going out of scope somewhere in your code, and destroyed consequently, while the push button, menu and action all survive it, since they're instantiated with new, thus they live on the heap.
Something like this:
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
BlockItem blockitem;
blockitem.createButton();
ui->gridLayout->addWidget(blockitem.getButton());
}
In the sample code above, blockitem goes out of scope at the end of the method, so it is destroyed and the connection loses its receiver side (i.e. breaks).
The same would happen if you instantiate a BlockItem object on the heap, using new, but accidentally delete it somewhere. Again, the signal sender (the QAction object) survives the receiver and the connection is broken.
I'm writing an application in C++ using the Qt library. There is a central window (the parent) and all the children are launched when needed. Since a number of these windows can be open multiple times, but display different data, I'm declaring the objects with new. Here is an example of what I've got:
Home_Window.hpp
View_Window *SomeWindow;
Home_Window.cpp
void Home_Window::on_WindowButton_clicked()
{
SomeWindow = new View_Window();
SomeWindow->show();
}
What I want to do, is delete the object, when the window is closed to reduce the memory footprint of the application. I've already been able to delete all of the objects contained in the child window to reduce memory usage, but the core object still lingers, and if, through a single day a user opens and closes 1000's of windows, and each object holds onto 40-50KB of memory, the footprint of the application goes from a couple of MBs of memory to 100's of MBs of Memory.
I've not been able to find a guide online that would allow me to achieve this. I was considering a slot and signal pair, as I know that when a window is closed, it sends the QObject::destroyed() signal. Only issue, is I've not tried to setup a signal and slot pair like this.
Any suggestions are appreciated.
to delete the window when it is closed, you can set the WA_DeleteOnClose attribute on it. Your on_WindowButton_clicked() should look something like:
void Home_Window::on_WindowButton_clicked()
{
View_Window* w= new View_Window();
w->setAttribute(WA_DeleteOnClose);
w->show();
}
This way, you don't have to worry about destroying w yourself, it will get deleted automatically when it is closed.
You need to do two things:
The window's lifetime must be managed even if the window isn't closed.
You can give it a parent that you know will end its life at some point. Or you can use a QScopedPointer or std::unique_ptr.
The window must delete itself when it's closed.
void Home_Window::on_WindowButton_clicked()
{
// parent window flags
// vvvv vvvvvvvvvv
auto window = new View_Window(this, Qt::Dialog); /* 1. */
window->setAttribute(Qt::WA_DeleteOnClose); /* 2. */
window->show();
}
At the very least, you should set the Qt::Window flag. The Qt::Dialog includes the Qt::Window flag, and also declares the window to be a dialog box - that fact has platform-specific interpretation; read more about window flags here.
If your View_Window's API is broken, and it doesn't take the window flags as the 2nd argument to the constructor, you need to set them separately:
window->setWindowFlags(Qt::Dialog);
Every widget should be taking Qt::WindowFlags as the optional, 2nd argument to the constructor, with a default value reflecting the usual use of the window. That's the expectation set by all of Qt's widgets.
You can try to delete the pointer to ViewWindow by using: delete SomeWindow;
I'm developing a simple prototype with qt creator.
I have used designer in order to design my windows.
Say us that main window has a menu with an option called "Suspend". When this option is selected, it is called the method MainWindow::on_actionSuspend_triggered() whose simplified implementation could be resumed as follows:
void MainWindow::on_actionSuspend_triggered()
{
SuspendDialog suspend_dialog(this);
suspend_dialog.setModal(true);
auto status = suspend_dialog.exec();
return;
}
The SuspendDialog was specified with designer, it is derived from QDialog class and it is very simple (three push buttons a combo box and a spin box. This class does not allocate memory.
Now, when I run valgrind inside qtcreator for checking memory usage I get two issues of type Mismatched free() / delete / delete []. Some bizarrus is that the two issues refers the same line, which is at the end of destructor of SuspendDialog whose implementation is:
SuspendDialog::~SuspendDialog()
{
delete ui;
}
And that was automatically generated by qt designer.
My question is: is this a false positive of valgrind or am I doing some wrong?
Thanks in advance
By doing the below you are asking for trouble:
SuspendDialog suspend_dialog(this); // wrong! do not pass 'this' here
Passing pointer to 'this' in Qt implies that you pass the parent responsible for release of that widget. Or, the release will happen twice: first when the object on stack getting destroyed and next when the parent object getting destroyed.
If you execute the dialog with exec() you can still allocate the dialog widget on stack but do not pass this to it:
SuspendDialog suspend_dialog;
//
suspend_dialog.exec(); // exec() only
Or you can allocate the dialog widget in the heap and then you can pass this to it:
SuspendDialog* pSuspendDialog = new SuspendDialog(this);
//
pSuspendDialog->exec(); // or maybe show() depending on task
I use this code:
MyDialog *md = new MyDialog();
md -> show();
to open a dialog window in Qt. Will md be deleted automatically when the dialog window is closed or do I need to run delete md when the window is finished?
In your little piece of code you need to delete it, because it doesn't have a parent, if you set a parent, the parent will delete it's children and you only need to delete the "main-window" (the window that doesn't have a parent).
Also for QWidget derived classes you can use the: Qt::WA_DeleteOnClose flag and then the memory will be deallocated when the widget closes, see the documentation here
Then code will become:
MyDialog *md = new MyDialog();
md->setAttribute(Qt::WA_DeleteOnClose);
md->show();
Yes. Unless you pass this while this is a QWidget or any other QWidget:
MyDialog *md = new MyDialog(this);
md->show();
you need to:
delete md;
at some point in order to release its memory. Also you need to make sure in this case that the object tree is well linked. What you can also do is call setAttribute(Qt::WA_DeleteOnClose); on md so that when you close the dialog, its memory will also be released as Zlatomir said. However if you need md to live after it was closed setAttribute(Qt::WA_DeleteOnClose); is not an option. This is also dangerous and could lead to access violation/segmentation fault if you are not careful.
My friend and I have each created parts of a GUI using Qt 4. They both work independently and I am trying to integrate his form with the my main window. As of now this is the code I am using to try and load his form:
//connect buttons and such
connect(exitbtn, SIGNAL(triggered()),this,SLOT(terminated()));
connect(add, SIGNAL(triggered()),this,SLOT(add_rec()));
void MainWindowImpl::add_rec()
{
//form quits as soon as it loads...?
DialogImpl dia;//name of his form
dia.show();
}
I have included his header file. The program compiles but when I hit the trigger his form loads up for maybe half a second and then closes. Does anyone know what I am doing wrong?
You have almost get it right. This is because the RAII of C++. If you allocate the Dialog on stack, it would be destructed as soon as the function return.
Assuming MainWindowImpl inherits publically from QWidget, you're looking for this:
void MainWindowImpl::add_rec()
{
// passing "this" to the constructor makes sure dialog will be cleaned up.
// Note that DialogImpl will need a constructor that takes a
// QObject* parent parameter.
DialogImpl* dialog = new DialogImpl(this);
dialog->show();
}
Look at the Qt documentation for examples of how the constructors should look.
Apparently QT4 only allows one instance of an object at a time, however pointers are another matter. Change both the main.cpp and what ever your main window to look something like this:
DialogImpl *dia=new DialogImpl;
dia->show();