Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Detect that "I'm running" in Qt GUI event thread

I have this function to update some GUI stuff:

void SavedConnections::renderList()
{
  // Do GUI stuff! Must run in Qt thread!!!
    ...
}

I need to ensure that this function isn't called from other threads. What I plan to do is to defer it into event loop and raise a warning:

void SavedConnections::renderList()
{ 
  if(!this_thread_is_Qt_GUI_thread()) {
    qDebug()<< "Warning: GUI operation attempted from non GUI thread!\n";
    QCoreApplication::postEvent(this, new UpdateGUIEvent());
    return;
  }
  // Do GUI stuff! Must run in Qt thread!!!
    ...
}

This pattern is also very convenient to make methods that are guaranteed to run asynchronously in GUI thread without any ugly syntax. I already asked similar question about Java's ExecutorService.

like image 786
Tomáš Zato - Reinstate Monica Avatar asked Jan 26 '16 16:01

Tomáš Zato - Reinstate Monica


People also ask

What is the main thread in Qt?

As mentioned, each program has one thread when it is started. This thread is called the "main thread" (also known as the "GUI thread" in Qt applications). The Qt GUI must run in this thread.

How do you handle event loops in Qt?

In fact, they are handled in a special way by Qt, and are processed only if the running event loop has a smaller degree of "nesting" (w.r.t. event loops) than the one where deleteLater was called. For instance: QObject *object = new QObject; object->deleteLater (); QDialog dialog; dialog.exec ();

How to create an instance of the Qt Find dialog?

Note that the creation of the instance of the Qt Find dialog is happening on the Main (GUI) thread, but it happens each time you click the "Find" menu option. The variable named theApp is a staticly-declared instance of the main application which is derived from CWinApp and utlimately becomes the "parent" object in the QDialog constructor.

Why can't I delete a qthread object in Qt?

This is because the QThread object is living in another thread, namely, the one in which it was created. Qt also requires that all objects living in a thread are deleted before the QThread object that represents the thread is destroyed; this can be easily done by creating all the objects living in that thread on the QThread::run () method's stack.


1 Answers

You can check if the current thread is the thread your object lives in:

if (QThread::currentThread() != this->thread()) {
   // Called from different thread
}

Note that this might not be the main GUI-Thread! It is the thread this lives in (see QObject Thread affinity). If you don't change it using QObject::moveToThread, it is the thread the object was created in.

This is also what QCoreApplication::postEvent uses to determine into which thread the event should be posted. The targeted Thread must run a QEventLoop to respond to the event.

So checking for the main-GUI-Thread (qApp->thread()), but posting to this's thread might not work, if your object does not live in the main-GUI-Thread. However, if you do GUI stuff there, it should anyway live in the GUI-Thread

like image 60
king_nak Avatar answered Sep 25 '22 08:09

king_nak