QStyle ownership - c++

When using styles in Qt applications, I ran across an interesting problem of QStyle ownership. QStyle inherits from QObject, which typically accepts QObject* parent as a constructor parameter to manage the lifetime of its child. But QStyle's constructor does not have this constructor parameter. First question - why is that?
Moreover when setting style to the whole application with QApplication::setStyle(QStyle * style), the documentation says that the application object takes the ownership of the style. So writing (as in docs) app->setStyle(new MyWonderStyle()); should be safe and the application should delete the style when not used any more. I hope it does that.
But for QWidget::setStyle(QStyle* style) the documentation says that the ownership is not transferred. So in my view writing widget->setStyle(new MyWonderStyle()); results in memory leak if the style of the widget is set more than once or when the widget is deleted.
So my question - what is the best practice for managing custom styles especially the ownership in Qt? Is there some standard way or is it completely up to the developer to handle it?

I would say that QApplication::setStyle(QStyle*) takes ownership of QStyle because there is an overloaded function QApplication::setStyle(QString). This function creates a QStyle object internally and takes ownership of it because there is no other option in that case. Taking ownership in one function and not taking it in another one could result in confusion.
On the other hand, QWidget does not take ownership of QStyle because you may want to assign the same style to multiple QWidgets.
Lack of QStyle(QObject*) constructor is probably just an oversight. You can safely use setParent(QObject*) instead. In fact, QApplication::setStyle(QStyle*) uses setParent to take ownership of QStyle.

Related

Why does Qt use raw pointers?

I have gone back to Qt/C++ programming recently after coding a lot with plain C++.
When browsing StackOverflow, I often catch up on posts like "Why use pointers?" where in most cases the gist of the answers is "if you can avoid it, don't use them".
When coding in C++, I now mostly try using stack variables which are passed by (const) reference or, if necessary, std::shared_ptr resp. std::unique_ptr where needed.
Getting back to Qt, I found all those "principles" to be completely ignored apparently.
I know that Qt uses its own memory management to take care of raw pointers, but here's my question:
Why don't they at least use shared_ptr or unique_ptr, particularly since they even have an own implementation QSharedPointer?
Qt since versions 4.x was designed around imitating Java's framework ideology in C++ environment, using C++98 means. Instead of RAII approach of interaction it establishes "owner" - "slave" relation, in framework's term that's "parent" and "child". More of, Qt uses concept of PIMLP -private implementation. QObjects you operate with aren't real representation of what is happening, they are interfaces to completely hidden inner implementation.
By design, you have to create a QObject-derived object of child element and pass ownership to the owning object . E.g. where a window is an owner, a Button inside window will be the "slave" object. When owner is deleted, all objects that were slaved to it will be deleted too. All QObjects are thread-aware, but QWidgets can work only in main thread. This creates a non-owning pointer:
QWidget *myWidget = new QWidget(mainWindow);
mainWindow will be owning QWidget instance in this case. But this one is owning?
QWidget *myWidget = new QWidget;
It isn't. It's still owned by QApplication.
QObjectDerivedClass *myWidget = new QObjectDerivedClass;
It's an owning pointer, but this object was registered to exist in our framework. Even more, any instance can be found if it was assigned a name, storing QObjects to reach them is just an caching optimization.
All QObjects and QWidgets are registered globally and are iterable. With destruction of QApplicationCore instance all QWidgets of top level will be freed. There is undocumented exception out of that rule at least in Qt 4.x versions that QDesktopWidget objects are ignored even if they are top-level widgets. So, if a QMainWindow was forced to appear on certain screen by becoming its child, it wouldn't be destroyed.
Now comes into play signal-slot connections. In GUI certain handlers begin their work as soon as parent-child connection is established, but you can add new handlers. if a child object is deleted between beginning and end of message pump created by QEventLoop, your program may encounter an UB. To avoid it, you have to call deleteLater() which marks object for deletion at designed moment. Processing signals between threads is done separately. Practically, the main event loop is the only part of GUI that is synced with other threads.
With such complex structure and already existing requirement of working in one thread, imposed by some of supported embedded platforms, need to use smart pointers within GUi framework was negligible compared to possible impact on performance.
Before C++11 Qt had QPointer (and still got it), which is aware if QObject still exists or not using mechanics similar to owner-child interaction.
This design predates C++11 and QSharedPointer appeared only after that to fill a niche requested by users to maintain user-defined data model. It doesn't support some features, e..g you can't have an atomic version of it like ISO version does, it's only partially atomic until very last releases of 5.x. QAtomicPointer isn't either QPointer or QSharedPointer, it acts like a std::atomic<QObject*>. QSharedPointer though allows use of custom non-standalone deleter, including a call of deleteLater():
QSharedPointer<MyDataQObject> objPtr { new MyDataQObject, &QObject::deleteLater };
Assuming that MyDataQObject is derived from QObject, objPtr will call method deleteLater() in context of managed object instead of using delete on managed pointer when destroyed or reset.

