如何从ApplicationWindow QML文件获取QMainWindow以允许QDockWidget与QML文件一起使用

joo*_*z24 5 qt qml

我正在使用Qt 5.5.0,我正在尝试将QDockWidget与QML文件一起使用。我的main.qml当前设置为“应用程序”窗口,带有一组按钮,用于选择各种QML“页面”文件,我希望在可停靠窗口中打开这些文件。

我希望这些页面选择按钮位于屏幕固定区域中的QML文件中。当前,这些按钮位于ToolBar部分中,以实现此目的,并将main.qml设置为ApplicationWindow。

为了使用QDockWidget,我需要一个QMainWindow。我尝试按照如何将QML工具栏和菜单栏嵌入QMainWindow中给出的示例进行操作

因此,在main.cpp中,我尝试获取与我的main.qml相关联的QMainWindow,如下所示:

#include <QApplication>
#include <QQmlApplicationEngine>
#include <QDebug>
#include <QQmlContext>
#include <QQmlEngine>
#include <QtQml>
#include <QtQuick>
#include <QMainWindow>
#include <QGridLayout>
#include <QPushButton>
#include <QQuickWidget>

#include "pageset.h"

QMainWindow* GlobalMainWindow;

int main(int argc, char *argv[])
{

    QApplication app(argc, argv);

    qmlRegisterType<PageSet>("pagesetter", 1, 0, "MyPageSet");

    QQmlApplicationEngine engine;
    engine.load(QUrl(QStringLiteral("main.qml")));

//I’ve added the following just to try and get a QMainWindow....

    QObject *rootObject = engine.rootObjects().first();
    QQuickWindow *qmlWindow = qobject_cast<QQuickWindow *>(rootObject);

    /* From /sf/ask/1901720761/ */
    QWidget *container = QWidget::createWindowContainer(qmlWindow);
    container->setMinimumSize(qmlWindow->size());   //This IS required!

    //Place container to the top of your widget

    QMainWindow *mainwindow = new QMainWindow();
    GlobalMainWindow = mainwindow;
    //NB. Crashes without setMenuWidget!!
    mainwindow->setMenuWidget(container);

    //At first, get a small white border around the qml window - and no buttons are responsive
    //then if you somehow adjust size so it 'snaps', all looks ok and buttons work!
    mainwindow->setMinimumSize(qmlWindow->size());   //??
    mainwindow->show();

    return app.exec();
}
Run Code Online (Sandbox Code Playgroud)

我不确定QMainWindow的上述用法是否有效,因为QML文件可以很好地显示,而在engine.load和return之间没有任何代码。

无论如何,我的main.qml是这样的:

import QtQuick 2.4
import QtQuick.Controls 1.4
import QtQuick.Window 2.2
import QtQuick.Layouts 1.2
import pagesetter 1.0

ApplicationWindow
{
    title: qsTr("Test")
    visible: true
    width:1080
    height:720

    MyPageSet{
        id: pageSet
    }

    toolBar: ToolBar{
        GridLayout{
        x: 4; anchors.top: parent.top; anchors.bottomMargin: 4; anchors.fill:parent
        rows: 2;
        columns: 5;

        Button 
        {
            Layout.fillWidth: true; Layout.fillHeight: true;
            text: "page1"; checkable: true; 
            onClicked:
            {
               pageSet.display("Page1.qml")
            }
        }
        }   //End of Grid

    }   //End of toolbar
}
Run Code Online (Sandbox Code Playgroud)

其中,MyPageSet使用“ display”方法注册为C ++类“ PageSet”,如下所示:

void PageSet::display(QString file)
{
   QDockWidget *dock = new QDockWidget(tr("DockWidget name TBD"), GlobalMainWindow);

   QQuickView *view = new QQuickView();

   QWidget *container = QWidget::createWindowContainer(view, dock);
   container->setMinimumSize(200, 200);
   container->setMaximumSize(200, 200);
   container->setFocusPolicy(Qt::TabFocus);

   view->setSource(QUrl(file));


   dock->setWidget(container);

   GlobalMainWindow->addDockWidget(Qt::LeftDockWidgetArea, dock);
}
Run Code Online (Sandbox Code Playgroud)

Page1.qml是

Rectangle
{
 ...various buttons
}
Run Code Online (Sandbox Code Playgroud)

该代码可以运行,但是尽管可以看到Page1.qml文件已加载(创建时,我已经在各种自定义类型中进行了调试),但是看不到显示的页面。

我怀疑这是由于我的QMainWindow并不是我真正需要的。

我知道如果直接将Page1.qml直接添加到main.qml中,则可以正确显示它,因此我认为这没有任何问题。

任何人都可以建议我应该如何获取QMainWindow,以便可以在其上附加停靠小部件,或者关于我做错了什么以及为什么什么都不显示的任何其他建议。