Threads and GUI
I am relatively new to Qt, so excuse my ignorance. I have a Qt application with a main window and a TCPServer. The TCPServer is forking, in the sense that it creates QThreads and pushes worker QObjects into them.
Now the QObjects which are created by the TCPServer contain a lot of data which they display on their own GUI. I had initially created a ui xml with the QObject which was to display all this data (taken from the local variables of the QObject). But I understand now that the GUI needs to be run in the main thread.
Although I know that signal-slot would be the best way to send the QObject data to the main thread and launch the ui from there, I am not sure how to encapsulate the following before pushing it via a slot:
15 Nos. of bool (checkboxes)
15 Nos. of quint8 (comboboxes)
10 Nos. of QStrings (lineEdit)
Should I create a structure to hold this and push that via a signal (any Qt specific best practice to use structures)? Or should I declare all this data public in the QObject and access if from the main thread (bad OOPS programming I guess) ? Any other correct and efficient way?
Also am I right in understanding that signals-slots mechanism does not actually copy data, so the overhead to "send" this data is minimum?
I would like to also say in my first post that I am enjoying my Qt experience. It is a wonderful tool which I met 2 months ago, being a hardware designer essentially.
As far as I remember from Qt4 rules, you can use only QImage outside the main thread
Probably, there is new stuff regarding opengl renders in qt5. need to check
If your slot passes parameters "by value", then these values are copied. This is no different from any "normal" function call. This is especially true for queued connections, as used for communication between objects that live in different threads. In this case, the parameters need to be stored in a queue, until the thread's event loop, eventually, fetches the pending signal and calls the slot function.
In order to avoid overhead, I would store these values only once, e.g. in a struct, and just pass a pointer. It's even a very common method to not "push" any data in the signal, but just use the signal as a notification. The receiver can then "pull" the data from the object who sent the signal using suitable getter methods...
Anyway, if you work with pointers here, you need to ensure that the data, to which these pointers refer, remains valid until the receiver has processed them. In general, the sender Thread doesn't know when this happens! To solve this problem, for example, your thread could just append the data into a ring-buffer and send out a notification signal. The other thread, upon receiving the signal, would then fetch the pending data from the buffer. Needless to say that your buffer has be properly guarded with mutexes...
Thanks everyone for their replies.
As a quick fix, I let go of the threads for the initial tests in the last few days.
But now I face another problem. I have a central class controlPanel, which creates objects of a class(revHandle) with QTcpSocket, when a new connection is received on the QTcpServer.
Data is received in the revHandle and some simple data processing is performed, before a signal emits carrying data to the controlPanel. The dataset is 3 Nos. of QVector<qint16>.
The packet data rate is about 700 packets per second, with a speed of less than 100kbits/secs.
Running this application on a core 2 duo machine, causes both the CPU units to ramp up to almost 70-90% when I run it in ubuntu. In windows the application almost freezes the GUI.
I can't put all the 1000+ lines of code here for the entire application, but would be happy to share what you think is necessary.