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.
Related
I wish to pass an object using the signal/slot mechanism between threads in Qt. Since I will be passing a pointer to the object, is it safe to call the methods on the object on the receiver's side?
According to this question question the object is not copied (so using original object).
Is this safe? Or am I executing methods on an object belonging to one thread in another thread? Is there a better way to do this?
(I have approximately 20 getters in this class so I don't want to pass individual variables, as well some of the variables are in fact pointers to objects as well)
It is not necessarily safe - signals and slots can be used to cross thread boundaries, so it's possible you could end up trying to access the object from another thread.
The thread in which the slot will be called is determined by the connection type. See the documentation, but as an example:
connect(source, SIGNAL(mySignal(QObject*)), destination, SLOT(mySlot(QObject*)), Qt::DirectConnection);
In this case the function mySlot() will be called from the same thread that the mySignal() signal was emitted in. If your object is not accessed from any threads other than the same thread as the signal emitter this would work fine.
connect(source, SIGNAL(mySignal(QObject*)), destination, SLOT(mySlot(QObject*)), Qt::QueuedConnection);
In this case the function mySlot() will be queued, and called by the event loop of the destination object. So anything done to the object, would happen from within the thread running the event loop of the destination.
I personally find it's best to just stick to passing simple values as arguments. Even though this can work, you would need to add suitable multithreading guards to your QObject if it's likely to be accessed from multiple threads.
First of all, try to use QtConcurrent when you are developing a multi-threaded application. The QtConcurrent namespace provides high-level APIs that make it possible to write multi-threaded programs without using low-level threading primitives such as mutexes, read-write locks, wait conditions, or semaphores.
After that, safety depends on your class members. If all members are thread-safe, then all will be run safely.
I have a series of classes that have a number of analogous Shared methods that I want to ensure are implemented in a consistent manner in each class. These Shared methods are called via reflection in various areas of code, and up to this point I’ve been keeping them in synch manually. As the number of classes grows, ensuring synchronization is becoming a bit tedious – as is the process to ensure, when I add a new Shared method to the paradigm, that it is indeed implemented in all of the classes to prevent run-time errors when reflection comes looking for them.
I’d initially thought this would be an ideal use of interfaces, but per various threads (such as Why we can not have Shared(static) function/methods in an interface/abstract class?) you cannot define Shared methods as part of an interface. I then tried to define a common base class and mark these methods MustOverride, but you cannot do that either. I’ve looked into delegates (which I’ve not used before), but it appears to allow the opposite of what I’m trying to do (namely, delegates seem to allow a common implementation of a common need from multiple classes instead of a unique implementation of a common need from multiple classes).
As such, is there an approach in VB.Net to ensure at compile-time that each of my classes implements a set of common Shared methods and functions in a consistent manner?
As a side note, the classes in question are currently all extensions of Entity Framework classes and are being blended into the EF classes.
EDIT: As a alternative to a language feature (which may not exist), I'd also be open to suggestions on any refactoring-type tools that provide this sort of functionality.
Here is sort of the skeleton of code I'm using:
Public MustInherit Class AbstractUpdateItem
Public MustOverride Function ValidateFields(ByRef dto As BusinessDTO) As Boolean
End Class
Public Class UpdateSomeFields
Inherits AbstractUpdateItem
Public Overrides Function ValidateFields(ByRef dto As BusinessDTO) As Boolean
' some code here to do the real stuff
End Function
End Class
When I comment out one of my Overrides Function (ValidateFields), I get a compile time error: Class x must either be declared 'MustInherit' or override the following inherited 'MustOverride' member(s): ValidateFields. So that would seem to ensure that they implement a set of methods. They aren't declared as shared, but will that do what you want?
In Qt Application code Class A has one member method like method1(). I want to call this method in another member function method2() and run mehtod1() in a different thread. But what I found from the qt documentation is follows.
Inherit a new class MyThread(suppose) from QThread.
Override the function method run() with your required code.
Create an object of MyThread in Class A and then call the run function wherever you want.
But the above seems bit complex. Is there any mechanism in Qt so that I can create a new QThread(without inheriting) instantly in my method1() and run the method2() with this thread and then return to method1() after execution finishes?
Please let me know if I am not clear in my question.
Yes there is a way like you want.
This article will help you to understand why it's not the correct way to inherit from QThread: https://www.qt.io/blog/2010/06/17/youre-doing-it-wrong
This article will help you to know how use QThread in a real simple way: https://www.qt.io/blog/2006/12/04/threading-without-the-headache
You can use QObject slots and signals or event support, combined with threads.
Basically, a QObject's slots called through signal/slot mechanism are executed in the thread that created the QObject. You can also move the object ownership from one thread to another using QObject::moveToThread.
You can also use QCoreApplication::postEvent to post events for execution in the thread the object was created in.
See more about threads and QObjects in Qt documentation ("Threads and QObjects" topic in index).
Going to your problem, you can use two separate objects in different threads to "spread" the execution.
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.
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.