Qt5-QML:ColumnLayout 在嵌套循环中覆盖另一个 ColumnLayout
Posted
技术标签:
【中文标题】Qt5-QML:ColumnLayout 在嵌套循环中覆盖另一个 ColumnLayout【英文标题】:Qt5-QML: ColumnLayout is overwriting another ColumnLayout when in a nested loop 【发布时间】:2019-11-29 23:54:12 【问题描述】:从我的previous post 成功设计一个小型应用程序的布局后,我正在添加事件的逻辑。我几乎完成了它,但有些事件并没有按照我的计划发生。下面的逻辑和完整的源代码here以防万一想验证:
1) 如下图所示,当我选择要连接的机器人后,它确实显示我正在连接,但我根本无法与QML
页面进行交互动作被阻止。我认为这可能是因为我有 2 个 ColumnLayout
并且我认为一个正在覆盖另一个,但我不确定为什么会发生这种情况,因为我认为逻辑是完整的:
预期结果是当我连接到机器人时,整个页面都可以正常工作,而不是(或看起来)被禁用。
在构成问题的Minimal Reproducible Example的代码中最重要的部分下方:
main.cpp
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQmlContext>
int main(int argc, char *argv[])
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QGuiApplication app(argc, argv);
QQmlApplicationEngine engine;
const QUrl url(QStringLiteral("qrc:/main.qml"));
QObject::connect(&engine, &QQmlApplicationEngine::objectCreated,
&app, [url](QObject *obj, const QUrl &objUrl)
if (!obj && url == objUrl)
QCoreApplication::exit(-1);
, Qt::QueuedConnection);
engine.load(url);
return app.exec();
main.qml
import QtQuick 2.12
import QtQuick.Controls 2.12
import QtWebEngine 1.8
import QtQuick.Controls.Styles 1.4
ApplicationWindow
id: root
visible: true
width: 440
height: 630
title: qsTr("Conn")
property Page1 page1: Page1
property Page2 page2: Page2
Component.onCompleted:
page1.selectDialog.connect(function()
mystackview.push(page2);
);
page2.onButtonClicked.connect(function(buttonId)
page1.dialogId = buttonId;
mystackview.pop();
);
StackView
id: mystackview
anchors.fill: parent
initialItem: page1
Page1.qml
import QtQuick 2.12
import QtQuick.Controls 2.12
import QtQuick.Layouts 1.12
import QtQuick.Controls.impl 2.12 // for IconLabel
import QtWebEngine 1.8
Page
property int dialogId: -1
signal selectDialog()
function buttonClick(button)
button.text = qsTr("Connecting to %1...").arg(button.text);
button.enabled = false;
if (button.background && button.background instanceof Rectangle)
button.background.color = "green";
button.background.gradient = null;
button.background.visible = true;
if (button.contentItem && button.contentItem instanceof IconLabel)
button.contentItem.color = "white";
button.contentItem.font.bold = true;
button.contentItem.font.pointSize = 20;
function buttonClearList(buttonClear)
buttonClear.text = qsTr("Clear List").arg(buttonClear.text);
buttonClear.enabled = true;
if (buttonClear.background && buttonClear.background instanceof Rectangle)
buttonClear.background.color = "red";
buttonClear.background.gradient = null;
buttonClear.background.visible = true;
if (buttonClear.contentItem && buttonClear.contentItem instanceof IconLabel)
buttonClear.contentItem.color = "white";
buttonClear.contentItem.font.bold = true;
buttonClear.contentItem.font.pointSize = 20;
ColumnLayout
// anchors.fill: parent
// anchors.topMargin: 0 // margin from top of the page
Layout.fillWidth: true
width: parent.width
spacing: 5
Button
id: button1
text: "Select Robot"
width: parent.width
onClicked: selectDialog()
Layout.fillWidth: true
font.pointSize: 20
Button
id: dialogA
text: "Freddie Mercury: Connected"
visible: dialogId === 1
Layout.fillWidth: true
font.pointSize: 20
spacing: 10
onClicked:
buttonClick(this)
ColumnLayout
anchors.fill: parent
anchors.topMargin: 50 // margin from top of the page
Layout.fillWidth: true
spacing: 10
GroupBox
id: box1
width: parent.width
title: "Connection"
font.pointSize: 20
Layout.fillWidth: parent
spacing: 10
GridLayout
width: parent.width
columns: 1
RowLayout
id: row1
spacing: 200
Layout.fillWidth: true
Layout.fillHeight: false
Label
id: textField
text: "Connection:"
font.pointSize: 15
Layout.fillWidth: true
Text
id: connected
text: "Not-Connected"
color: "red"
font.pointSize: 15
horizontalAlignment: Text.AlignRight
Layout.fillWidth: true
Button
id: clist
text: "Clear List";
Layout.fillWidth: true
font.pointSize: 20
width: parent.width
onClicked:
buttonClearList(this)
Page2.qml
import QtQuick 2.12
import QtQuick.Controls 2.12
import QtQuick.Layouts 1.12
Page
signal onButtonClicked(var buttonId)
Component.onCompleted:
button1.clicked.connect(function()
onButtonClicked(1);
);
ColumnLayout
id: mybuttons
anchors.fill: parent
spacing: 5
Button
id: button1
Layout.fillWidth: true
Layout.fillHeight: true
text: "Freddie Mercury"
font.pointSize: 20
到目前为止,我一直在尝试将ColumnLayout
定位在不同位置的非常不同的组合。但我的怀疑是:我已经有一个ColumnLayout
,之后我有另一个ColumnLayout
,我认为它们正在相互覆盖。
但是,从official documentation 并咨询其他sources 重新在嵌套循环中使用它是没有问题的。
同样的post 谈到Column
是Positioner
,而ColumnLayout
是一个布局。
我确定我以正确的方式使用,但缺少一些东西。
请指出正确的方向来解决这个问题。
【问题讨论】:
提供minimal reproducible example @eyllanesc,非常感谢您阅读我的问题,最小可验证示例可以在这里找到https://bitbucket.org/ERaggi/signalsqml/src/master/ 我还更新了添加它的问题,以便它可用 我没有要求你提供链接,我要求你提供一个 MRE,根据定义,它应该是一个代码,应该在你的问题中允许你进行复制粘贴,然后执行它并然后重现您的问题。我认为根据您在该网站上的经验,您知道我的意思。 对不起,给我一分钟 【参考方案1】:基本设计规则:如果父项也禁用子项。
说明:
在您的情况下, ColumnLayout 是 Button 的子项,这是您的子项的其他项目的容器,因此如果 Button 被前面的 ColumnLayout 规则禁用,它也会被禁用,因此整个ColumnLayout 的内容。
解决方案:
在您的情况下,ColumnLayout 不必是 Button 的子级,但它可以位于同一级别。
另一方面,您还有其他错误:
如果您要使用 Layout.XXX,那么您不应该使用 widths.YYY,因为它们完成相同的任务,但如果您同时使用两者,您可能会遇到问题,因为它的行为可能不确定,因为它们会相互竞争.import QtQuick 2.12
import QtQuick.Controls 2.12
import QtQuick.Layouts 1.12
import QtQuick.Controls.impl 2.12 // for IconLabel
Page
property int dialogId: -1
signal selectDialog()
function buttonClick(button)
button.text = qsTr("Connecting to %1...").arg(button.text);
button.enabled = false;
if (button.background && button.background instanceof Rectangle)
button.background.color = "green";
button.background.gradient = null;
button.background.visible = true;
if (button.contentItem && button.contentItem instanceof IconLabel)
button.contentItem.color = "white";
button.contentItem.font.bold = true;
button.contentItem.font.pointSize = 20;
function buttonClearList(buttonClear)
buttonClear.text = qsTr("Clear List").arg(buttonClear.text);
buttonClear.enabled = true;
if (buttonClear.background && buttonClear.background instanceof Rectangle)
buttonClear.background.color = "red";
buttonClear.background.gradient = null;
buttonClear.background.visible = true;
if (buttonClear.contentItem && buttonClear.contentItem instanceof IconLabel)
buttonClear.contentItem.color = "white";
buttonClear.contentItem.font.bold = true;
buttonClear.contentItem.font.pointSize = 20;
ColumnLayout
Layout.fillWidth: true
width: parent.width
spacing: 5
Button
id: button1
text: "Select Robot"
width: parent.width
onClicked: selectDialog()
Layout.fillWidth: true
font.pointSize: 20
Button
id: dialogA
text: "Freddie Mercury: Connected"
visible: dialogId === 1
Layout.fillWidth: true
font.pointSize: 20
spacing: 10
onClicked:
buttonClick(this)
ColumnLayout
id: layout
visible: dialogId === 1
Layout.fillWidth: true
spacing: 10
GroupBox
id: box1
width: parent.width
title: "Connection"
font.pointSize: 20
Layout.fillWidth: parent
spacing: 10
GridLayout
width: parent.width
columns: 1
RowLayout
id: row1
spacing: 200
Layout.fillWidth: true
Layout.fillHeight: false
Label
id: textField
text: "Connection:"
font.pointSize: 15
Layout.fillWidth: true
Text
id: connected
text: "Not-Connected"
color: "red"
font.pointSize: 15
horizontalAlignment: Text.AlignRight
Layout.fillWidth: true
Button
id: clist
visible: dialogId === 1
text: "Clear List";
Layout.fillWidth: true
font.pointSize: 20
width: parent.width
onClicked:
buttonClearList(this)
【讨论】:
以上是关于Qt5-QML:ColumnLayout 在嵌套循环中覆盖另一个 ColumnLayout的主要内容,如果未能解决你的问题,请参考以下文章
如何在 QML 的 ColumnLayout 中使用 topMargin
ScrollView 内的 ColumnLayout 不会调整其内容的大小