Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. Mobile and Embedded
  4. Embedding external applications into QtWidgets - reparenting QWidgets/QWindows

Embedding external applications into QtWidgets - reparenting QWidgets/QWindows

Scheduled Pinned Locked Moved Unsolved Mobile and Embedded
6 Posts 3 Posters 4.9k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • E Offline
    E Offline
    eiger824
    wrote on 17 May 2017, 16:17 last edited by
    #1

    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

    A 1 Reply Last reply 18 May 2017, 03:26
    0
    • E eiger824
      17 May 2017, 16:17

      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

      A Offline
      A Offline
      ambershark
      wrote on 18 May 2017, 03:26 last edited by
      #2

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

      My L-GPL'd C++ Logger github.com/ambershark-mike/sharklog

      1 Reply Last reply
      1
      • E Offline
        E Offline
        eiger824
        wrote on 21 May 2017, 14:30 last edited by
        #3

        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

        1 Reply Last reply
        0
        • E Offline
          E Offline
          eiger824
          wrote on 22 May 2017, 11:37 last edited by
          #4

          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

          A 1 Reply Last reply 22 May 2017, 21:49
          0
          • E eiger824
            22 May 2017, 11:37

            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

            A Offline
            A Offline
            ambershark
            wrote on 22 May 2017, 21:49 last edited by
            #5

            @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?

            My L-GPL'd C++ Logger github.com/ambershark-mike/sharklog

            1 Reply Last reply
            0
            • B Offline
              B Offline
              bambam007
              wrote on 2 Jul 2018, 19:09 last edited by
              #6

              @eiger824 I actually put the process thread in the same widget/window class call. I obtain the PID directly and pass it into the QWindow::fromWinId(id); but am getting this Xcb connection error, how did you read the Pid into the method please? Btw I am embedding a .jar Gui in the widget.
              Thanks!

              1 Reply Last reply
              0

              • Login

              • Login or register to search.
              • First post
                Last post
              0
              • Categories
              • Recent
              • Tags
              • Popular
              • Users
              • Groups
              • Search
              • Get Qt Extensions
              • Unsolved