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