Some Question regarding Pointers and Destructors and safety...
-
Hi ,
I have some dump questions but it is important to clear my mind about it.
I want to open a window from my main window. when I click on ListView , It should open a new window .
The new window , opens using The class which displays a QML as a QdeclarativeView on the screen.Like This :
in Main Window : I open a window by clicking on ListView that this new Window is not a Dialog , it is a standalone window.
also , Clicking again on List View will cause to open an other new window.Questions :
-
What is the best method to make the child window a child of the main window ? ? setParent(Qt::window ) ??
-
I want the child window to close and destruct upon close , so I use setAttribute( Qt::WA_DeleteOnClose );
is it the best way ?
because I create my new window like this :
@ ChildWindow chldwin = new ChildWindow(.... arg...);
chldwin->setAttribute( Qt::WA_DeleteOnClose )
chldwin->show();-@
is it the best way to force the window to destroy upon close ?
or
@connect(quit, SIGNAL(clicked()), qApp, SLOT(quit()));-@
http://doc.trolltech.com/4.3/tutorial-t4.html- what is your best recommendation for a program to debug or monitor the program memory usage , or trace it.?
Thanks again
-
-
Hi,
I'm not an expert on QML, but to answer your question in general. In Qt, QWidget constructor as with all classes derived from QObject, the constructor of the class takes a "parent" argument.
So in ChildWindow constructor's initializer list, you would have..
@
ChildWindow::ChildWindow(...args..., parent)
: QWidget([...args...,] parent)
{
}
@Qt's memory management model is such that, for widgets and other classes derived from QObject, the parent child relationship is used for destruction. That is, when you destroy the parent the children's destructors get called too. So that should help you take care of memory management.
Now, one could use the Qt::WA_DeleteOnClose attribute.. but be careful something isn't deleted multiple times. Also keep in mind the MainWindow created in main(), even if on the stack, stays in scope till the program ends, so unless you allocate the MainWindow with "new" i.e. dynamic memory, don't set the Qt::WA_DeleteOnClose flag on it.
Now for debugging memory, on Linux, you could use valgrind, it works fine. You will need to compile your code with "-g" flag added to the gcc calls to enable instrumentation. There are a couple of shareware tools on windows, which you could use.. "Automated QA":http://www.automatedqa.com helped me once. There are also other system level profilers, which show system calls realtime and the time taken, which could be useful sometimes in debugging memory issues.
Hope that answers your question.
[EDIT: code formatting, please wrap in @-tags, Volker]
-
@jim_Kaiser:: thank you very much for your help and information.
I still need to clear out the meaning of what you said :
Now, one could use the Qt::WA_DeleteOnClose attribute.. but be careful something isn’t deleted multiple times.--? this way , I just leave the close to the window itself and in no condition I close the window externally .
Also , during destruction of the instant of the class , I delete all pointers defined locally which are not inherited by QObject . (As qt documents says )My Mainwindow is also not the main . it is called in main window but it is called after some other processes are completed.
I would like to know is there any cautions or recommendation of how to define a window as a child window of an other window !!!! , is the Qt::Window enough or any available document ? or ...
thanks in advance
-
If you do not call delete on the main window pointer yourself, the Qt::WA_DeleteOnClose is safe. If you set a parent on the widget, it is safe too. The widget is deleted by the system as a result of the flag or by the parent QObject once that one is deleted itself, but not by both. If a QObject is destroyed with delete, it signals its parent so (if it has one, of course). This all holds only for heap allocated QObjects (using new and assigning to a pointer). Do not do this for stack allocated QObjects, those may be deleted twice, eventually leading to earth deconstruction :-)
If you adhere to this, you will not create memory leaks.
-
Hi Satmosc,
What I meant by that was..
@
#include "mainwindow.h"
#include "ui_mainwindow.h"MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
}MainWindow::~MainWindow()
{
delete ui;
delete m_testWidget;
}void MainWindow::on_showButton_clicked()
{
m_testWidget = new QWidget();
m_testWidget->setAttribute(Qt::WA_DeleteOnClose);m_testWidget->show();
}
@In the above example, when we click the button a new window is shown, and as you can see, the window is created without a parent.
The code would give a segfault in trying to delete the m_testWidget twice. When we close the window manually, it's deleted, but we are also deleting it in our destructor, so, it causes a crash.
Of course, if you have a parent for a widget, then it is not a window by default, but can be made into one using the setWindowFlags(Qt::Window) as you have pointed out.
I'm not able to replicate a case where the Qt::WA_DeleteOnClose conflicts with Qt's automatic destruction of objects using the parent/child. But what I meant about the main() function is:
Don't do this:
@
#include <QtGui/QApplication>
#include "mainwindow.h"int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.setAttribute(Qt::WA_DeleteOnClose);
w.show();return a.exec();
}
@Because, in this case, we would get a seg fault at the end of execution, because the main window is deleted on close, and at the end of main() which returns after the close of the main window, the variable "w" allocated on the stack will be tried to be removed causing multiple deletions.
If I find some more relevant documentation, I will add it to this thread.
[EDIT: Thank you Volker for the additional info. As mentioned above, you can use both the automatic memory management using parent/child and Qt::WA_DeleteOnClose together safely. So this is okay..
@
#include "mainwindow.h"
#include "ui_mainwindow.h"MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
}MainWindow::~MainWindow()
{
delete ui;
}void MainWindow::on_showButton_clicked()
{
m_testWidget = new QWidget(this);
m_testWidget->setWindowFlags(Qt::Window);
m_testWidget->setAttribute(Qt::WA_DeleteOnClose);m_testWidget->show();
}
@
)