QtQuick 2 - 自定义元素,如何调整根对象的大小?

Posted

技术标签:

【中文标题】QtQuick 2 - 自定义元素,如何调整根对象的大小?【英文标题】:QtQuick 2 - Custom element, how to resize root object ot it's content? 【发布时间】:2015-05-01 02:25:38 【问题描述】:

有没有办法调整自定义元素的大小以适应其内容?我在 QML 上写了一些按钮示例,但是如果 main.qml 中未定义大小,则每次播放场景时我都需要使用文本长度调整大小。抱歉,但无法通过网络找到有关该内容的内容,只能反转有关如何将内容适合父母的问题。有来源:

BreezeButton.qml

import QtQuick 2.2
Item 
    id: root
    width: 172
    height: 72
    property string caption: "Button"
    property string iconSource: null
    signal clicked
    Rectangle 
        id: body
        border 
            width: 2
            color: "#808e8e"
        
        anchors
            fill: parent
        
        gradient: Gradient 
            id: bodyGradient
            GradientStop  position: 0.4; color: "#4d4d4d" 
            GradientStop  position: 0.9; color: "#31363b" 
        
        MouseArea
            id: bodyMouseArea
            z: bodyText.z + 1
            anchors 
                fill: parent
            

            hoverEnabled: true
            onEntered: 
                body.border.color = "#3daee9"

            
            onExited: 
                body.border.color = "#7f8c8d"
            
            onPressed: 
                body.color = "#3daee9"
                body.gradient = null
            
            onReleased: 
                body.color = "#4d4d4d"
                body.gradient = bodyGradient
            
            onClicked: 
                root.clicked()
            
        
        Text 
            id: bodyText
            anchors 
                top: body.top
                bottom: body.bottom
                left: icon.right
            
            width: body.width - icon.width
            font.pointSize: 14
            color: "#fcfcfc"
            text: caption
            verticalAlignment: Text.AlignVCenter
            horizontalAlignment: Text.AlignHCenter
        
        Image 
            id: icon
            source: iconSource
            anchors 
                left: body.left
                top: body.top
                bottom: body.bottom
                leftMargin: 5
                topMargin: 5
                bottomMargin: 5
            
            height: root.height - 8
            width: icon.height
            sourceSize.width: icon.width
            sourceSize.height: icon.height
        
    

例如,基本的 QML 按钮可以在每次播放场景时调整大小以适应其文本长度。

【问题讨论】:

【参考方案1】:

利用 Qt 是开源的这一事实很好。几乎所有你需要知道的关于如何实现 Qt 所做的事情都可以通过在代码库中动手找到。您提到了 Qt Quick Controls 的 Button 类型,所以看看那里会有所帮助。

通过Button.qml搜索只能得到菜单宽度和高度的结果,这对我们没有用处。

让我们看看它的基本类型:BasicButton。那里也没有提到宽度或高度。

如果您熟悉Qt Quick Controls,您会记得控件通常具有关联的样式,而这些样式中的组件通常决定了控件的大小,这与您想要实现的非常相似。

但我们假设您对此并不熟悉,因为仍然有可能找出您想知道的内容,您只需要多一点耐心即可。因此,现在是前往控制台并在qt5/qtquickcontrols 中运行git grep Button 的好时机。如果你这样做,你会得到很多结果。我不会把所有这些都介绍一遍,因为这就是这个练习的重点:提高你找到所需内容的能力。但是,您将看到的许多结果与Button 没有直接关系。

我们还假设您查看了结果并发现了 ButtonStyle.qml 匹配项。这些是我们听起来有趣的唯一结果,因此打开该文件。查看组件,我们看到background 和label。请注意,它们都指定了 implicitWidth 和 implicitHeight... 很有趣。阅读这些文档:

如果未指定宽度或高度,则定义项目的自然宽度或高度。

...

设置隐式大小对于根据内容定义具有首选大小的组件很有用,例如:

// Label.qml
import QtQuick 2.0

Item 
    property alias icon: image.source
    property alias label: text.text
    implicitWidth: text.implicitWidth + image.implicitWidth
    implicitHeight: Math.max(text.implicitHeight, image.implicitHeight)
    Image  id: image 
    Text 
        id: text
        wrapMode: Text.Wrap
        anchors.left: image.right; anchors.right: parent.right
        anchors.verticalCenter: parent.verticalCenter
    

我们已经很清楚现在该做什么了,但让我们通过查看Button 的组件are used 来确认它:

/*! \internal */
property Component panel: Item 
    anchors.fill: parent
    implicitWidth: Math.max(labelLoader.implicitWidth + padding.left + padding.right, backgroundLoader.implicitWidth)
    implicitHeight: Math.max(labelLoader.implicitHeight + padding.top + padding.bottom, backgroundLoader.implicitHeight)
    baselineOffset: labelLoader.item ? padding.top + labelLoader.item.baselineOffset : 0

    Loader 
        id: backgroundLoader
        anchors.fill: parent
        sourceComponent: background
    

    Loader 
        id: labelLoader
        sourceComponent: label
        anchors.fill: parent
        anchors.leftMargin: padding.left
        anchors.topMargin: padding.top
        anchors.rightMargin: padding.right
        anchors.bottomMargin: padding.bottom
    

这里反复出现的主题是implicitWidthimplicitHeight,我们可以通过查看代码推断出这一点。当然,如果你不熟悉代码,这需要更长的时间来做,但是你做的越多,它就会变得越容易,尤其是在特定框架的上下文中。

【讨论】:

太棒了,正是我想要的。谢谢你。我只是 QML/Qt 初学者,所以现在还不知道所有的陷阱和类型。 不用担心。 :) 我回答的目的是帮助您更轻松地查看源代码,即使您是初学者。有时,这比尝试通过 Google 寻找特定问题的解决方案或搜索文档(当您可能不知道要查找什么时)更容易。 很好的解释风格和详细描述如何执行故障排除。

以上是关于QtQuick 2 - 自定义元素,如何调整根对象的大小?的主要内容,如果未能解决你的问题,请参考以下文章

调整自定义视图的报告大小以包括绘制的图形

如何自定义CollectionView中每个元素的大小和间距

在QtQuick中自定义样式[重复]

vue3的根节点

QtQuick/Qml自定义控件(3)-自定义对话框

QtQuick/Qml自定义控件(1)-ToolTip