英文:
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();
我尝试了几种方式:
- 创建一个普通函数来创建
MainWindow
并显示,然后调用qmlRegisterSingletonType<QObject>(...)
。 - 创建一个类中的工厂方法和包装器(
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->setAttribute(Qt::WA_DeleteOnClose);
mainWindow->show();
I tried several ways:
- Create a normal function to create
MainWindow
and show, then callqmlRegisterSingletonType<QObject>(...)
. - Create a factory method and wrapper in a class(
MainWindowFactory
), then call
qmlRegisterSingletonType<MainWindowFactory>(
"Kmc", 1, 0, "MainWindow",
[](QQmlEngine*, QJSEngine*) -> 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: "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)
}
You can Try it Online!
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论