April 29, 2011

bazz-dee bazz-dee
Lab Rat
6 posts

[solved] Qt Signal/Slots in one class but emitted from different threads

 

Hi,

i saw a lot of post concerning this topic, but all topics did not match my problem.

The project is devided in two parts, a library where all processing is done and the GUI. The library is completly in C++/MFC and should not be changed that much because it is also used in none Qt projects which have to be running without Qt dependencies. The library defines an interface to make calls to an GUI. So the Qt GUI also implements this interface in order to receive the calls from the library. The library runs several threads.

Some of the processing of the GUI calls should not block the library from running. So the GUI class defines slots and signals, the signals are emitted in the implemented interface functions. The signals and slots are connected using:

  1. "connect(this, SIGNAL(xyz), this SLOT(xyz));"

I think the problem is that the intface functions that emit the signals are running in thread a but the GUI runs in thread b. The right way would be create QObjects inside the library and define the signals on that side, but this is not possible in my case. Any suggestions?

12 replies

April 29, 2011

Gerolf Gerolf
Area 51 Engineer
3210 posts

You could go a bit another way:

use

  1.     QMetaObject::invokeMethod(this, "foo", Qt::QueuedConnection);

There you can also post parameters

  1.     QMetaObject::invokeMethod(this, "foo", Qt::BlockingQueuedConnection, Q_ARG(<param type>, param));

 Signature 

Nokia Certified Qt Specialist.
Programming Is Like Sex: One mistake and you have to support it for the rest of your life. (Michael Sinz)

April 29, 2011

koahnig koahnig
Mad Scientist
2106 posts

The connection is using pointers to the same instance, isn’t it?
I assume that you are using the same object through pointers in different threads. Then this might be possible. However, the signal-slot mimic will more or less generate a direct function call which will be executed in the thread you are emitting the signal. I do not see a way to tell the thread that it has to execute the function in another thread.
I guess you need to separate the different tasks in two objects. Otherwise it will not function.

April 29, 2011

Andre Andre
Area 51 Engineer
6031 posts

You can also use the connection type in your connect statement, if you need.

It depends on what you want to do in response to those signals though. You can not trigger anything that modifies the GUI from another tread than the GUI thread. That can only be done using queued connections, never with direct method calls or direct connections (amount to pretty much the same thing).

 Signature 

Looking for Qt developers to join our team @ i-Optics: https://qt-project.org/forums/viewthread/25393/

April 29, 2011

bazz-dee bazz-dee
Lab Rat
6 posts

Gerolf wrote:
You could go a bit another way:

use

  1.     QMetaObject::invokeMethod(this, "foo", Qt::QueuedConnection);

There you can also post parameters

  1.     QMetaObject::invokeMethod(this, "foo", Qt::BlockingQueuedConnection, Q_ARG(<param type>, param));

That is working, thank you.

April 29, 2011

Gerolf Gerolf
Area 51 Engineer
3210 posts

Using the typed connect also works with emit signal then:

  1. "connect(this, SIGNAL(xyz), this SLOT(xyz), Qt::QueuedConnection);"

 Signature 

Nokia Certified Qt Specialist.
Programming Is Like Sex: One mistake and you have to support it for the rest of your life. (Michael Sinz)

April 29, 2011

bazz-dee bazz-dee
Lab Rat
6 posts

Gerolf wrote:
Using the typed connect also works with emit signal then:

@
“connect(this, SIGNAL, this SLOT, Qt::QueuedConnection);”
@

I tried that before and had no success

April 29, 2011

Gerolf Gerolf
Area 51 Engineer
3210 posts

If you then emit inside your class, it did not work? strange… should do logically the same as QMetaObject::invokeMethod

 Signature 

Nokia Certified Qt Specialist.
Programming Is Like Sex: One mistake and you have to support it for the rest of your life. (Michael Sinz)

April 29, 2011

bazz-dee bazz-dee
Lab Rat
6 posts
Gerolf wrote:
If you then emit inside your class, it did not work? strange… should do logically the same as QMetaObject::invokeMethod

That was the first thing i tried, from what i read i thought it should work. But the code never reached the slot function

April 29, 2011

Gerolf Gerolf
Area 51 Engineer
3210 posts
bazz-dee wrote:
Gerolf wrote:
If you then emit inside your class, it did not work? strange… should do logically the same as QMetaObject::invokeMethod

That was the first thing i tried, from what i read i thought it should work. But the code never reached the slot function

perhaps, the code was wrong? Did you add the parameter types inmj signals and also the brackets? param,eter trypes in the slot ?

  1. connect(this, SIGNAL(xyz(type1, type2)), this SLOT(xyz()));

 Signature 

Nokia Certified Qt Specialist.
Programming Is Like Sex: One mistake and you have to support it for the rest of your life. (Michael Sinz)

April 29, 2011

bazz-dee bazz-dee
Lab Rat
6 posts

i had the parameters in both

April 29, 2011

Gerolf Gerolf
Area 51 Engineer
3210 posts

only the types, or also the parameter names?

 Signature 

Nokia Certified Qt Specialist.
Programming Is Like Sex: One mistake and you have to support it for the rest of your life. (Michael Sinz)

April 29, 2011

bazz-dee bazz-dee
Lab Rat
6 posts

only the types. i still have it running with signals/slots where the signals are emitted from the GUI thread

 
  ‹‹ Qt Network: urls not loading      convert QFile to FILE* ››

You must log in to post a reply. Not a member yet? Register here!