How to copy QWidget through pointers in C++

My goal is this:
QWidget *p = new QSpinBox(0); // This can be any type of QWidget.
QWidget* Get()
{
/*
Here using p, I need to return a NEW object of QSpinBox or whatever
the qwidget assigned to p. I can't return p because it will be deleted
after this method, so the next time p would be empty.
*/
}
It's used for the QStyledItemDelegates::createEditor() method. The widget returned from get will be deleted when the delegate editing is done.
All QObjects are not copyable by definition. See its header file.
Same applies to QSpinBox.
Reason is simple cloning of signal slots memory management could lead to unpredictable results, so it was disabled by design.
The copy of a pointer to an object doesn't copy the object in any way. In Qt the copy of QObject derived classes is indeed disabled, but you can copy pointers to the object around as much as you want, or until you run out of memory...
Due to the design of Qt QObject derived classes have unique identities. This means they must not be copied, at least in the rational sense of the term. You could however write your own "clone function" that creates a new instance with unique identity and applies all of the properties of the object p points to to the new instance. E.g. you can fake it to a certain amount but don't expect to get a copy functionally identical to the original. If you want to get a fully functionally identical clone, you will have to implement your own signal and slot mechanism instead of using the one provided by Qt.
You CAN indeed return p - but it will point to nothing if you call delete on it. Keep in mind returning p will simply copy the pointer, it has nothing to do with the actual object pointed to. p is just a number.
Edit:
At a deeper look at the "reflection facilities" provided by Qt, it looks like you could get signals and slots to clone, but it is not pretty - you have to query every QMetaMethod of the QMetaObject associated with the particular instance to find the signals, but then you hit a brick wall - you will have to resort to using private APIs (a big no-no in 99.9999% of the cases) in order to query for the signal receivers in order to connect the new copy to them as well. Definitely not something that was intended to be done. In short, you need to rethink your strategy at getting the problem solved.
Overall, as I mentioned in the comments, your problem seems to be bad design, and even though it is technically possible to make the bad design work, you'd be much better if you simply improve your design and avoid arduous if not even masochistic endeavors.
s is a pointer, which can be copied and modified at will; modifications to the copy will never affect the original. If what you meant was in fact the object which s referred to, then it's sufficient to provide it with a copy constructor and a copy assignment operator; depending on the content of the class, the compiler may have generated these for you.
Depending on the content, it's also possible that the compiler generated versions don't do what you need.
Given the name of the class, I suspect that it is part of Qt. In that case, check the documentation. It may support cloning, in which case, what you probably want is a clone.

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.

Memory management for collections of widgets in Qt

