Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

QT 5.5 embed external application into QWidget

Tags:

c++

linux

qt

I'm interested in embedding an external application inside of my QT 5.5 Widget based application. I'm only concerned with it working on Linux. I'm using CentOS 7 with GNOME.

This is the code I have tried:

Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);

    QWindow *window = QWindow::fromWinId(125829124);
    QWidget *widget = QWidget::createWindowContainer(window);
    widget->setParent(this);
    QVBoxLayout *layout = new QVBoxLayout();
    layout->addWidget(widget);
    this->setLayout(layout);
}

In this example I'm getting the WinId separately and just hard-coding the value for testing. The application to be embedded is running.

When I execute my Application it runs with no errors. And the application to be embedded changes screen position and resizes, however it does not embed inside my application. It is still a separate window. If I kill my application, the embedded application is killed as well.

So is there a way to actually embed the application inside of my application?

*************** UPDATE ****************

Something interesting I just uncovered. When I run my application (container application) the second application (the one I want embedded) remains an independent Window outside of my application. However if I resize my application window (click the lower right corner to resize the window) the second application (to be embedded) resizes as well, but remains an independent Window outside of my container application.

Even more interesting is that if I kill my application, both applications "disappear" from the desktop. However System Monitor shows the second application (the one I want embedded) is still running (however with no GUI). Now if I launch my application again the second application is in fact embedded in my container application, just the way I would like!

So I guess I have to figure out why killing my application and then relaunching it embeds the second application correctly.

like image 354
dan poder Avatar asked Nov 13 '15 18:11

dan poder


2 Answers

The following achieves the desired result, the key was adding the FramelessWindowHint:

QWindow *window = QWindow::fromWinId(211812356);
window->setFlags(Qt::FramelessWindowHint);

QWidget *widget = QWidget::createWindowContainer(window);

QVBoxLayout *layout = new QVBoxLayout(this);
layout->addWidget(widget);
this->setLayout(layout);
like image 116
dan poder Avatar answered Nov 10 '22 09:11

dan poder


You should have a look at this code: https://github.com/qtproject/qt-solutions/tree/master/qtwinmigrate/src

It was designed to embed non-QT windows into a QWidget on Windows. But there may be some tricks you can pickup from here, like attributes they set to make the windows be nicely integrated with each other.

For instance, you may try this (from qwinwidget.cpp):

QEvent e(QEvent::EmbeddingControl);
QApplication::sendEvent(widget, &e);

If it does not help, check qwinwidget.cpp and qwinhost.cpp for other options.

like image 23
jpo38 Avatar answered Nov 10 '22 07:11

jpo38