Qt widgets and pointers - c++

When working with Qt widgets (i.e; QLabel), why do we use pointers?
For example, why do we write:
QLabel *label = new QLabel("Hello");
And, not:
QLabel label = new QLabel("Hello");?
Thanks.

new returns a pointer. If you create an object via dynamic memory allocation - you obviously have to use a pointer.
QLabel label = new QLabel("Hello"); is incorrect code and will not compile.
Why do you use dynamic allocations for widgets? Because they have to be alive between function calls, as with any event driven GUI system. Allocations on stack (local objects) will be deallocated at the end of the scope, which wouldn't work well with widgets.

Because if you will create them on a stack they will be deleted after end of scope.
If you will write something like this:
void foo()
{
QWidget windget;
}
widget will be removed after foo() is terminated. If using new it will live until it will be deleted manually (usually by parent Widget).
I don't think QLabel label = new QLabel("Hello"); will even compile. Possibly you ment
QLabel label("Hello");

I think this is not a Qt problem, this should be a question of C++ programming.
You maybe use Java before, as java don't have pointer concept.
My suggestion, find a C++ book and learn the basic concept and usage about what's the meaning for a C++ pointer before you try to use C++ and Qt.

Just to be complete, there is no reason why you shouldn't allocate some widgets on the stack. This is especially handy for objects with a limited lifespan, like context menu's and modal dialogs where you have to wait on the result. On these widgets you normally call exec(), which blocks until the user closes it.

If you want to define a var without a pointer, it looks like QLabel label;
The label we got:
is located on the stack.
can not support polymorphism.
In c++ a var will only be object-oriented if you use it via a pointer or a reference. Qt is a object-oriented class library, so this is why QLabel is defined with a pointer.

Related

why qt application always new widgets instead of on stack?

there. I've seen this example from qt: https://doc.qt.io/qt-5/qtwidgets-widgets-calculator-example.html, and wonder why qt always create widgets with new instead of allocating on stack
Button *Calculator::createButton(const QString &text, const char *member)
{
Button *button = new Button(text);
connect(button, SIGNAL(clicked()), this, member);
return button;
}
create widget on stack is faster, and in this question: QT-specific difference of stack vs. heap attributes?
Mike's answer says that create on stack is perfectly fine, but why official documents use new mostly?
This is simple: because you want the widget to live even after this function scope is finished and QObjects are not copyable. The following code does not work because you cannot copy the object.
Button Calculator::createButton(const QString &text)
{
Button button(text); // allocated on stack, it is OK so far...
return button; // nope, you cannot copy that! it does not compile.
}
The following code does not work either because you would be passing a deleted object.
Button *Calculator::createButton(const QString &text)
{
Button button(text); // allocated on stack, it is OK so far...
return &button; // ... returning pointer, still OK...
// Oh no! End of scope here, the object gets murdered now.
// whoever holds the pointer to it, holds a dead, invalid object.
}
The object gets deleted at the end of scope and you would be passing a pointer to freed, hence invalid memory.
The example you referred to
class Widget2 : public QWidget
{
Q_OBJECT
public:
Widget2(QWidget* parent = nullptr);
private:
QPushButton button;
};
does not necessarily mean that the button is created on the stack. It depends on how the instance of Widget2 is created. If it is on the stack, then also button is on the stack. If it is newed on the heap, then also button is on the heap. The difference from the "normal" case where button is declared and kept as a pointer is that in the example above they are allocated together in one allocation. Yes, it is negligibly faster but it is just a premature optimization. Allocation of widgets will never ever be your bottleneck, believe me. Btw. most objects in Qt are implemented using PIMPL idiom to preserve binary compatibility, so they internally allocate their private objects on the heap anyway.
Yes, you can keep your button as a NON-pointer member. This is legal. But it is not wise. There is an issue with this approach: you must #include all the subwidgets in the header and you cannot forward-declare them. Which definitely makes you compile time longer. But that is not the main problem, you can wait a little. The bigger problem is that you are introducing building dependencies which makes your code less composable. Imagine you have your custom widgets split into multiple libraries - then everything what you #include in your headers visible to other modules also requires to be visible to these modules. This soon becomes unmanageable mess because you will not be able to hide/encapsulate implementation details. And the fact that your widget uses some button certainly is an implementation detail. Just keep as little details in your header as possible. Keeping a pointer (can be forward-declared) is definitely less of a burden than keeping a non-pointer member (must be #included!). Moreover if you keep a pointer, then you can use substitution principle and this pointer can actually point to any subclass instance. In little toy applications or school homeworks this does not matter but when you are designing a really large application wit lots of modules and submodules organized as libraries or when you are writing libraries which are to be used by others, then these things REALLY DO matter. This makes the difference between well maintainable and totally unmaintainable code.
In my practice I have encountered only two usecases where widgets are actually allocated on the stack. First is when they are created in main() where you can write:
int main() {
QApplication app;
MainWindow w; // it is really on the stack
w.show();
return app.exec();
// here is the main window automatically destroyed
}
Another case is when you open a display a modal dialog with a blocking event loop using exec().
void showSomeMessage() {
QMessageBox box; // yes, we should set a parent here, for sake of simplicity I omitted it
// etc. set text and button here
box.exec(); // blocking here, we are waiting for user interaction
// end of scope - we are done here, we do not need the message box any more
// so it is perfectly fine it gets automatically deleted here
}
These cases are perfectly fine. Actually, as you can see blocking exec() in both these cases, they are very similar.
Conclusion: it is better to declare member QObjects or QWidgets via pointers and always forward-declare them in your headers instead of #includeing their headers. This way you can design more composable, maintainable and future-proof code. You will not see any significant difference in small toy projects, but you will benefit from this good practice when your codebase grows larger. Even better habit is to keep them via QPointer (which a special Qt weak pointer), which has twofold benefit: 1) it is automatically initialized to nullptr and 2) when the objects gets destroyed, the pointer is automatically set to nullptr so you can easily check if it is alive. Plus QPointer provides implicit conversions to raw pointer so it does not affect the way you write your code. It is a very handy class.

