Instantiating a tool window in qml from c++



  • Hi everyone,

    I'm trying to instantiate from c++ a qml window such that it behaves like a tool window for the main window (also in qml).
    My problem is that the window content appears inside the main window instead of in a proper separated window.

    alt text

    I tried to do this from qml and it works, however this isn't an option for the application i'm developing without reworking the way I handle windows.

    Here is the example I wrote.

    • main.cpp
    int main(int argc, char *argv[])
    {
      QGuiApplication app(argc, argv);
      QQmlApplicationEngine engine;
      WindowAllocator* allocator = new WindowAllocator(&engine);
      allocator->showMainWindow();
      return app.exec();
    }
    
    • windowallocator.cpp
    #include "windowallocator.h"
    
    #include <QQmlComponent>
    #include <QQmlContext>
    
    WindowAllocator::WindowAllocator(QQmlApplicationEngine* engine)
      : QObject(engine)
      , _engine(engine)
      , _main_window(nullptr)
    {
      _engine->rootContext()->setContextProperty("win_allocator", this);
    }
    
    WindowAllocator::~WindowAllocator()
    {}
    
    void WindowAllocator::showMainWindow()
    {
      QQmlComponent component(_engine, QUrl(QStringLiteral("qrc:/main.qml")));
      _main_window = dynamic_cast<QQuickWindow*>(component.create(_engine->rootContext()));
      _main_window->show();
    }
    
    void WindowAllocator::showToolWindow()
    {
      QQmlComponent component(_engine, QUrl(QStringLiteral("qrc:/Tool.qml")));
      QQuickWindow* tool_window = dynamic_cast<QQuickWindow*>(component.create(_engine->rootContext()));
      // Reparent the tool window to the main window
      // Note this is not a visual item parenting (QQuickWindow is not a QuickItem)
      tool_window->setParent(_main_window); 
      tool_window->show();
    }
    
    • main.qml
    import QtQuick 2.5
    import QtQuick.Controls 1.3
    import QtQuick.Window 2.2
    
    Window {
      id: root
      visible: true
      width: 640
      height: 480
      title: qsTr("Hello World")
    
        Tool {
            id: tool
        }
    
        Column {
           anchors.horizontalCenter: parent.horizontalCenter
           anchors.verticalCenter: parent.verticalCenter
    
           Button {
               text: "Open embedded"
               onClicked: tool.show()
           }
    
            Button {
                text: "Open qml allocated"
                onClicked: {
                    var component = Qt.createComponent("Tool.qml");
                    var win = component.createObject(root);
                    win.show();
                }
            }
    
            Button {
                text: "Open cpp allocated"
                onClicked: {
                    win_allocator.showToolWindow()
                }
            }
        }
    }
    
    • Tool.qml
    import QtQuick 2.5
    import QtQuick.Window 2.0
    
    Window {
        flags: Qt.Tool
        width: 300
        height: 200
    
        Rectangle {
            color: "steelblue"
            anchors.fill: parent
    
            Text {
                text: "This is a tool window"
                anchors.centerIn: parent
            }
        }
    }
    

    I suppose this is either me not reparenting things properly or a bug/limitation in Qt.
    This behavior was only tested on Windows 7

    Do you have any idea how to make this work ?

    Thanks for your time.



  • Nevermind. I found the solution.

    The parenting between the main window and the tool window should not be done with setParent but with setTransientParent.

    I hope this helps someone someday


Log in to reply
 

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