QWindow, QWidget, Qt5, X11Embedding how?



  • I have several applications which are developed using QX11Embed* in Qt4.8. Now i am trying to migrate to Qt5.So after some reading i found functions like
    @QWindow@

    and

    @createWindowContainer@

    are used for embedding other windows and applications.
    But using QWindow and createWindowContainer to create such application is very difficult and there needs to be more work done for QWindow for painting and rendering.

    is there any other way in Qt5.1(in Qt5.0 createWindowContainer is not available) to embed widgets and application by using simple QWidgets and other container functions.

    unfortunately createWindowContainer takes only QWindow as the argument and i cannot use that function.

    Regards,
    Dcqt.



  • All the x11 stuff has moved to the "extras" department found on Gitorious. (QX11EmbedWidgets and QX11EmbedContainer and the likes are not in 5.x)

    Try this:
    http://qt-project.org/doc/qt-5.1/qtx11extras/qx11info.html



  • Thanks for the quick reply.
    In fact i have gone through all those links but none mentioned about replacement of those functions(QX11EmbedWidgets and QX11EmbedContainer).
    Any idea on how to embed widgets in Qt5.1.

    I have been searching for the functions for months but could not succeed.



  • I think you need to choose the source components and build those.
    When you download and install QT you have an option to include source components.
    This gives you among other things a QT project file named "qtx11extras.pro", that contains:

    @
    requires(qtHaveModule(widgets))
    load(qt_parts)
    @

    then in the "src.pro" you have:

    @
    TEMPLATE = subdirs
    contains(QT_CONFIG, xcb) {
    SUBDIRS += x11extras
    }
    @

    These files defines functions that lets you query X11 for info and where to put your widgets, like:

    @
    int QX11Info::appScreen()
    {
    if (!qApp)
    return 0;
    QDesktopWidget *desktop = QApplication::desktop();
    return desktop->primaryScreen();
    }
    @

    I'm on seriously thin ice here, not really knowing what the heck I'm talking about, but hopefully it may contain a clue....


  • Moderators

    Hi,

    In Qt 5.1, use "QWindow::fromWinId()":http://qt-project.org/doc/qt-5.1/qtgui/qwindow.html#fromWinId followed by QWidget::createWindowContainer(). This is similar to constructing a QX11EmbedWidget and then calling QX11EmbedWidget::embedInto().

    Note: The QWindow can be a standalone window. If you don't need QWidgets, you don't need to call QWidget::createWindowContainer()

    [quote author="cseder" date="1381182948"]I think you need to choose the source components and build those.[/quote]It makes no sense to install the source components and then compile that source yourself. If it's in "source components", then you can already install the pre-built (and tested) binaries.



  • [quote author="JKSH" date="1381201648"]Hi,

    In Qt 5.1, use "QWindow::fromWinId()":http://qt-project.org/doc/qt-5.1/qtgui/qwindow.html#fromWinId followed by QWidget::createWindowContainer(). This is similar to constructing a QX11EmbedWidget and then calling QX11EmbedWidget::embedInto().
    [/quote]

    Hi,
    Thanks for your post.
    There is an example program here using QWindow and createWindowContainer.(By me some time back)

    http://www.qtcentre.org/threads/54922-Qt5-and-embedwidgets?p=246367&highlight=#post246367

    but problem is the window is some times getting embedded and some times not.

    One more thing, I have several applications which are using QWidget for which i can add layout and add a QWebView for displaying a web page of my choice, but QWindow does not allow layouts, if i want to add a QWebView to QWindow , How can that be done?

    In any ways using QWindow and createWindowContainer needs a lot of work(need to send winid from client to main application) and lot of paintings and rendering.

    if there is no option i will go with this option or else please suggest me alternate.



  • [quote author="cseder" date="1381182948"]I think you need to choose the source components and build those.[/quote]It makes no sense to install the source components and then compile that source yourself. If it's in "source components", then you can already install the pre-built (and tested) binaries.[/quote]

    And that's why I said:

    [quote author="cseder" date="1381182948"]
    I’m on seriously thin ice here, not really knowing what the heck I’m talking about, but hopefully it may contain a clue….[/quote]



  • Now I got a double post, trying to get the fprmatting right.

    Now I understand that I can use regular Markdown?

    EDIT: no double after all... Jeez. ;-)



  • any pointers for me??



  • in the following site it is mentioned that embedding widgets can be done using OpenGL Widgets, but there are no proper examples available .

    http://qt.developpez.com/doc/4.7/qt-embeddedlinux-opengl/

    can any one post some basic example about embedding widget, so that i will build on that.

    Thanks.


  • Moderators

    [quote author="Dcqt" date="1381214297"]problem is the window is some times getting embedded and some times not.[/quote]Hmm... that sounds like a bug, either in Qt or your code.

    Can you give more details on when your embedding succeeds, and when it fails?

    [quote]One more thing, I have several applications which are using QWidget for which i can add layout and add a QWebView for displaying a web page of my choice, but QWindow does not allow layouts, if i want to add a QWebView to QWindow , How can that be done?[/quote]QWidget::createWindowContainer() converts a QWindow into a QWidget. After you convert, you can add it to another widget's layout.

    [quote]In any ways using QWindow and createWindowContainer needs a lot of work(need to send winid from client to main application) and lot of paintings and rendering.[/quote]What do you mean? Is it more work than QX11EmbedWidget?



  • The following is what i was using in Qt 4.8 for embedding widgets.
    Now i need to port this code to Qt 5 , for that i need embedx11 equivalent functions.
    the link provided above is the version i was using in Qt 5 , but it is having the said problems.(i will copy the code here if you would like)
    will you please go through this and suggest me based on that.
    i am splitting this reply into two posts because of max number of characters limitation.

    applicationwindow.cpp

    @#include "applicationwindow.h"

    ApplicationWindow::ApplicationWindow(QWidget *parent) :
    QWidget(parent)
    {

    }
    ApplicationWindow::ApplicationWindow(int min_width,int min_height,int max_width,int max_height,QWidget* parent)
    :min_width(min_width),min_height(min_height),max_width(max_width),max_height(max_height),QWidget(parent)
    {

    }

    QX11EmbedContainer* ApplicationWindow::createApplicationWindow()
    {
    window = new QX11EmbedContainer();
    window->setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Expanding);
    QPalette pl = QPalette();
    pl.setColor(QPalette::Window,Qt::black);
    window->setAttribute(Qt::WA_PaintOnScreen,true);
    window->setPalette(pl);
    window->setMouseTracking(true);
    window->setMinimumSize(min_width,min_height);
    window->setMaximumSize(max_width,max_height);
    return window;
    }

    ApplicationWindow::~ApplicationWindow()
    {
    }
    @

    applicationwindow.h

    @#ifndef APPLICATIONWINDOW_H
    #define APPLICATIONWINDOW_H

    #include <QWidget>
    #include <QX11EmbedContainer>

    class ApplicationWindow : public QWidget
    {
    Q_OBJECT
    public:
    explicit ApplicationWindow(QWidget parent = 0);
    explicit ApplicationWindow(int min_width,int min_height,int max_width,int max_height,QWidget
    parent=0);
    QX11EmbedContainer* createApplicationWindow();

    public:
    virtual ~ApplicationWindow();
    private:
    int max_width;
    int max_height;
    int min_width;
    int min_height;

        QX11EmbedContainer* window;
    

    signals:

    public slots:

    };

    #endif // APPLICATIONWINDOW_H

    @

    main.cpp

    @#include "mainwindow.h"

    MainWindow *Container;
    int main(int argc, char *argv[])
    {
    QApplication qapp(argc, argv);
    Container = new MainWindow();
    Container->show();
    return qapp.exec();
    }

    @

    mainwindow.cpp

    @#include "mainwindow.h"

    #define HEIGHT 708
    #define FTP_HEIGHT 60
    #define WIDTH 196

    #define HELLOTEST "../hellotest/hellotest"

    extern MainWindow *Container;

    MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    {

    ApplicationProcess = NULL;
    QWidget* mainwindow  = new QWidget();
    
    getDisplayProperties(&max_width,&max_height);
    setWindowMinimumSizes(max_width - 300,HEIGHT - 100);
    setWindowMaximumSizes(max_width,max_height);
    
    createActions();
    createMenus();
    
    mainwindow->setMinimumSize(min_width,min_height);
    mainwindow->setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Expanding);
    mainwindow->setMaximumSize(max_width,max_height);
    setCentralWidget(mainwindow);
    
    QPalette pl ;
    pl.setColor(pl.Background,Qt::white);
    
    mainwindow->setAutoFillBackground(true);
    mainwindow->setPalette(pl);
    
    vLayout = new QVBoxLayout();
    mainLayout = new QHBoxLayout();
    vWidget = new QWidget();
    
    appwindow = new ApplicationWindow (min_width - WIDTH ,min_height - (FTP_HEIGHT + 105),max_width - WIDTH,max_height - (100 +FTP_HEIGHT ) );
    display = appwindow->createApplicationWindow();
    
      vWidget->setLayout(vLayout);
    
      vLayout->addWidget(display);
      vLayout->setSpacing(1);
    
      mainLayout ->addWidget(vWidget);
      mainwindow ->setLayout(mainLayout);
     vLayout->setContentsMargins(0,0,0,0);
     display->setContentsMargins(0,0,0,0);
     mainwindow->setContentsMargins(0,0,0,0);
    
     mainwindow->setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Expanding);
     display->setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Expanding);
    

    }

    void MainWindow::getDisplayProperties(int* width,int* height )
    {
    int x = 0,y = 0;
    QRect rec;
    QDesktopWidget D;
    rec = D.geometry();
    rec.getRect(&x,&y,width,height);
    }

    void MainWindow::setWindowMinimumSizes(int min_width,int min_height)
    {
    this->min_width = min_width;
    this->min_height = min_height;
    }
    void MainWindow::setWindowMaximumSizes(int max_width,int max_height)
    {
    this->max_width = max_width;
    this->max_height = max_height;
    }

    void MainWindow::createActions()
    {
    HelloTestAct = new QAction(tr("&HelloTest"),this);
    connect(HelloTestAct,SIGNAL(triggered()),this,SLOT(Launch_Hello_Test()));

    }

    void MainWindow::Launch_Hello_Test()
    {

    qDebug() << "Launch_Hello_Test";
    
    ApplicationProcess = new QProcess(display);
    QString executable(HELLOTEST);
    QStringList arguments;
    arguments << QString::number(display->winId());
    ApplicationProcess->start(executable, arguments);
    

    }

    void MainWindow::createMenus()
    {
    fileMenu = menuBar()->addMenu(tr("&File"));
    fileMenu->addAction(HelloTestAct);
    }

    MainWindow :: ~MainWindow()
    {
    }

    @
    mainwindow.h

    @#ifndef MAINWINDOW_H
    #define MAINWINDOW_H

    #include <QMainWindow>
    #include <QDialog>
    #include <QtGui>
    #include <qwidget.h>
    #include <QProcess>
    #include <QString>
    #include "applicationwindow.h"

    class MainWindow : public QMainWindow
    {
    Q_OBJECT
    public:
    MainWindow(QWidget parent = 0);
    ~MainWindow();
    private:
    QProcess
    ApplicationProcess;
    int max_width;
    int max_height;
    int min_width;
    int min_height;

    QMenu *fileMenu;

    QWidget* mainwindow;
    ApplicationWindow* appwindow;
    QHBoxLayout* mainLayout;
    QVBoxLayout* vLayout;
    QWidget* vWidget;
    QX11EmbedContainer* display;
    QAction* HelloTestAct;
    private:
    void createActions();
    void createMenus();
    void getDisplayProperties(int* width,int* height);
    void setWindowMinimumSizes(int min_width,int min_height);
    void setWindowMaximumSizes(int min_width,int max_width);

    private slots:
    void Launch_Hello_Test();
    };

    #endif // MAINWINDOW_H
    @



  • following is the sample app, it does not do much , just go and sit in one container.

    hellotest.cpp

    @#include "hellotest.h"

    HelloTest :: HelloTest(QWidget *parent):
    QWidget(parent)
    {

    qDebug() << "in hello test";
    QWidget *window = new QWidget(parent);
    QVBoxLayout *vl = new QVBoxLayout;
    window -> resize(500,500);
    window -> setPalette(QPalette(QColor(0,255,0,255)));
    window -> setAutoFillBackground(true);
    this -> setLayout(vl);
    vl -> addWidget(window);
    

    }

    HelloTest::~HelloTest()
    {

    }

    @

    hellotest.h

    @#ifndef HELLOTEST_H
    #define HELLOTEST_H

    #include <QWidget>
    #include <QDebug>
    #include <QX11EmbedWidget>
    #include <QApplication>
    #include <QVBoxLayout>
    #include <QDebug>

    class HelloTest :public QWidget
    {
    Q_OBJECT

    public:
        HelloTest(QWidget *parent = 0);
        ~HelloTest();
    private:
    

    };

    #endif // HELLOTEST_H

    @

    main.cpp

    @#include "hellotest.h"

    QX11EmbedWidget *embed;
    HelloTest *hellotest;

    int main(int argc, char argv[])
    {
    QApplication qapp(argc, argv);
    QString windowId(qapp.arguments()[1]);
    QVBoxLayout
    layout = new QVBoxLayout;

    embed = new QX11EmbedWidget;
    embed -> setMinimumSize(500,500);
    embed -> setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Expanding);
    
    embed -> setPalette(QColor(255,0,0,255));
    embed -> setAutoFillBackground(true);
    
    hellotest = new HelloTest(embed);
    hellotest -> setContentsMargins(0,0,0,0);
    
    if(NULL == embed)
    {
        qDebug() << "Unable to create hellotest";
        return 0;
    }
    if(argc < 2)
    {
        qDebug() << "More Arguments Needed";
        return 0;
    }
    qDebug()<<"windowId in WG:"<<windowId;
    
    layout -> addWidget(hellotest);
    embed -> setLayout(layout);
    embed -> embedInto(windowId.toULong());
    embed -> show();
    return qapp.exec();
    

    }@



  • [quote author="JKSH" date="1381286709"]Hmm... that sounds like a bug, either in Qt or your code.[/quote]

    Thats is really what i want to know,

    [quote author="JKSH" date="1381286709"]Can you give more details on when your embedding succeeds, and when it fails?[/quote]

    Its random, out of 10 trials some times 8, 5 , 3 , 1, none.

    [quote author="JKSH" date="1381286709"]
    QWidget::createWindowContainer() converts a QWindow into a QWidget. After you convert, you can add it to another widget's layout.
    [/quote]

    i tried this i will let you know by example in a while,
    kindly go through my Qt5 example code

    [quote author="JKSH" date="1381286709"]
    What do you mean? Is it more work than QX11EmbedWidget?[/quote]
    I am quite new here, it may be done in other way.
    for QWindow to function properly so may functions are created
    for example in the raster example provided with Qt

    QBackingStore is used and then functions likes event,renderLater, resizeEvent,exposeEvent, paintDevice and QPainter, ...etc.. etc...



  • please kindly post your opinion.
    i need this very badly... :(


  • Moderators

    [quote author="Dcqt" date="1381297578"]
    [quote author="JKSH" date="1381286709"]Can you give more details on when your embedding succeeds, and when it fails?[/quote]

    Its random, out of 10 trials some times 8, 5 , 3 , 1, none.[/quote]Do these trials use the same winIds all the time?

    [quote author="Dcqt" date="1381297578"][quote author="JKSH" date="1381286709"]
    QWidget::createWindowContainer() converts a QWindow into a QWidget. After you convert, you can add it to another widget's layout.
    [/quote]

    i tried this i will let you know by example in a while[/quote]Have you tried this yet? What did you get?

    It should be straightforward:
    @
    QVBoxLayout* layout = ...

    QWindow* myWindow = QWindow::fromWinId(id);
    QWidget* myWidget = QWidget::createWindowContainer(myWindow);
    layout->addWidget(myWidget);
    @

    [quote author="Dcqt" date="1381297578"]kindly go through my Qt5 example code[/quote]It's quite long and hard to read. Please post minimal examples. You should remove parts that aren't related to your problem, like setting size/palette/background/margins/menus/etc.

    [quote author="Dcqt" date="1381297578"]for QWindow to function properly so may functions are created
    for example in the raster example provided with Qt

    QBackingStore is used and then functions likes event,renderLater, resizeEvent,exposeEvent, paintDevice and QPainter, ...etc.. etc...[/quote]You use those functions only if you want to paint the window yourself. Since you want to embed an external window, you don't need to paint anything. The external window already paints itself.



  • [quote author="JKSH" date="1381385832"]Do these trials use the same winIds all the time?
    [/quote]
    No the winIds are different for each run.

    [quote author="JKSH" date="1381286709"]Have you tried this yet? What did you get?

    It should be straightforward:
    [/quote]
    Yes you are right i tried the same way , i tried to add a webview to the display(QWidget), but its not getting added.
    and in the log i am getting below

    bq. LEAK: 3 RenderObject
    LEAK: 1 Page
    LEAK: 1 Frame
    LEAK: 4 WebCoreNode

    @
    QWidget * display = new QWidget;
    QWidget * window ;

    void MainWindow::launch_app(int id)
    {
    WId winid = (WId) id;
    qDebug()<<"In launch_app win id is "<< id;
    QVBoxLayout *vl = new QVBoxLayout;
    display->setLayout(vl);
    window = createWindowContainer(QWindow::fromWinId(winid),display,
    Qt::WindowMinMaxButtonsHint|Qt::WindowCloseButtonHint
    |Qt::WindowCancelButtonHint
    |Qt::FramelessWindowHint);

     QUrl qurl("http://google.com");
        QHBoxLayout *layout2 = new QHBoxLayout;
     QWebView   *m_WebView = new QWebView;
     window->setLayout(layout2);
      layout2->addWidget(m_WebView);
      m_WebView->setFocusPolicy(Qt::StrongFocus);
    
      m_WebView->load(qurl);
      m_WebView->show();
     vl -> addWidget(window);
     qDebug()<<"addWidget";
    

    }
    @

    [quote author="JKSH" date="1381385832"] It's quite long and hard to read. Please post minimal examples. You should remove parts that aren't related to your problem, like setting size/palette/background/margins/menus/etc.[/quote]

    Sorry , i will clean up and post new.

    [quote author="JKSH" date="1381385832"] You use those functions only if you want to paint the window yourself. Since you want to embed an external window, you don't need to paint anything. The external window already paints itself.[/quote]

    I removed all those painting and events and every thing now the raster class only have this

    @class RasterWindow : public QWindow
    {
    Q_OBJECT
    public:
    explicit RasterWindow(QWindow *parent = 0);
    };
    @

    then i tried this but nothing shown up on my widget.

    @window = createWindowContainer(QWindow::fromWinId(winid),display,
    Qt::WindowMinMaxButtonsHint|Qt::WindowCloseButtonHint
    |Qt::WindowCancelButtonHint
    |Qt::FramelessWindowHint);

        window->setPalette(QPalette(QColor(255,0,0,255)));
        window->setAutoFillBackground(1);@
    


  • I will follow with current discussion going on here , but i also want to explain you the problem clearly as i am getting some hope that i can solve problem with your help.

    I have a mainwindow from which i launch the applications using QProcees by passing the window id.

    @QX11EmbedContainer* Container;
    QStringList arguments;
    ApplicationProcess = new QProcess(Container);
    arguments << QString::number(Container->winId());
    ApplicationProcess->start(executable, arguments);@

    The window id i am passing is of "Container", this is layed out on mainwindow.

    now i have several applications which have following code in their main.

    @ QString winId(qapp.arguments()[2]);
    embwdgt = new QX11EmbedWidget;
    embwdgt -> setLayout(layout);// to have other widgets on it
    embwdgt -> embedInto(winId.toULong());
    embwdgt -> show();@

    and some other applications use

    @gst_x_overlay_set_window_handle(GST_X_OVERLAY(sink),windowID);@

    this approach works well on Qt 4.8, but not on Qt 5.0 because of following reason.
    Qt 5.0 does not have QX11EmbedContainer and QX11EmbedWidget.

    now i need to find the equivalent of QX11EmbedContainer and QX11EmbedWidget in Qt 5 or use some other mechanism
    which have the same effect.

    i am not sure how big the modification will be, becasue i dont know a way yet.

    createWindowContainer and QWindow are available in Qt 5.1 but not available in Qt 5.0

    if i have to use Qt 5.0 i wont be able to use createWindowContainer and QWindow also.

    thus gives us three questions,

    is it possible to have embed widgets in Qt 5.0, if so, how?
    if Qt 5.1 is the only way , then i need a small working example for embedding widgets?
    is there any other way by which we can embed widgets (through x11 or xcb interface)?


  • Moderators

    By the way, what OS are you running? Is it in a native machine, or virtual machine?

    Remember the differences:

    • In Qt 4, you give the CONTAINER's WinID to the client. Then, the client embeds itself into the container.
    • In Qt 5, you give the CLIENT's WinID to QWindow::fromWinId(). This function does two things at the same time: (1) Create a container, and (2) Embed the client into the container.

    Here is how you should do it:
    @
    // This is your client widget
    QWidget* client = new QWidget();

    // Add buttons, labels, etc. to your client
    client->setLayout(...);

    // Get your client's WinID
    WId clientId = client->winId();

    // This is your container, with the client ALREADY embedded inside
    QWindow* container = QWindow::fromWinId(clientId);

    // Show your container, with the client embedded inside.
    container->show();
    @

    If you want your container to be a QWidget instead of a QWindow, then:
    @
    QWidget* client = new QWidget();
    client->setLayout(...);
    WId clientId = client->winId();

    // This is your container, with the client ALREADY embedded inside
    QWidget* container = QWidget::createWindowContainer(QWindow::fromWinId(clientId));
    container->show();
    @

    [quote author="Dcqt" date="1381398640"]
    @
    window = createWindowContainer(QWindow::fromWinId(winid));
    window->setLayout(layout2);
    @
    [/quote]Here, winid is your client's WinID. window is your container widget with the client embedded inside.

    If you have a normal widget, widget->setLayout() will remove the existing layout in the widget (which might be why you don't see anything). However, I don't think layouts can even be applied to a container widget.

    You should add your container to a layout. You should not add a layout to your container:
    @
    // Don't show your container

    QVBoxLayout *layout = new QVBoxLayout();
    layout->addWidget(container);
    layout->addWidget(webView);

    QWidget *bigWidget = new QWidget();
    bigWidget->setLayout(layout);
    bigWidget->show();
    @

    [quote]is it possible to have embed widgets in Qt 5.0, if so, how?[/quote]No, sorry. The functionality was only added in Qt 5.1.

    [quote]is there any other way by which we can embed widgets (through x11 or xcb interface)?[/quote]I haven't seen any other way.



  • [quote author="JKSH" date="1381426867"]By the way, what OS are you running? Is it in a native machine, or virtual machine?
    [/quote]

    I am using a native machine with ubuntu oneric.
    [quote author="JKSH" date="1381426867"]
    Remember the differences:

    • In Qt 5, you use the CLIENT's WinID to QWindow::fromWinId(). This function does two things at the same time: (1) Create a container, and (2) Embed the client into the container.
      [/quote]
      I was not aware of this,thanks a lot again.

    the samples i will check tomorrow and let you know if i have any issue
    i dont have setup @ home :(



  • I wrote a sample program using Qwindow to embed QWidget in it.

    widget.h

    @#ifndef WIDGET_H
    #define WIDGET_H

    #include <QtWidgets/qwidget.h>
    #include <QtWidgets>

    class Widget : public QWidget
    {
    Q_OBJECT

    public:
    Widget(QWidget *parent = 0);
    ~Widget();
    };
    #endif // WIDGET_H

    @

    widget.cpp

    @Widget::Widget(QWidget *parent)
    : QWidget(parent)
    {
    setPalette(QPalette(QColor(255,0,0,255)));
    setAutoFillBackground(true);
    WId winid = this->winId();
    qDebug()<<"winid is "<<winid;
    QWindow *winCon = QWindow::fromWinId(winid);
    winCon->show();
    qDebug()<<"After Qwindow";
    }

    Widget::~Widget()
    {

    }
    @

    main.cpp

    @#include "widget.h"

    int main(int argc, char *argv[])
    {
    QApplication a(argc, argv);
    Widget w;
    //w.show();
    return a.exec();
    }@

    I tried following:

    @ //w.show();
    QWindow *winCon = QWindow::fromWinId(winid);
    winCon->show();
    @

    Result:
    Only a transparent window is seen no color on it and window
    cannot close we had to press CTRL+C for exitting.

    @ w.show();
    QWindow *winCon = QWindow::fromWinId(winid);
    winCon->show();
    @

    Result :
    Red color window is seen , but no idea its embedded or it is independent, able to close the window , but the terminal is hanged , i mean terminal does not show prompt(i am running from terminal ./embed)

    why is this behaviour?
    do we need to set some thing after embedding in the QWindow other than show.?



  • I have added
    @
    QWidget *winCon = QWidget::createWindowContainer(QWindow::fromWinId(winid));
    winCon->show();
    @

    in widget.cpp instead of showing QWindow.

    for the case 1 above , the result is same except the window is closing upon close.
    for the case 2 window is closed , but terminal hanged ( no prompt ).



  • Yeah, got it , we need to have both winCon->show(); and w.show(); as well.
    I tried with WebView and its embedding into container.

    I have to try this on my few applications and get back if have any issue.

    I want to clarify few things

    In Qt 4.x the client used to receive the winId from server and embed into server
    in Qt 5.x the client needs to send its winId to server to embed itself into server.

    Now there is a lot of difference between these including the APIs used, so what about the applications developed using Qt 4.x way, all of them have to be modified , thats a heavy work!

    is there any solution to this ? i mean can i retain my Qt 4.x mechanism in Qt5.x by any APIs.


  • Moderators

    [quote author="Dcqt" date="1381488962"]Yeah, got it , we need to have both winCon->show(); and w.show(); as well.[/quote]Ah sorry, I forgot that part. I'm glad you worked it out.

    [quote]Now there is a lot of difference between these including the APIs used, so what about the applications developed using Qt 4.x way, all of them have to be modified , thats a heavy work!

    is there any solution to this ? i mean can i retain my Qt 4.x mechanism in Qt5.x by any APIs.[/quote]As I said before, I'm not aware of any other APIs that support XEmbed in Qt 5. You can try subscribing to the "Interest mailing list":http://lists.qt-project.org/mailman/listinfo/interest and asking there. Qt's engineers are active there.

    Do you need to port to Qt 5? If not, it may make more sense to stick to Qt 4.8.5



  • yes , we are upgrading to Qt5.

    I have tried this on one of my application.
    The window is embedding , but the problem is only first time the window is embedding properly , means it is correctly fixing in the size of its parent, and all other times the window is not fixing in the size of parent.

    i have set the size of window equal to the parent.
    @
    QVBoxLayout *vl = new QVBoxLayout;
    display->setLayout(vl);
    window = createWindowContainer(QWindow::fromWinId(winid),display,
    Qt::WindowMinMaxButtonsHint|Qt::WindowCloseButtonHint
    |Qt::WindowCancelButtonHint
    |Qt::FramelessWindowHint);

     window->setMinimumSize(min_width ,min_height);
     window->setMaximumSize(max_width ,max_height);
    window->setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Expanding);
     vl -> addWidget(window);
    window->show();
    

    @


  • Moderators

    [quote author="Dcqt" date="1381666089"]The window is embedding , but the problem is only first time the window is embedding properly , means it is correctly fixing in the size of its parent, and all other times the window is not fixing in the size of parent.[/quote]Sorry, I don't understand what you mean by "first time" or "fixing in the size".

    Please describe:

    What do you want window's size to be?

    What's wrong with window's size when you run your code? Is it too big? Is it too small? Does it change size?

    [quote author="Dcqt" date="1381666089"]i have set the size of window equal to the parent.[/quote]When a widget is in a layout, the layout controls its size.

    What is window's parent?

    [quote author="Dcqt" date="1381666089"]
    @
    Qt::WindowMinMaxButtonsHint|Qt::WindowCloseButtonHint
    |Qt::WindowCancelButtonHint
    |Qt::FramelessWindowHint);
    @
    [/quote]What do you want to achieve with these flags? They apply to top-level widgets only.

    Since you put window inside display's layout, it is not a top-level widget so it cannot use those flags.

    [quote author="Dcqt" date="1381666089"]
    @
    window->show();
    @
    [/quote]No need to write this. When you show() display, all of its child widgets will also get shown. window is one of display's child widgets, because you put window in display's layout.



  • [quote author="JKSH" date="1381680214"]
    Please describe:

    What do you want window's size to be?

    What's wrong with window's size when you run your code? Is it too big? Is it too small? Does it change size?

    [/quote]

    I want the window size to be always equal to its parent i.e the widget on which the window is added.( here it is display 2nd arg in createWindowContainer).

    I observed one thing, when the window is embedding its not embedding from top right corner always, some times coming in the middle , some times at mid left , and it does not cover all of its parent , covers only a portion of parent

    [quote author="JKSH" date="1381680214"]
    @
    window->show();
    @

    No need to write this. When you show() display, all of its child widgets will also get shown. window is one of display's child widgets, because you put window in display's layout.[/quote]
    [/quote]

    in my case if i dont write the window is not shown , i have somany layouts and widgets may be i am doing some thing wrong...., but i am applying on the top widgets which is always visible

    below is the sample codes i am using and i wrote my observation at the end.

    code :

    @
    MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    {
    QWidget *Main = new QWidget;
    setCentralWidget(Main);
    Main->setMinimumSize(300,200);
    Main->setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Expanding);

    QHBoxLayout *Hlay2 = new QHBoxLayout;
    
    Main->setPalette(QPalette(QColor(255,0,0,255)));
    Main->setAutoFillBackground(true);
    WId winid = this->winId();
    qDebug()<<"winid is "<<winid;
    QWindow *Qwin = QWindow::fromWinId(winid);
    QWidget *winCon = createWindowContainer(Qwin);
    Hlay2->addWidget(winCon);
    Main->setLayout(Hlay2);
    winCon->setPalette(QPalette(QColor(0,0,255,255)));
    winCon->setAutoFillBackground(true);
    

    }
    @

    1. i get the below errors when running, what does it mean?
      QXcbConnection: XCB error: 8 (BadMatch), sequence: 230, resource id: 67108868, major code: 7 (ReparentWindow), minor code: 0
      QXcbConnection: XCB error: 8 (BadMatch), sequence: 265, resource id: 67108874, major code: 7 (ReparentWindow), minor code: 0
      QXcbConnection: XCB error: 8 (BadMatch), sequence: 272, resource id: 67108874, major code: 7 (ReparentWindow), minor code: 0

    2. even after closing windows the process still runs, i had to forcely close the application


  • Moderators

    [quote author="Dcqt" date="1381690139"]I want the window size to be always equal to its parent i.e the widget on which the window is added.( here it is display 2nd arg in createWindowContainer).[/quote]It worked for me. When I change the parent's size, the embedded part changes size too.

    You manually changed lots of size settings with functions like setMinimumSize(), setMaximumSize(), and setSizePolicy(). Maybe they are affecting your window. Get rid of them and see what happens.

    [quote]I observed one thing, when the window is embedding its not embedding from top right corner always, some times coming in the middle , some times at mid left , and it does not cover all of its parent , covers only a portion of parent [/quote]I saw this too. I think it's a bug. Please file a bug report at http://bugreports.qt-project.org/ and provide a MINIMAL example -- you still have too many unnecessary functions, like setAutoFillBackground().

    [quote author="Dcqt" date="1381690139"][quote author="JKSH" date="1381680214"][quote]
    @
    window->show();
    @
    [/quote]
    No need to write this. When you show() display, all of its child widgets will also get shown. window is one of display's child widgets, because you put window in display's layout.[/quote]
    in my case if i dont write the window is not shown[/quote]Yes, you are right, sorry!

    [quote author="Dcqt" date="1381690139"]i have somany layouts and widgets may be i am doing some thing wrong...., but i am applying on the top widgets which is always visible[/quote]When you are trying something new, always try it with simple code first.

    If you use complicated examples, your life becomes very hard.

    [quote author="Dcqt" date="1381690139"]1) i get the below errors when running, what does it mean?
    QXcbConnection: XCB error: 8 (BadMatch), sequence: 230, resource id: 67108868, major code: 7 (ReparentWindow), minor code: 0
    QXcbConnection: XCB error: 8 (BadMatch), sequence: 265, resource id: 67108874, major code: 7 (ReparentWindow), minor code: 0
    QXcbConnection: XCB error: 8 (BadMatch), sequence: 272, resource id: 67108874, major code: 7 (ReparentWindow), minor code: 0[/quote]I'm not sure, sorry. Subscribe to the "Interest mailing list":http://lists.qt-project.org/mailman/listinfo/interest and ask there -- the list has more experienced people.

    [quote author="Dcqt" date="1381690139"]2) even after closing windows the process still runs, i had to forcely close the application[/quote]I think this is another bug; please report it too.

    As a workaround, you can force the parent widget to get destroyed when you close it, and force the app to quit when the widget is destroyed:

    @
    display->setAttribute(Qt::WA_DeleteOnClose);
    QObject::connect(display, SIGNAL(destroyed()), qApp, SLOT(quit()));
    @

    When you have filed your bug reports, please post the links here so that other people can follow the issue.



  • Sorry , that was my mistake.

    i was applying the layout repeatedly on the display , i understood this from the log when running......so thats why only for the first time the window will be displayed.

    i changed that part and some code clean up.

    below version is working perfectly fine , except for small problem.

    @
    void MainWindow::launch_app(int id)
    {
    WId winid = (WId) id;
    qDebug()<<"In launch_app win id is "<< id;
    QVBoxLayout *vl = new QVBoxLayout;
    display->setLayout(vl);

    window = createWindowContainer(QWindow::fromWinId(winid));
    vl -> addWidget(window);
     qDebug()<<"addWidget";
    

    }

    void MainWindow::finish(int,QProcess::ExitStatus)
    {
    qDebug()<<"finish";
    QLayout *lay = display->layout();
    delete lay;lay=NULL;
    }@

    and some where

    @
    void MainWindow::Launch_Test_exe()
    {
    ApplicationProcess = new QProcess();
    QString executable(TEST_EXE);
    connect(ApplicationProcess,SIGNAL(finished(int,QProcess::ExitStatus)),this,SLOT(finish(int,QProcess::ExitStatus)));

    ApplicationProcess->start(executable, arguments);
    

    }
    @

    the problem is :

    when the window is embedded , it is some times displayed completely on display widget , and some times on a portion of it.
    I applied QPalette on the display and found it out. If i maximize the main window then it is covering all the display window.

    I applied following on the display..
    @
    display = new Window (min_width -KP_WIDTH ,min_height - (FP_HEIGHT + LW_HEIGHT),max_width - RWIDTH,max_height - (75 +FP_HEIGHT ) );
    display->setContentsMargins(0,0,0,0);
    display->setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Expanding);
    @



  • [quote author="JKSH" date="1381770127"]
    I saw this too. I think it's a bug. Please file a bug report at http://bugreports.qt-project.org/ and provide a MINIMAL example -- you still have too many unnecessary functions, like setAutoFillBackground().[/quote]

    Sorry, i over looked...

    i will raise a bug report, but before that , i need to learn some x11 programming to embed widgets from one process to other.my people told me we have to use only Qt 5.0, as you know it does not support any of the above functions , so i have to rely on Native X11 library class.

    do you have any idea , any examples will be greatly appreciated .. :)

    I thank you a lot :)
    You are with me till my problem is solved , i have been trying to solve it for weeks


  • Moderators

    It's ok :) And you're welcome; do help others on the forum if you can!

    I'm quite curious -- if your team has just started to upgrade from Qt 4 to Qt 5, why did they choose Qt 5.0 and not Qt 5.1? Qt 5.1 has many bug fixes and new features, but is 100% compatible with Qt 5.0.

    I don't have X11 experience, unfortunately. Try searching for tutorials outside, like http://math.msu.su/~vvb/2course/Borisenko/CppProjects/GWindow/xintro.html

    Good luck



  • Hi all,

    Is anyone solved the problem as i am also facing similar problem.It will good if anyone can share replacement for qx11embedcontainer in qt 5.2.

    thanks


  • Moderators

    Hi,

    [quote author="pratap" date="1407410200"]Is anyone solved the problem as i am also facing similar problem.It will good if anyone can share replacement for qx11embedcontainer in qt 5.2.[/quote]Please read the previous posts in this thread. I posted examples on how to use QWindow::fromWinId() and QWidget::createWindowContainer() to replace QX11EmbedContainer.



  • I have checked previous posts based on that i tried to use QWindow::fromWinId() and QWidget::createWindowContainer() but its not working for me .

    below is source code

    @int main(int argc, char *argv[])
    {
    QApplication app(argc, argv);

    QVBoxLayout *vl = new QVBoxLayout;
    
    QtQuick1ApplicationViewer viewer;
    viewer.addImportPath(QLatin1String("modules"));
    viewer.setOrientation(QtQuick1ApplicationViewer::ScreenOrientationAuto);
    viewer.setMainQmlFile&#40;QLatin1String("qml/testX11Embed/main.qml"&#41;&#41;;
    viewer.showExpanded();
    
    viewer.setLayout(vl);
    
    //getting the window id of thirdparty application
    
    system&#40; "xwininfo -int -name 'Navigation - India' |grep 'Window id: '| awk '{gsub(\"xwininfo: Window id: \", \"\"&#41;;print}' >> EmbeddingLogNavigation.txt"&#41; ;
    
    std::string sWiId;
    
    long int navigationWindowId;
    std::ifstream in("EmbeddingLogNavigation.txt");
    std::stringstream buffer;
    buffer << in.rdbuf();
    std::string contents(buffer.str());
    
    for( int i = 0 ; contents[i] != ' ' && contents[i] != '\0' ; ++i )
        sWiId += contents[i];
    
    std::stringstream sstr(sWiId);
    
    sstr >> navigationWindowId;
    

    ////////////////////////////////////////////////

    QWidget navwidget;
    navwidget.setGeometry(0 ,0,2000 ,1000);
    navwidget.resize(500,500);
    navwidget.setPalette(QPalette(QColor(0,255,0,255)));
    navwidget.setAutoFillBackground(true);
    
    navwidget.createWindowContainer(QWindow::fromWinId(navigationWindowId));
    vl -> addWidget(&navwidget);
    navwidget.show();
    
    return app.exec&#40;&#41;;
    

    }
    @


  • Moderators

    [quote author="pratap" date="1407414917"]below is source code[/quote]Your code is too complex. Write something simpler -- don't include things that are not related to embedding.

    [quote author="pratap" date="1407414917"]
    @viewer.setLayout(vl);@
    [/quote]The viewer already has its own layout. This line will break your viewer.

    [quote author="pratap" date="1407414917"]
    @
    navwidget.createWindowContainer(QWindow::fromWinId(navigationWindowId));
    vl -> addWidget(&navwidget);
    navwidget.show();
    @
    [/quote]QWidget::createWindowContainer() is a static function that returns a pointer to your embedded window. You need to use this return value.
    @
    QWidget *emb = QWidget::createWindowContainer(QWindow::fromWinId(navigationWindowId));
    emb->show();
    @



  • Thanks for reply.

    I tried as you mentioned. But output is two separate windows one for viewer and one for navwidget.

    bq. Your code is too complex. Write something simpler — don’t include things that are not related to embedding.

    @int main(int argc, char *argv[])
    {
    QApplication app(argc, argv);

    QVBoxLayout *vl = new QVBoxLayout;
    
    QtQuick1ApplicationViewer viewer;
    viewer.addImportPath(QLatin1String("modules"));
        viewer.setOrientation(QtQuick1ApplicationViewer::ScreenOrientationAuto);
    viewer.setMainQmlFile&#40;QLatin1String("qml/testX11Embed/main.qml"&#41;);
    viewer.showExpanded();
    
    long int navigationWindowId; // Window Id of navigation application
    

    // I have to embed this window into viewer window.I am able to get window id using system call.

    // Code for embedding

    QWidget *navwidget = QWidget::createWindowContainer(QWindow::fromWinId(navigationWindowId));
    vl->addWidget(navwidget);
    navwidget->show();

    @
    Output of this is two separate windows as mentioned above. Please guide me where i am doing wrong? i am using is default Qml project here provided by Qt creator(just for information).


  • Moderators

    [quote]Output of this is two separate windows as mentioned above.[/quote]You need to put both widgets in the same layout, and embed the layout in a blank widget.

    @
    QtQuick1ApplicationViewer *viewer = new QtQuick1ApplicationViewer;
    // (Initialize the viewer)
    // ...

    QWidget *navwidget = QWidget::createWindowContainer(QWindow::fromWinId(navigationWindowId));

    QVBoxLayout *vl = new QVBoxLayout;
    vl->addWidget(viewer);
    vl->addWidget(navwidget);

    QWidget w;
    w.setLayout(vl);
    w.show();
    @



  • Thanks for helping me but its not working for me.I am getting following errors.

    QXcbConnection: XCB error: 3 (BadWindow), sequence: 250, resource id: 60817411, major code: 18 (ChangeProperty), minor code: 0
    QXcbConnection: XCB error: 3 (BadWindow), sequence: 332, resource id: 60817411, major code: 7 (ReparentWindow), minor code: 0
    QXcbConnection: XCB error: 3 (BadWindow), sequence: 334, resource id: 60817411, major code: 8 (MapWindow), minor code: 0
    QXcbConnection: XCB error: 3 (BadWindow), sequence: 367, resource id: 60817411, major code: 18 (ChangeProperty), minor code: 0
    QXcbConnection: XCB error: 3 (BadWindow), sequence: 368, resource id: 60817411, major code: 12 (ConfigureWindow), minor code: 0

    I am clueless where i am doing wrong.If you can share any example code will be great help.


  • Moderators

    [quote author="pratap" date="1407502698"]Thanks for helping me but its not working for me.I am getting following errors.

    QXcbConnection: XCB error: 3 (BadWindow), sequence: 250, resource id: 60817411, major code: 18 (ChangeProperty), minor code: 0
    QXcbConnection: XCB error: 3 (BadWindow), sequence: 332, resource id: 60817411, major code: 7 (ReparentWindow), minor code: 0
    QXcbConnection: XCB error: 3 (BadWindow), sequence: 334, resource id: 60817411, major code: 8 (MapWindow), minor code: 0
    QXcbConnection: XCB error: 3 (BadWindow), sequence: 367, resource id: 60817411, major code: 18 (ChangeProperty), minor code: 0
    QXcbConnection: XCB error: 3 (BadWindow), sequence: 368, resource id: 60817411, major code: 12 (ConfigureWindow), minor code: 0
    [/quote]Have you checked the value of your Window ID? Is it correct?

    [quote]I am clueless where i am doing wrong.If you can share any example code will be great help.[/quote]Huh? I've posted so many pieces of code in this thread



  • Yes window ID is correct. I am able to embed Qml into Qt widget but other way it is not happening. I am getting errors as mentioned above.


Log in to reply
 

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