Correct way to manage memory in Qt when exposing QObject class into qml?

I'm using C++ to code the most of my program logic. I like exposing C++ classes into QML so that the QML can use JS to do many complex jobs. However, here comes a problem:
If the C++ function return a QObject*
Q_INVOKABLE QObject* parseJson(const QString& someArguments)
{
return new SomeClassExtendsQObject(someArguments);
}
which is then assigned to a JS variable and used
var result = exposingCppObj.parseJson("I'm Arguments");
result.someMemberFunction(...);
.....
if I use
delete result
in QML JS, is the instance really freed like it would be in C++?
An object created in C++ but accessible from QML can have two ownership states:
QQmlEngine::CppOwnership and QQmlEngine::JavaScriptOwnership. You rarely need to set this state as Qt can usually work out the appropriate one. In your example since the object is created from a QML call, it is automatically assigned QQmlEngine::JavaScriptOwnership.
When an object is assigned QQmlEngine::JavaScriptOwnership the JS garbage collector will destroy it when necessary; there's rarely need to explicitly destroy it.
One last thing, if you do want to destroy an object in QML, use destroy(). The JS delete keyword is for removing both the value of a property and a property itself from objects.

Smart pointers memory managers in Qt

I'm trying to develop a Qt Application for mobile phones, so I decided not to use any standard library(as I fear some platform may not yet be supported). So, I had to reimplement the smart pointer wrapper(using the standard draft, of course) without any standard headers. In Qt, there are some Widgets, such as QMenu and QToolBar which when needed to be created -- It is created as such
QMenu *mainMenu = new QMenu;
QToolBar *toolBar = new QToolBar;
//To add a new menu bar or ToolBar, we do
mainMenu = menuBar()->addMenu("&File");
//add all the elements to the first menuBar
mainMenu->addAction(QAction { });
mainMenu = menuBar()->addMenu("&Edit"); //for second Menu
//same goes for QToolBar
The only way I implemented the unique_ptr "observers" is to use the get(), operator* and operator-> member functions to access the underlying members. What's obvious is that MenuBar()->addNew() returns a new pointer to another mainMenu.
Now to my question(s), what happens to the old pointer(s) that ? What keeps track of them? How can smart pointers be used in replacement of these naked pointers or do I have to stick with the "good old ways" of using strictly the naked pointers?
NOTE: All files can be found here
as I fear some platform may not yet be supported
That feels like incorrect guess. Every mobile platforms support it these days and Qt does depend on the standard library explicitly these days.
Even if it did not, you do not need to implement your own smart pointer as Qt has been providing these for ages:
QPointer
QSharedPointer
QWeakPointer
QScopedPointer
Here you can find a thorough explanation about them by Thiago.
So, the bottom line is just this: do not implement them yourself because you are reinventing the wheel and it is likely that you will need to fix bugs that had been fixed awhile ago. The ready-made solution will probably also scale better than your implementation from scratch and maintained by others without you needing to spend time with it.
If you only wish to deal with the automated construction and decontruction of QObject subclasses, you could also use the Qt parent/child hierarchy. Here you can read more about that one:
Object Trees & Ownership
That means, you could write something like this for QWidgets (because they are also QObjets):
QMenu *mainMenu = new QMenu(this);
QToolBar *toolBar = new QToolBar(this);
where this is basically the parent, like mainwindow, or it could be the Qt application object if you have one top-level widget, for instance, and so on.
The simplest method for managing memory with Qt is by leveraging their "object tree" structure. You can read more about it in this question: Memory management in Qt?. Basically, Qt keeps a tree of parent-child relationships between QObjects and when the parent is deleted, it deletes all child objects. So feel free to use good, old new QObject(parent) and let Qt handle the cleanup for you.

