基本上,我試圖在 QML 中使用我自己的一些類重新創建 IconLabel。但是,它在有限的意義上起作用:
import QtQuick 2.15
import QtQuick.Controls.Material 2.15
import QtQuick.Layouts 1.15
Item {
id: root
property int spacing: 8
property string direction: "left"
property string icon: ""
property bool is_img: false
property int icon_size: 24
property int font_size: 14
property string text: ""
property string font: "Roboto"
property color color: "black"
property color icon_color: "black"
property color text_color: "black"
Component.onCompleted: {
var cmd = `
import QtQuick 2.15
import QtQuick.Controls.Material 2.15
import QtQuick.Layouts 1.15
`;
var isHorizontal = direction === "left" || direction === "right";
var alignmentCmd = `Layout.alignment: ${isHorizontal ? "Qt.AlignVCenter" : "Qt.AlignHCenter"}`;
var iconCmd = "";
if (icon_color === "black")
icon_color = color;
if (text_color === "black")
text_color = color;
if (root.icon !== "") {
if (is_img) {
iconCmd = `MImage {
source: "${icon}"
Layout.alignment: ${isHorizontal ? "Qt.AlignVCenter" : "Qt.AlignHCenter"}
Layout.fillWidth: true
Layout.fillHeight: true
fillMode: Image.PreserveAspectCrop
width: ${icon_size}
height: ${icon_size}
}`;
} else {
iconCmd = `MIcon {
icon: root.icon
color: root.icon_color
${alignmentCmd}
width: ${icon_size}
height: ${icon_size}
}`;
}
}
var textCmd = `
Text {
text: root.text
font.pixelSize: root.font_size
font.family: root.font
color: root.text_color
${alignmentCmd}
}
`;
var componentCmd = direction === "left" || direction === "top" ? iconCmd textCmd : textCmd iconCmd;
cmd = `
${isHorizontal ? "RowLayout" : "ColumnLayout"} {
spacing: ${isHorizontal ? "root.spacing" : "0"}
${componentCmd}
}`;
Qt.createQmlObject(cmd, root, "dynamicComponent");
}
}
如果我單獨使用它,它會做我想做的一切,比如

import QtQuick 2.15
import QtQuick.Controls 2.15
import QtQuick.Layouts 1.15
import QtQuick.Dialogs
import QtQuick.Controls.Material 2.15
import "components"
ApplicationWindow {
id: root
visible: true
width: 640
height: 480
title: qsTr("Hello World")
MIconLabel {
icon_color: Material.color(Material.Red, Material.Shade500)
direction: "right"
icon: "home"
text: "Home"
}
MIconLabel {
icon_color: "black"
icon: "menu"
text: "Menu"
y: 100
}
}
但由于某種原因,它拒絕與 RowLayout 或任何此類性質的合作。

import QtQuick 2.15
import QtQuick.Controls 2.15
import QtQuick.Layouts 1.15
import QtQuick.Dialogs
import QtQuick.Controls.Material 2.15
import "components"
ApplicationWindow {
id: root
visible: true
width: 640
height: 480
title: qsTr("Hello World")
ColumnLayout {
MIconLabel {
icon_color: Material.color(Material.Red, Material.Shade500)
direction: "right"
icon: "home"
text: "Home"
}
MIconLabel {
icon_color: "black"
icon: "menu"
text: "Menu"
}
}
}
因此,我問是否有某種方法可以讓父物件檢測到新創建的物件(如重繪 或重新測量方法?)。我試圖調整視窗大小以希望重新繪制事件,但沒有發生任何好事。我還在console.log初始化方法的最后使用了列印出新創建物件的維度,以及根物件的維度,下面的運算式計算為True:root.width == object.width == root.childrenRect.width和root.height == object.height == root.childrenRect.height.
只是在這里解釋一些細節:MIcon是一個預先宣告Text為. 如果未提供影像,則基本上是帶有圓角和占位符的 Image 包裝器。font.familyMaterial IconsMImage
uj5u.com熱心網友回復:
花了一些時間閱讀您的代碼。我閱讀了您的代碼,我覺得這是(1)粗暴使用 createQmlObject() 并且我建議您找到另一種方法來做同樣的事情。例如,您是否知道大多陣列件都icon.source具有icon.color? 例如
ItemDelegate {
icon.source: "..."
icon.color: "..."
}
我嘗試使用以下方法重新創建您的 UI:
ItemDelegate渲染文本和圖示icon.source并icon.color為 SVG 著色LayoutMirroring實作從左到右和從右到左的模式- 添加
Frame了組件以直觀地檢查嘗試的尺寸
這是完整的作業示例:
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
Page {
ColumnLayout {
width: parent.width
Frame {
ItemDelegate {
text: "Home"
icon.source: "home-32.svg"
icon.color: "red"
LayoutMirroring.enabled: true
}
}
Frame {
ItemDelegate {
text: "Menu"
icon.source: "hamburger-32.svg"
icon.color: "black"
}
}
}
}
//home-32.svg
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32"><path d="M11 8.5V5H6v8.5L2.5 17H5v12h8v-8h6v8h8V17h2.5L16 3.5zM26 16v12h-6v-8h-8v8H6V16H4.914L7 13.914V6h3v4.914l6-6L27.086 16z"/><path fill="none" d="M0 0h32v32H0z"/></svg>
//hamburger-32.svg
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32"><path d="M28 7H4V6h24zm0 9H4v1h24zm0 10H4v1h24z"/><path fill="none" d="M0 0h32v32H0z"/></svg>
您可以
正如 Stephen Quan 所建議的那樣,如此大量的 createQmlObject 是不好的。因此,提出了一種替代解決方案,盡管它缺乏在各種方向上創建 IconLabel 的能力。
import QtQuick 2.15
import QtQuick.Controls.Material 2.15
import QtQuick.Layouts 1.15
Rectangle {
id: root
property color color: "black"
property alias spacing: rowLayout.spacing
property alias icon: icon.icon
property alias text: text.text
property alias text_size: text.font.pixelSize
property alias icon_size: icon.size
property alias font: text.font.family
property var icon_color: null
property var text_color: null
implicitHeight: rowLayout.implicitHeight
implicitWidth: rowLayout.implicitWidth
RowLayout {
id: rowLayout
anchors.fill: parent
MIcon {
id: icon
icon: root.icon
size: root.icon_size
Layout.alignment: Qt.AlignVCenter
}
Text {
id: text
Layout.alignment: Qt.AlignVCenter
}
}
Connections {
function onColorChanged() {
root.icon_color = root.color
root.text_color = root.color
}
function onIcon_colorChanged() {
icon.color = root.icon_color
}
function onText_colorChanged() {
text.color = root.text_color
}
}
Component.onCompleted: {
if (root.icon_color == null) {
root.icon_color = root.color
}
if (root.text_color == null) {
root.text_color = root.color
}
}
}

轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/520150.html
標籤:qtqmlpyside6
上一篇:QML將ListView滾動一行
