
Originally Posted by
jslim
"Rule number 1 when working with threads in Qt: never ever access a widget in a secondary thread."
==> I'm just curious, is there a reason for that??
Most UI is handled by a single thread, so adding multithread capability, e.g. locking in every widget method, would create lots of overhead for the standard use case.
And Qt makes it very easy to transfer data from a secondary thread to the main thread, so even the MT case is not complicated for the application developer either.

Originally Posted by
jslim
"1) Send an event to the main thread
2) Call a widget slot via QMetaObject::invokeMethod
3) Emit a signal and use a cross-thread signal slot connection."
==> very good. However, I think I should study QMetaObject. In fact, I do not understand the QMetaObject documentation. (
https://doc.qt.io/archives/qt-4.8/qm...l#invokeMethod) :-(
It basically works like this
// Calling a slot without arguments
QMetaObject::invokeMethod(myWidgetPointer,
"nameOfSlot", Qt
::QueuedConnection);
// Calling a slot with arguments
QMetaObject::invokeMethod(myWidgetPointer,
"nameOfSlot", Qt
::QueuedConnection, Q_ARG
(QString,
"someString"), Q_ARG
(int,
42));
// Calling a slot without arguments
QMetaObject::invokeMethod(myWidgetPointer, "nameOfSlot", Qt::QueuedConnection);
// Calling a slot with arguments
QMetaObject::invokeMethod(myWidgetPointer, "nameOfSlot", Qt::QueuedConnection, Q_ARG(QString, "someString"), Q_ARG(int, 42));
To copy to clipboard, switch view to plain text mode
The QueuedConnection ensures that the slot is called by the thread running the event processing for myWidgetPointer, i.e. the main thread.

Originally Posted by
jslim
"Any specific reason why you are using low-level, system specific, threading API and not simply QThread?"
==> I could use QThread. But, can not use QThread proficiently and there are API functions provided by the embedded device.
The Qt API is far easier to use and in this case has the nice side effect that you can simply emit a signal from within the thread's loop
{
Q_OBJECT
protected:
void run() override;
signals:
void updateWidgets();
};
void MyThread::run()
{
int socketFd = -1;
socketFd = socket( "Network Socket open" );
struct sockaddr_in addr;
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = inet_addr("Server IP address");
addr.sin_port = htons(Server_Listen_Port);
connect( socketFd, (struct socketaddr*)&addr, sizeof(addr) );
while( 1 ) {
pthread_mutex_lock( &threadMutex );
while( isThreadRunning == true ) {
send( socketFd, "request data", strLength, MSG_NOSIGNAL );
recv( socketFd, (void *)&recvBuffer, BUFFER_SIZE, 0 );
emit updateWidgets();
}
pthread_mutex_unlock( &threadMutex );
pthread_mutex_lock( &threadMutex );
if( isThreadRunning == false )
pthread_cond_wait( &threadCond, &threadMutex );
pthread_mutex_unlock( &threadMutex );
}
}
class MyThread : public QThread
{
Q_OBJECT
protected:
void run() override;
signals:
void updateWidgets();
};
void MyThread::run()
{
int socketFd = -1;
socketFd = socket( "Network Socket open" );
struct sockaddr_in addr;
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = inet_addr("Server IP address");
addr.sin_port = htons(Server_Listen_Port);
connect( socketFd, (struct socketaddr*)&addr, sizeof(addr) );
while( 1 ) {
pthread_mutex_lock( &threadMutex );
while( isThreadRunning == true ) {
send( socketFd, "request data", strLength, MSG_NOSIGNAL );
recv( socketFd, (void *)&recvBuffer, BUFFER_SIZE, 0 );
emit updateWidgets();
}
pthread_mutex_unlock( &threadMutex );
pthread_mutex_lock( &threadMutex );
if( isThreadRunning == false )
pthread_cond_wait( &threadCond, &threadMutex );
pthread_mutex_unlock( &threadMutex );
}
}
To copy to clipboard, switch view to plain text mode
Obviously you wouldn't even need a thread for this kind of workload because the Qt socket API can do non-blocking/asynchronous data transfer all by itself 
Cheers,
_
Bookmarks