PDA

View Full Version : Non-Gui thread Callback API and Qt - how



The Storm
29th October 2008, 16:24
Hello,

I am developing a GUI application that use external non-Qt based library. This external library have a callback interface class that I have to inherit and override the virtual methods in order to use the data that comes. The problem is that the callbacks are called from other thread that is created by the external library and in this way I can't update my GUI with the new information that comes. My question is - is there a way to use signal and slots inside the callback interface class in order to update safely my GUI?

Thank in advance.

caduel
29th October 2008, 17:13
Yes, just make sure you use a Qt::QueuedConnection in QObject::connect() when connecting signals to slots. Queued connections are not executed right away but rather queued into (the other threads) event queue and work fine with threads.

The Storm
29th October 2008, 18:40
Thanks for the reply. :) Do I have to inherit QObject and put the Q_OBJECT macro in to the interface class?

caduel
29th October 2008, 18:47
if you want to emit signals: yes
(ok, to be more precise: if you want to declare signals, yes.
you could emit signals that a base class has declared w/o adding a Q_OBJECT.)

The Storm
30th October 2008, 14:15
Hi,

Thank you for your help. I made my own signals in to the callback interface class and when I connect them everything is working fine. But when I create a new Widget(any kind) in the slot (located in to the main windows class) I am getting incorrect drowing. The widget is not drawn at all until I do not call setAutoFillBackground(true) and show() functions. Ok in this way I will get it drawed but if I made some changes on it ( for example treeview ) like to add an item it will now show up, until I do not call hide(); and show(); functions. Very weird and annoing. I am using Qt 4.4.3 on Windows XP with Visual C++ 2008.

Please help.

caduel
30th October 2008, 14:58
Make sure the slot is executed in the gui thread's context (print QThread::currentThread() and compare it to the gui thread).

The widgets you are creating: are these new windows, or just additions to existing windows? In any case, newly created widgets (or a parent of them) have to be shown explicitly.

If that does not answer your questions, please be more specific and maybe provide some source.

The Storm
30th October 2008, 15:43
I used QThread::currentThread() and it seems that I am getting the slot calls in to the main GUI thread as it have to be but the problem still exist.

In my case I create a QTreeWidget and I put items in it. I create it like this:



void MainWindow::onLoginSuccess() // slot
{
// 'this' is a pointer to a QMainWindow
QTreeWidget *TreeWidget = new QTreeWidget(this->ui.centralwidget);
TreeWidget->show();
}


In this way it will not show up, I will have to call setAutoFillBackground(true) before show in order to get the QTreeWidget visible. Ok I can live with that but when I add a items they are not showing up until I don't do hide(), show() calls to the QTreeWidget. I have connected the slot like this:



// g_document.getListener() returns a pointer to the Callback API
connect( g_document.getListener(), SIGNAL(loginSuccess()), this, SLOT(onLoginSuccess()), Qt::QueuedConnection );


But if I create the QTreeWidget for example in to the constuctor of the MainWindow it will work just fine and I am able to add items via slots that are called from the other external library thread using QObject::connect().

The Storm
3rd November 2008, 08:21
Anyone, please ?

caduel
3rd November 2008, 10:56
Is that on purpose that you do not insert the newly created widget into its parent's layout()?

The Storm
3rd November 2008, 20:24
I do not use layouts at the moment, I think that the widget should display itself when I put the parent in its constructor, but when is called from an slot function it doesn't work correctly...