Embedding external applications into QtWidgets - reparenting QWidgets/QWindows



  • Hello everyone!

    I am new in this blog, so first of all:

    qDebug() << "Hello world! :-)";
    

    To the real problem:
    I am having trouble embedding an "external" window into my "parent" application. Both applications are Qt5-Widgets applications and created in QtCreator. The scenario is the following:

    A) Host application: it has a simple descriptive QLabel and a blank, empty stackedWidget below the QLabel.

    B) Guest application: it has just a colored widget and a QLabel which says "Guest app"

    What I want to achieve: Launch B (Guest app) from A (Host app) via a QProcess and embed B in the main stackedWidget of A, i.e., in the Host app:

    QProcess p;
    p.setProgram("<path-to-Guest-app>");
    p.setArgs("<argument-list>"); //eventually not needed since, as said, it is just a dummy app that does nothing
    p.start();
    qDebug() << "Sucess! Child process running with pid: " << p.processId();
    

    and then do the reparenting of the B application window into A's main stackedWidget.

    So far I've tried the following:

    auto *window = QWindow::fromWinId((WId)Guest_App_Window_Id);
    Q_ASSERT(window);
    qDebug() << "Assertion passed! Window may be valid";
    QWidget *widget = QWidget::createWindowContainer(window);
    ui->stackedWidget->addWidget(widget);
    

    But when I run it, I get the following ugly errors:

    Sucess! Child process running with pid:  5981
    Window id:  73400325  was obtained
    Assertion passed! Window may be valid
    QXcbConnection: XCB error: 3 (BadWindow), sequence: 361, resource id: 73400325, major code: 7 (ReparentWindow), minor code: 0
    QXcbConnection: XCB error: 3 (BadWindow), sequence: 362, resource id: 73400325, major code: 7 (ReparentWindow), minor code: 0
    QXcbConnection: XCB error: 3 (BadWindow), sequence: 363, resource id: 73400325, major code: 18 (ChangeProperty), minor code: 0
    QXcbConnection: XCB error: 3 (BadWindow), sequence: 364, resource id: 73400325, major code: 12 (ConfigureWindow), minor code: 0
    QXcbConnection: XCB error: 3 (BadWindow), sequence: 365, resource id: 73400325, major code: 7 (ReparentWindow), minor code: 0
    QXcbConnection: XCB error: 3 (BadWindow), sequence: 366, resource id: 73400325, major code: 18 (ChangeProperty), minor code: 0
    QXcbConnection: XCB error: 3 (BadWindow), sequence: 367, resource id: 73400325, major code: 8 (MapWindow), minor code: 0
    

    Any suggestions on either how to solve this problem or how to embed/reparent an external application into another Qt widget? Any help is much appreciated :)

    Best regards,
    eiger824



  • @eiger824 Are you sure your window id is correct? Oh and you are running as a normal user not root right?



  • Hey @ambershark, thank you for your reply!

    I doubt that I am getting the right window ID. In fact, when I retrieve the WId from the function call

    WId id = QWidget::winId();
    

    the result differs to the one I get when I query the window Id of the "guest" app according to http://stackoverflow.com/questions/2250757/is-there-a-linux-command-to-determine-the-window-ids-associated-with-a-given-pro

    So my question(s) here remain:
    1.) How can I get the window Id of the child process?
    2.) How can I correctly embed my child process into my "host" application's window?

    Thanks again,
    /eiger824



  • I may have found a solution in
    http://stackoverflow.com/questions/33699258/qt-5-5-embed-external-application-into-qwidget
    By making use of QProcess we can write the main widget's window ID to standard output from the child process and read it back from the parent process, and then create our widget according to:

    auto *window= QWindow::fromWinId(id); // id is the window ID of the child process
    Q_ASSERT(window);
    auto *widget = QWidget::createWindowContainer(window);
    
    //let vLayout be a QVBoxLayout object, already defined, then:
    vLayout->addWidget(widget);
    this->setLayout(vLayout);
    

    I got it to work on Desktop Linux but when I cross compile I get the error that the window ID is bad. I guess some mismatch with the unsigned long long implementation on my processor which differ from the host processor. I'll keep investigating.

    /eiger824



  • @eiger824 Sorry been out camping.. no internet. ;)

    Anyway, I'm glad you figured out your problem.

    As for the cross compile.. What device/os are you cross compiling for? What is the bit depth? It sounds like your guess on your cast is correct. Probably assuming 64-bit but x-compiling to 32-bit?


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.