C++ - Why do I create these widgets on the heap?

When creating a GUI with C++ and Qt you can create a label for example like this :
QLabel* label = new QLabel("Hey you!", centralWidgetParent);
This creates the object on the heap and will stay there until I either delete it manually or the parent gets destroyed. My question now is why do I need a pointer for that? Why not create it on the stack?
//Create a member variable of Class MainWindow
QLabel label;
//Set parent to show it and give a text so the user can see it
QWidget* centralWidget = new QWidget(this); //Needed to add widgets to the window
this->setCentralWidget( centralWidget );
label.setParent(centralWidget);
label.setText( "Haha" );
This works fine, I can see the label and it did not vanish.
We use pointers in C++ to let something live longer so we can use an object in various scopes. But when I create a member variable, won't it stay until the object gets destroyed?
Edit:
Maybe I didn't clarify it enough. This is the MainWindow class:
class MainWindow : public QMainWindow
{
Q_OBJECT
QLabel label; //First introduced here...
public:
MainWindow(QWidget *parent = 0);
~MainWindow();
};
//Constructor
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
{
QWidget* centralWidget = new QWidget(this);
this->setCentralWidget( centralWidget );
label.setParent(centralWidget);
label.setText( "Haha" );
}
If your label gets out of the scope, the destructor (QLabel::~QLabel) will be called. From the docs:
Destroys the object, deleting all its child objects.
It is not necessary to create object on the heap - you could put the object on the stack, but then you need to be responsible about lifetime of the object (the one of the most problematic issues about allocating data on the heap is the question of "who and when should delete these objects?", and in Qt it is handled by the hierarchy - whenever you delete your widget, all the child widgets will be deleted).
Why your program works - I don't know - it may just not work (label is destroyed at the end of the scope). Another issue is - how will you change the text of the label (from some slot, for example) if you don't have a reference to it?
Edit I just saw that your label is a member of the MainWindow. It is perfectly fine to have a complete objects, and not the pointer to the objects as the member of your class, as it will not be destroyed before MainWindow is. Please note that if you create instance of your MainWindow like this:
MainWindow *w = new MainWindow();
label will be created on the heap.
Because that is how Qt was designed. I realize that's not a very satisfying answer, but Qt was simply designed as "widgets are created on the heap, and parents are responsible for deleting their children".
Realize that the origins of Qt are old, older than what we consider "modern C++".
Another thing to keep in mind is that Qt uses the so called pimpl paradigm where object data is implicitly shared and managed behind the class you actually instantiate. See here: http://qt-project.org/wiki/Dpointer
The bottom line is that if you are allocating on the stack in order to avoid using the heap, Qt is just pulling a fast one on you and using the heap anyway.
Allocating a widget as a local variable typically is not a good idea, since usually it will go out of scope before being useful in any way; since QObject supports the composition pattern via its "parent-child" relationships (that are well integrated with C++ destructors), usually the simplest thing is just to exploit such a feature.
On the other hand, you can make it a member of your MainWindow class, or in general allocate it in any way such that it has a lifetime less than the lifetime of its parent. In facts, when such QLabel is destroyed, it automatically deregisters from its parent, avoiding double deallocation. But often is more comfortable just to allocate the widgets on the heap, registering them as children of the current window, since usually you don't actually need to access many widgets after you created them (e.g. labels), so it's not necessary to clutter your class with useless data members. You just do new QLabel(this, ...) into your window constructor and that's it.
What you should not do, instead, is to allocate your widgets without new if their lifetime gets longer than the lifetime of their parent (e.g. putting them in a global or static variable) - doing this will cause the parent to try to delete them on its destruction, which will cause a crash at best, silent memory corruption at worst. This can be fixed (by manually deregistering the widgets in your class destructor), but I can't imagine any scenario where such a thing would be useful.
Main reason - possibility of dynamic creating / removing widgets. QObject (and QWidget) desing as classes that could not have copy constructor, so you couldn't pass is in arguments (by value/reference). So using pointers in all cases makes code more simple and clear.

