I have the following problem: our main application uses the Qt toolkit to display windows and interact with the user. However, most of our application does not know part of the GUI. Now I have created the following design:
- There is a singleton class that can request rendering for this object (OpenSceneGraph node, but that doesn't matter for the question)
- Rendering request causes singleton to signal
- The main window class (which uses Qt) has a slot for handling rendering of an object
- Currently, the slot only creates a new text editing widget and places it in the
QMdiAreamain window
However, when you try to create a new widget, the application inevitably crashes . Error message area:
QObject::setParent: Cannot set parent, new parent is in a different thread
[xcb] Unknown request in queue while dequeuing
[xcb] Most likely this is a multi-threaded client and XInitThreads has not been called
[xcb] Aborting, sorry about that.
myApplication: ../../src/xcb_io.c:178: dequeue_pending_request: Assertion `!xcb_xlib_unknown_req_in_deq' failed.
Aborted
After looking at stackoverflow, I found similar questions (which were not easily applicable to this situation). Obviously, Qt does not like it when I change something in the main window from another thread. However, I did not consciously create a new thread, and I thought that the singleton (which is created in the main function immediately after the call QApplication()) should be in the same thread as Qt. Apparently I'm wrong.
Here is a minimal example that shows what I'm doing (I extracted the relevant parts of the code, so the example is not entirely functional):
class Object
{
public:
};
class Singleton
{
public:
typedef boost::signals2::signal<void (Object*)> signalShowObject;
signalShowObject _showObject;
};
class MainWindow : public QMainWindow
{
public:
MainWindow()
{
Singleton::getInstance()->_showObject.connect( boost::bind(&MainWindow::showObject, this, _1) );
}
private:
QMdiArea* _mdiArea;
void showObject(Object* object)
{
_mdiArea->addSubWindow( new QTextEdit() )->show();
}
};
My attempts to solve this problem were very awkward:
- Qt-
MainWindow , Boost - , Boost,
Qt , - Qt,
, . . , ?