Finding QObject which is not part of qobjects hierarchy - qt

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.

Related

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.

QAction is a special GUI related class, can it be connected to slots?

I was wondering if somebody could clarify the following for me. I'm about to sit a test in relation to Qt and the sample questions are rather ambiguous. One of the questions are as follows:
QAction is a special GUI related class in Qt. About QAction instances, we can
correctly say that:
a. QAction istances are equivalent to slots.
b. QAction instances can be connected to slots.
c. QAction instances trigger GUI events automatically.
Am I right in thinking QAction's can actually be connected to slots? And that B is the correct answer?
QAction is just a class. It acts exactly like other QObject classes when it comes to signals and slots. All "a", "b" and "c" statements are wrong. QAction instance is not a slot and cannot be connected to a slot. "Connection" is defined only between instances' signals and slots, not instances themselves. The truth is that QAction provides triggered signal that can be connected to a slot.
Also it seems that you may be confused by slots auto-connection. You can create a slot named on_<action_name>_triggered and it will be automatically connected to the corresponding action. But this feature works with any QObject-derived classes, not only QAction.
It's hard to understand what you mean by "GUI events". QAction is not a widget. It doesn't operate GUI directly. Any GUI events are processed by the used widget (e.g. QMenu). Also note that events are not signals. When you use QAction, you generally don't need to think about events.

QMainWindow destructor

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...)

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.

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