QWindow, QWidget, Qt5, X11Embedding how?



  • 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.



  • I'd like to jump into this topic. I'm currently migrating our Qt4 code that heavily relies on window embedding to Qt 5.3.

    In Qt 4 the classes QX11EmbedContainer and QX11EmbedWidget exposed several signals such as void clientClosed (), void clientIsEmbedded (), void containerClosed () etc.

    The new mechanism in Qt5 doesn't have those signals. What are the signal equivalents in Qt5 to get informed when a client has been embedded or closed?

    Thanks!


Log in to reply
 

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