Confusion about usage of 'new' for UI Widgets in QMainWindow constructor

My coding practice using Qt can best be described as follows:
If the Widget is going to be actively used (e.g. A QLineEdit which provides text), I declare it in the header file and then initialise it in MainWindow.cpp.
e.g. TextEditor.h:
class TextEditor
{
//other code
private:
QLineEdit edtFind;
};
2.. If a widget is not going to be used (e.g. QLabel, QWidget), or it's part of a signal slot system (e.g. QPushButton), I declare and inialise it inside constructor using new.
-e.g.
TextEditor::TextEditor()
{
//other code
QWidget* searchPanel = new QWidget();
edtFind = new QLineEdit("Enter Search Term");
QPushButton* findButton = new QPushButton("Find");
connect(findButton,SIGNAL(pressed()),this,SLOT(find()));
ui->statusbar->addPermanentWidget(searchPanel);
}
My question is, am I using an efficient approach in point 2? Would it be better to not allocate memory from the heap?
Thanks.
Your approach is not efficient. You should use heap allocated objects when you actually need them:
objects that have a longer lifetime
using a forward declaration in order to avoid including a header file
holding a reference to an object created elsewhere
Your approach is more complicated without any visible benefit. Heap is known to be slow, and allocating a large number of small objects is known to fragment it (this might not make a difference in your app but it's still a bad practice).
While good advise for C++ in general, answer 1 is actually wrong for a big part in Qt: QObject (and with it all widgets, since QWidget derives from QObject). Rule there is to always allocate QObjects on the heap if they have a parent, because QObject features a parent-based garbage collection (when the topmost QObject-parent gets deleted, it will ask all its children to delete themselves recursively). The application may try to delete an object on the stack, which leads to a crash.
Note that some operations in Qt implicitly add or change the parent of a QObject as a side-effect (reparenting), such as adding a widget to a layout. However, this is usually documented in the API documentation. Since reparenting is very common with QWidgets, you should never put them on the stack. Other QObject-derived classes are safer, consult the API documentation in case of doubt.