Sorry for the dumb question, but I'm working with Qt and C++ for the first time, and working through the tutorial and some samples.
One thing that was mentioned was that Qt stuff doesn't need to be explicitly deleted. So, main question, does this also apply to collections of Qt stuff? Like say I want a dynamic number of MyWidgets, so I keep a vector or whatever of them. Are they still taken care of for me?
As a side question, what is going on to make it so I don't have to worry about destructors?
The Qt memory management model is based upon a parent-child relationship. Qt classes take an optional parent as a parameter of their constructor. The new instance registers with this parent such that it is deleted when the parent is deleted. If you are using a Qt collection (e.g. QList), I believe you can set the list as the parent of its entries. If you're using an std::vector or other collection type, you will not get "automatic" memory management.
The Qt model makes a lot of sense in a UI hierarchy where it matches one-to-one with the UI hierarchy. In other cases, it doesn't always map as cleanly and you need to evaluate whether using the Qt system makes sense for the particular situation. The normal C++ tools still work: you can use std::tr1::shared_ptr or any of the other smart pointer classes to help you manage object lifetime. Qt also includes QPointer, a guarded pointer, and the QSharedPointer/QWeakPointer pair that implement a reference-couting smart pointer and weak-reference pair.
Qt has an interesting object model for sure. When I first started it made me uneasy that there were so many new Foo calls and no deletes.
http://qt.nokia.com/doc/4.6/object.html Is a good place to start reading up on the object model.
Things of interest:
QObject subclasses have their assignment and copy-ctor methods disabled. The chain of object child-parents is maintained internally by QObject.
Generally when instantiating a QObject subclass (if you don't plan on managing its pointer yourself) you will provide another QObject pointer as the parent. This 'parent' then takes over the management of the child you just made. You can call setParent() on a QObject to change who "owns" it. There are very few methods in Qt that will change the parent of an object, and they all explicitly state that they do in the docs.
So to answer your specific question: it depends on how you made all of your MyWidget instances.
If you made each one with a parent, then no you don't have to delete them. The parent will delete them when it gets deleted.
If you're keeping a QList<MyWidget*> collection of them, and you didn't give them a parent, then you should delete them yourself.

References vs information hiding C++

I need suggestions on how to solve the type of problems described below. I'm fairly new at C++ and OO-design.
I've learnt:
Pointers shall be avoided when ever they can be replaced by references.
Objects shall have no knowledge of objects that they don't need to know about.
But when creating objects having references to other objects we must pass these references as input arguments to the constructor. Thus we need to know about objects we should not not know anything about.
But look at the following example:
Suppose I have a object "Menu" that needs to have it's own timer object "Timer". I'd like to implement this association as a reference.
The object MenuHandler aggregates a lot of Menu objects but shall not have any knowledge about Timer objects. But when the MenuHandler creates a Menu object it must pass a Timer reference argument to the constructor. Thus, ****MenuHandler** must know about **Timer****.
Any suggestions on how to treat these kind of problems?
I'd hesitate to bless your choice of words when it comes to the two numbered points. They're a sign you're on the right way learning C++, but they might be misleading to other novices. When I take a look at your concrete examples, this becomes more obvious.
A MenuHandler should not create menus. The content of menus is determined by by the application, so the application object (or the Controller part, if you've implemented Model-View-Controller) should create menus. The MenuHander merely takes ownership of menus created elsewhere.
Also, it may make sense to give each menu its own timer. That means the relation can be described as "Has a"; the menu has a timer. The relationship usually implmented by references can be described as "Knows a" (the inheritance relationship is usally called "Is a"). If each Menu object has a Timer, it can be a member, and initialized by the Menu constructor(s). The Timer object internally may obtain a reference to the system clock in its constructor, but that's not your concern.
Why not simply make the Timer object a member (by value) of the Menu class?
I find that I produce better (more maintainable, faster, etc) code and that I'm more productive using references in C++ than I would be solving the same problem with pointers... I think the traditional answer to your example would be to have a factory object that creates menus. In this way, the MenuHandler doesn't need to know about the Timer class.
The MenuHandler creates a Timer object, passes it into the Menu constructor, and forgets about it. That seems entirely reasonable.
If the MenuHandler unnecessarily kept a reference to the Timer, that would be against the advice point #2.
In a more general case where you need to provide a class to another class in order to do some kind of callback, you avoid mutual dependency (both know each other) by using an interface.
Class A derives from the interface. Class B accepts the interface as paramater in the constructor and calls the virtual function from that interface when needed.
Also check the observer design pattern.
For #1 Be very careful with the lifetime of your objects. References are no that suitable to handle dynamic graph of objets ( like your menu, menuhandler, timer, etc... ). What if you want to change the timer object later ?
It's not a good idea to have references as members in a class if the lifetime of referenced objects is not really known.
Avoiding pointer does not mean using references everywhere, you should have a look at smart pointers which will be more suitable for what you want to do.