gpt4 book ai didi

具有大量 Windows 或复杂 UI 的 Qt 5 QML 应用程序

转载 作者:行者123 更新时间:2023-12-04 20:04:54 36 4
gpt4 key购买 nike

在使用 QtQuick 控件的 QtQuick 2 中,您可以创建复杂的桌面应用程序。但是在我看来,整个 UI 必须在应用程序启动时立即声明和创建。您还不想使用的任何部分(例如 File->Open 对话框)仍必须创建,但它们是隐藏的,如下所示:

ApplicationWindow {

FileDialog {
id: fileOpenDialog
visible: false
// ...
}
FileDialog {
id: fileSaveDialog
visible: false
// ...
}
// And so on for every window in your app and every piece of UI.

现在,这对于简单的应用程序来说可能很好,但对于复杂的应用程序或有很多对话框的应用程序,这肯定是一件疯狂的事情吗?在传统的 QtWidgets 模型中,您可以在需要时动态创建对话框。

我知道有一些解决方法,例如您可以使用 Loader甚至直接在 javascript 中动态创建 QML 对象,但它们非常丑陋,并且您失去了 QML 语法的所有好处。您也不能真正“卸载”组件。嗯 Loader声称你可以,但我试过了,我的应用程序崩溃了。

这个问题有优雅的解决方案吗?还是我只需要咬紧牙关,一次为我的应用创建所有潜在的 UI,然后隐藏大部分?

注: this page有关于使用 Loader 的信息s 来解决这个问题,但正如您所见,这不是一个很好的解决方案。

编辑 1 - 为什么 Loader 不是最理想的?

好的,告诉你为什么 Loader并不是那么令人愉快,考虑这个例子,它开始一些复杂的任务并等待结果。假设 - 与人们通常给出的所有琐碎示例不同 - 任务有许多输入和多个输出。

这是 Loader解决方案:
Window {
Loader {
id: task
source: "ComplexTask.qml"
active: false
}
TextField {
id: input1
}
TextField {
id: output1
}
Button {
text: "Begin complex task"
onClicked: {
// Show the task.
if (task.active === false)
{
task.active = true;
// Connect completed signal if it hasn't been already.
task.item.taskCompleted.connect(onTaskCompleted)
}

view.item.input1 = input1.text;
// And several more lines of that...
}
}
}

function onTaskCompleted()
{
output1.text = view.item.output1
// And several more lines...

// This actually causes a crash in my code:
// view.active = false;
}
}

如果我在没有 Loader 的情况下这样做,我可以有这样的东西:
Window {
ComplexTask {
id: task
taskInput1: input1.text
componentLoaded: false
onCompleted: componentLoaded = false
}

TextField {
id: input1
}
TextField {
id: output1
text: task.taskOutput1
}

Button {
text: "Begin complex task"
onClicked: task.componentLoaded = true
}
}

这显然要简单得多。我显然想要的是 ComplexTask 的某种方式在 componentLoaded 时加载并激活其所有声明关系设置为 true,然后在 componentLoaded 时断开关系并卸载组件设置为假。我很确定目前没有办法在 Qt 中制作这样的东西。

最佳答案

从 JS 动态创建 QML 组件与从 C++ 动态创建小部件一样丑陋(如果不是更少,因为它实际上更灵活)。它没有什么难看的,你可以在单独的文件中实现你的 QML 组件,使用 Creator 在创建它们时提供的所有帮助,并在你需要它们的地方尽可能多地实例化这些组件。从一开始就隐藏所有东西是很丑陋的,它也很重,它不可能像动态组件实例化那样预测可能发生的一切。

这是一个简约的自包含示例,它甚至不使用加载器,因为对话框是本地可用的 QML 文件。

对话框.qml

Rectangle {
id: dialog
anchors.fill: parent
color: "lightblue"

property var target : null

Column {
TextField {
id: name
text: "new name"
}
Button {
text: "OK"
onClicked: {
if (target) target.text = name.text
dialog.destroy()
}
}
Button {
text: "Cancel"
onClicked: dialog.destroy()
}
}
}

main.qml
ApplicationWindow {
visible: true
width: 200
height: 200

Button {
id: button
text: "rename me"
width: 200
onClicked: {
var component = Qt.createComponent("Dialog.qml")
var obj = component.createObject(overlay)
obj.target = button
}
}

Item {
id: overlay
anchors.fill: parent
}
}

此外,上面的例子是非常简单的,只是为了说明,考虑使用堆栈 View ,无论是您自己的实现还是自 5.1 以来可用的股票 StackView .

关于具有大量 Windows 或复杂 UI 的 Qt 5 QML 应用程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26778495/

36 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com