I'm new to Qt. So I started to reimplement one of the get started examples: link.
However I get a SIGABRT signal when closing the windows. The reason for this is obvoisly due to some memory managment error.
Below you find the callstack and the relevant code. The line editWindow.setLayout(&layout);
causes the error. Is the layout class deleting widgets on destruction, therefor claiming ownership of them?
Whats the reaon for this behavior? And how to fix it?
Best regards.
information
callstacksource
QPushButton testButton("Test")开发者_如何学编程;
QVBoxLayout layout;
layout.addWidget(&testButton);
QWidget editWindow;
// the following line is the source of the error
editWindow.setLayout(&layout);
editWindow.show();
int val = app.exec();
Many different Qt functions will take ownership of the object being passed in which means it assumes control over all memory management and will free it upon delete. From the setLayout docs:
The QWidget will take ownership of layout.
After you have called setLayout
it has a parent and its parent deletes it in addition to it being deleted when the method's stack is cleaned up. Thus, it's being deleted twice which is causing the problems.
If everything else is correct, this change should fix it:
QVBoxLayout *layout = new QVBoxLayout();
//...
layout->addWidget(&testButton);
//...
editWindow.setLayout(layout);
Also, note that it's typical to create the main widget and then assign widgets that will be displayed on that widget as the parent. In other words, I'd expect something more like the following (though not strictly necessary). This also helps assure that if something does get reparented in the future you won't have problems:
QWidget editWindow;
QVBoxLayout *layout = new QVBoxLayout();
QPushButton *testButton = new QPushButton(&editWindow);
layout->addWidget(testButton);
editWindow.setLayout(layout);
editWindow.show();
int val = app.exec();
Most Qt objects which are reparented and to which ownership changes may happen will have a constructor that accepts a QWidget*
or QObject*
.
QWidget
expects a layout instance created via operator new and takes ownership of the instance, calling delete on it when the QWidget
is destroyed (see documentation). Hence what you need is something like this:
QVBoxLayout *layout = new QVBoxLayout();
/// ...
editWindow.setLayout(layout);
The same thing with ownership applies to your testButton.
The example code seems to be wrong (oddly enough). The destructor of a QWidget
calls delete
on its layout. In your case, the QVBoxLayout
instance has been created on the stack rather than the heap, so calling delete
on that pointer is invalid is aborts the application.
Same goes for all children of a QObject
. When a QObject
gets deleted, it calls delete
on all of its children, and if those children have been created on the stack, it will fail in the same way.
Now, to understand why Nokia posted such a bad example...
精彩评论