What is the right place to initialize QWidgets?

What is the best way (place) to initialize QWidgets when you add them programmatically?

I can figure out how to do this:

1) Create instances in the definition file and then initialize them in the list of initializers. This seems to be the right way, but it gets sloppy the more QWidgets you need to add to the window.

class SomeWindow : QDialog{ ... private: QLabel label1; QLabel label2; ... } SomeWindow::SomeWindow(...) : QDialog(...), label('label1 text'), label('label2 text') { ... layout.addWidget(&label1); layout.addWidget(&label2); ... } 

2) Coming from C #, I like it so much, but it seems to cause a memory leak ...

 SomeWindow::SomeWindow(...) : QDialog(...) { QLabel* label1 = new QLabel('label1 text'); QLabel* label2 = new QLabel('label2 text'); ... layout.addWidget(label1); layout.addWidget(label2); ... } 

Is there a better way to do this that I am missing?

We apologize for the question of the newcomers.

+4
source share
3 answers

Qt uses its own system to remove the parent child classes of QObject. When you delete an object, all children are also deleted.

With the first code you have 2 destructions (in the SomeWindow destructor and with the QObject system), then this code is illegal (only with Qt; with standard C ++ code this is good)

In the second code, the tags are deleted by the QObject system, you do not have a memory leak. No need to save a pointer to objects.

@Jairo

Configuring a parent in a constructor is not the only way to add children to objects. In particular, here is QLayout :: addWidget reparent objets (if the layout is correctly a child)

@msgmaxim

Be careful, the layout should not be a local variable in the constructor

+3
source

There are two ways to initialize a new widget.

In the first case, you have labels as objects. Therefore, when SomeWindow is destroyed, they will also be automatically destroyed. Remember that if you have a pointer to widgets instead of objects, you will need (and can) remove the labels in the dialog destructor.

 SomeWindow::~SomeWindow() { delete label1; label2.deleteLater(); // A safer way to delete a widget. Thread-safe. } 

And in the second case, a memory leak will occur, because you have no way to remove the widget in the destructor. But if you define a parent for labels, they will be deleted when the parent is also deleted. Take a look at the QWidget documentation .

If parent is 0, the new widget becomes a window. If the parent is another widget, this widget becomes the child window inside the parent. The new widget will be removed when its parent is removed.

Also, anytime the constructor of an object requests a parent QWidget or QObject, you might think that Qt will delete the object when the parent is deleted.

I am also a beginner, but hope this helps you.

+1
source

The advantage of having widget pointers in headings rather than on real objects is that you do not need to include all the headings for widgets, but simply forward their declarations. This increases compilation time, which can be noticeable in large projects.

In addition, if you have a dialog and you just add many widgets, such as QLabel, you can make the code more accurate by doing this in the implementation: -

 layout.addWidget(new QLabel('label1 text')); layout.addWidget(new QLabel('label2 text')); layout.addWidget(new QLabel('label3 text')); layout.addWidget(new QLabel('label4 text')); 

As already mentioned, the parent system of Qt will take care of clearing the widgets when their parent is removed.

Of course, if you want to change a property, for example text, you will need to find a widget from layouts, but often QLabel, as its name implies, simply imposes an element and its properties do not change.

+1
source

All Articles