QMainWindow destructor - qt

Why the QMainWindow's destructor is not virtual? If I inherit a class MainWindow from QMainWindow and have some pointer attribute on it I can't delete the memory using MainWindow's destructor.

QMainWindow's destructor is an override of an already existing destructor (QWidget::~QWidget()) which in turn is an override of a virtual destructor (virtual QObject::~QObject()). Thus, QMainWindow::~QMainWindow() is virtual. The same rules apply as with normal member functions.

QObject's destructor has been declared as virtual. QMainWindow is derived from QObject indirectly. I belive QMainWindow's destruct does not need virtual in this case. Did you set breakpoint in QMainWindow's destructor while deleting your derived class?

This is a defect in Qt (failure to adhere to CBP); it is best practice to always carry-over modifiers, especially virtual, in all derived classes, exactly to avoid this kind of problem.
NOT carrying-over the the virtual declaration means that, as a user, I have to not just lookup the class, but also ALL it's parents, to make sure the method(s) I want to override are virtual or not. A little laziness by the developers costs me lots of time.
Arguments about 'maintainability' are irrelevant; it makes the class harder to use (there will be many, MANY more users than maintainers...)

Related

Finding QObject which is not part of qobjects hierarchy

In a debug build I would like particular objects of my program to register themselves in some global registry so I can have a view in my app detecting them and showing theirs statuses.
As all of them are QObjects I was wondering if there is a clever way of registering them in some global QObjects list (which I am not aware of). I cannot use regular hierarchy as some of these objects simply never become a child of any other QObject.
Since QApplication inherits QObject you could just set your active QApplication as parent of all QObjects not fitting into your normal application tree. After closing all windows you could then check all children of QApplication for leaked QObjects by calling const QObjectList & QObject::children() const.

Qt (PyQt) globally available slots?

I have a fairly complex MVC structured application and I want a convenient way to update a QStatusBar from almost any part of it. My understanding is that I would have to pass around a lot of references to my QStatusBar or set up a bunch of signals in my controllers. It would get messy.
I also understand that QApplication is essentially a singleton. Would it be an acceptable idea to add a slot to it so that I could get the instance of QApplication from anywhere and emit to it?
Alternatively, what is a reasonable way to communicate global-ish things in my application without littering the controllers and views with references to widgets parented elsewhere?
How about implement singleton, that allow communication between components and gui, something like:
#include <statuscontroller.h>
StatusController::instance()->setStatus("Status string");
In this case only StatusController contain pointer to QStatusBar and available globally in gui thread.
With QObject as base class for StatusController you could use signals and slots.

Get a list of all QObjects created in a Application

To get a list of all the QWidgets created in an application we can simply call QApplication::allWidgets().
I've read the documentation, and I haven't found anything like this to get a list of all QObjects. If an application creates stand-alone QObjects that are not QWidgets I have no such function to use.
Is there a method to obtain such a list?
To begin with it's important to understand the difference between the QObject and QWidget classes.
class QObject
QObject instances have a pointer to their parent which may or may not be a null pointer. It's quite legitimate to create a QObject instance without a parent so long as you understand that it is your responsibility for that instance's lifetime i.e. if you don't delete it you will leak memory.
class QWidget
Although it appears you can create a QWidget without a parent, you can't. When you create an instance of a QWidget "without a parent" (i.e. by supplying a null pointer or letting it default to a null pointer) it's parent effectively gets set to your application's QApplication1 instance.
Is there a method to obtain such a list?
No. The reason QApplication::allWidgets() works is due to the fact that all QWidget instances have a pointer to them which is stored in your single QApplication instance. There is no central store of QObject pointers and therefore no in-built way of retrieving them.
One way around this is to ensure yourself that all QObjects instances (or instances of classes which inherit QObject) have a valid parent. Then you can use the QObject functions children(), findChild() and findChildren() to get pointers to these objects.
These are powerful tools, and like anything powerful, use them with care! Make sure you understand C++ object life spans before you use these in production code.
Notes:
QApplication inherits from QCoreApplication which inherits from QObject. There are some restrictions placed on how QApplication is used by the Qt framework.

Interface Segregation in Qt

I always try to apply the S.O.L.I.D principles and I really like the Qt toolkit but I find myself stuggeling all the time with the single inheritance rule.
If you are using multiple inheritance,
moc assumes that the first inherited
class is a subclass of QObject.
Also, be sure that only the first inherited class is a QObject.
How do you combine the single inheritance from a QObject rule and the Interface Segregation Principle.
I want to define the interfaces with signals and slots, but I'm not allowed to do this.
How do you get around this shortcomming?
Keep in mind that signals and slots are nothing more than functions that have special behaviors. Thus, you can use them to create interfaces.
For a full description of the process and a complete workaround for complex cases, see Qt Quarterly #15.
I don't think you can easily get around that with Qt's signal/slot mechanisms. You could try looking at either boost::signals or the sigc library, which are both more flexible in where you can place signals and slots. Be aware of possible namespace collisions with either library and Qt's signals and slots macros.

Can a class inherited from Qthread behave as a normal class?

Can a class inherited from QThread and having run method can have other methods and can it be used like another normal ( not inherited from QThread) class?
Yes, a class that inherits from QThread is still a normal class. However, care must be taken to synchronize calls to member functions that occur in a different thread context (i.e. calls from outside of the run method) as necessary. Read about Thread Support in Qt for more details. Herb Sutter has a nice collection of articles discussing different aspects of concurrency as well.

Resources