Multiple Stream Qt Boost Signal Processing

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) );

    // Set up MDI area etc.
  }

private:
  QMdiArea* _mdiArea;

  void showObject(Object* object)
  {
    // Creating a new subwindow here causes the crash. The `object` pointer is
    // not used and has just been included because it models my real problem
    // better.
    _mdiArea->addSubWindow( new QTextEdit() )->show();
  }
};

My attempts to solve this problem were very awkward:

  • Qt- MainWindow , Boost
  • , Boost, Qt ,
  • Qt,

, . . , ?

+3
2

, , singleton , . , . - , , .

, :

β€’ Qt- MainWindow

β€’ , Boost, Qt,

β€’ Qt,

Qt ( 1). , , , . Qt. Qt , ( 2), . Qt , , , .

note 1 - connect() - . Qt:: ConnectionType.

note 2 - , QObject . QObject , .

, , . , @tmpearce , .

+1

showObject :

if( QThread::currentThread() != thread() )
{
     bool ok = QMetaObject::invokeMethod(this, "showObject", Qt::QueuedConnection, Q_ARG(QObject *, object));

     if( ! ok )
         qDebug() << "Couldn't invoke method";

     return;
}

.

0

All Articles