如何在 QML 中动态创建 Qt 控件?

huangapple go评论79阅读模式
英文:

How to create qt widgets dynamically in qml?

问题

以下是翻译好的部分:

我正在尝试在一个QML窗口(InitialForm)中创建一个QMainWindow(MainWindow)。在InitialForm中有一个按钮,当我点击它时,希望能动态创建并显示一个MainWindow,类似于下面的操作:

MainWindow* mainWindow = new MainWindow(GameType::PVE);
mainWindow->setAttribute(Qt::WA_DeleteOnClose);
mainWindow->show();

我尝试了几种方式:

  1. 创建一个普通函数来创建MainWindow并显示,然后调用qmlRegisterSingletonType<QObject>(...)
  2. 创建一个类中的工厂方法和包装器(MainWindowFactory),然后调用:
qmlRegisterSingletonType<MainWindowFactory>(
    "Kmc", 1, 0, "MainWindow",
    [](QQmlEngine*, QJSEngine*) -> QObject* { return new MainWindowFactory(); });

在方式1中,我不知道如何将参数传递给MainWindow的构造函数。

在方式2中,我在点击InitialForm中的按钮后确实显示了一个MainWindow,但它立即消失,整个应用程序成功退出。

英文:

I'm trying to create a QMainWindow(MainWindow) in a qml Window(InitialForm)). There is a button in the InitalForm, and when I click it, I hope a MainWindow can be dynamically created and show. Do something like

    MainWindow* mainWindow = new MainWindow(GameType::PVE);
    mainWindow-&gt;setAttribute(Qt::WA_DeleteOnClose);
    mainWindow-&gt;show();

I tried several ways:

  1. Create a normal function to create MainWindow and show, then call qmlRegisterSingletonType&lt;QObject&gt;(...).
  2. Create a factory method and wrapper in a class(MainWindowFactory), then call
    qmlRegisterSingletonType&lt;MainWindowFactory&gt;(
        &quot;Kmc&quot;, 1, 0, &quot;MainWindow&quot;,
        [](QQmlEngine*, QJSEngine*) -&gt; QObject* { return new MainWindowFactory(); });

In way 1, I don't know how to pass arguments to constructor of MainWindow.

In way 2, a MainWindow does show after I clicked button in InitialForm, but it just disapper at once, and the entire application exit successfully.

答案1

得分: 2

以下是如何使用 Repeater 动态创建 MainWindow 组件的演示。使用 ListModel 传递参数给 MainWindow 的新实例。

我在 MainWindow.qml 中基于 ItemDelegate 创建了一个模拟实现,但你也可以在这里使用真实的C++实现。

单击 "Create Random" 按钮将向 ListModel 添加一个新项。这将实例化一个具有随机位置和颜色的新 MainWindow。单击新 MainWindow 将导致从 ListModel 中删除相应的条目,从而销毁 MainWindow。

import QtQuick
import QtQuick.Controls
Page {
    Repeater {
        model: ListModel { id: listModel }
        delegate: MainWindow { }
    }
    Button {
        anchors.centerIn: parent
        text: "Create Random"
        onClicked: {
            listModel.append( {
                p: Math.random() * 500,
                q: Math.random() * 500,
                w: 100,
                h: 50,
                r: Math.random(),
                g: Math.random(),
                b: Math.random(),
            } );
        }
    }
}

// MainWindow.qml
import QtQuick
import QtQuick.Controls
ItemDelegate {
    x: p
    y: q
    width: w
    height: h
    background: Rectangle { color: Qt.rgba(r,g,b) }
    text: index
    onClicked: listModel.remove(index)
}

你可以在线尝试!

英文:

Below is a demonstration of how you can use Repeater to dynamically create anMainWindow component. A ListModel is used to pass parameters to new instances of MainWindow.

I created a mock implementation in MainWindow.qml based on ItemDelegate, but, you could use the real C++ implementation here.

Clicking on the "Create Random" button will append a new item to the ListModel. Which will instantiate a new MainWindow with a random position and color. Clicking on the new MainWindow will cause the corresponding entry to be removed from the ListModel causing the MainWindow to be destroyed.

import QtQuick
import QtQuick.Controls
Page {
    Repeater {
        model: ListModel { id: listModel }
        delegate: MainWindow { }
    }
    Button {
        anchors.centerIn: parent
        text: &quot;Create Random&quot;
        onClicked: {
            listModel.append( {
                p: Math.random() * 500,
                q: Math.random() * 500,
                w: 100,
                h: 50,
                r: Math.random(),
                g: Math.random(),
                b: Math.random(),
            } );
        }
    }
}

// MainWindow.qml
import QtQuick
import QtQuick.Controls
ItemDelegate {
    x: p
    y: q
    width: w
    height: h
    background: Rectangle { color: Qt.rgba(r,g,b) }
    text: index
    onClicked: listModel.remove(index)
}

You can Try it Online!

huangapple
  • 本文由 发表于 2023年6月30日 01:55:22
  • 转载请务必保留本文链接:https://go.coder-hub.com/76583522.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定