×

INDI Library v2.0.6 is Released (02 Feb 2024)

Bi-monthly release with minor bug fixes and improvements

INDI Client, Qt and threads

  • Posts: 35
  • Thank you received: 1
Hey,

so I'm having some weird thread behavior, or at least it seems weird to me. I don't have too much experience with threads yet.

I made my client inherite from QObject and BaseClient to have it emit signals etc. (I'm aware that I could have used QtBaseClient, but when I started writing my code, there was no need to use Qt and now its a little too complex to change with low effort and no real need)
class cl_SacherClient : public QObject, public INDI::BaseClient
{
    Q_OBJECT
 
  public:
[....]
};

My client is child of the GUI.
QApplication app (argc, argv);
sacher::cl_SacherGUI* gui = new sacher::cl_SacherGUI;
std::unique_ptr<sacher::cl_SacherClient> client_ptr(new sacher::cl_SacherClient(gui));

So my problem is that the construction of GUI and client is all in one thread, everything fine so far, but than the newDevice, newAnything functions seem to be called from another thread which troubles me as I am constructing new QActions in the GUI (so this QActions will be children of the GUI due to clean up etc...) depending on the arrival of new basedevices. But the children-parent assignment doesn't work since the GUI is still in the first thread and children and their parent must live in the same thread as Qt states. Which results in these errors:
QObject: Cannot create children for a parent that is in a different thread.
(Parent is sacher::cl_SacherGUI(0x5594e6af8ca0), parent's thread is QThread(0x5594e6b498a0), current thread is QThread(0x7f1f1c002060)
QObject: Cannot create children for a parent that is in a different thread.
(Parent is sacher::cl_SacherGUI(0x5594e6af8ca0), parent's thread is QThread(0x5594e6b498a0), current thread is QThread(0x7f1f1c002060)
QObject::startTimer: Timers cannot be started from another thread
QObject::startTimer: Timers cannot be started from another thread
Plus, for every "newDevice" I receive I construct an object representing this object, much like a layer in between mostly for convenience. And these object are than also constructed in the second thread, which is not so severe as the first issue, but somewhat annoying.

So my question goes something like this: Is this normal behavior? If not, how could I solve this issue? If yes, what would be the workaround for the "children-parent-different thread" problem? Using QObject::moveToThread() for each QAction I add, which seems kinda quick and dirty to me?

It seems to me, like this could be normal since the client and GUI are created in my main.cpp, thus living in the main thread. But, of course, the newSomething functions are called from somewhere else (?). But than, how would that work? Is it thread-safe? (Again, I don't have too much experience with threads, please forgive me if I'm assuming weird things here)

Ubuntu 18.04.3 LTS
INDI Library: 1.8.2
Code 1.8.2-tgz. Protocol 1.7.
Qt: 5.9.5
KDE Frameworks: 5.44.0
4 years 1 month ago #50097

Please Log in or Create an account to join the conversation.

  • Posts: 35
  • Thank you received: 1

Replied by erik on topic INDI Client, Qt and threads

Hey, I figured it out. Was, in fact, just my own lack of experience.
So, there is this BaseClientQt for a reason when using Qt and QThread. Switched over to that one from BaseClient and now it works like a charm!

Cheers
Erik
4 years 1 month ago #50217

Please Log in or Create an account to join the conversation.

Time to create page: 0.664 seconds