Reputation: 635
Is there a way to resize custom element to fit it's content? I wrote some button example on QML, but I need that to resize with text length each time scene played if size not defined in main.qml. Sorry, but can't find something about that over network, only reverse question on how to fit content to parent. There is a source:
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
}
}
}
For example basic QML Button can resize each time scene played to fit it's text length.
Upvotes: 0
Views: 1650
Reputation: 24386
It's good to take advantage of the fact that Qt is open source. Almost everything you need to know about how to achieve something that Qt does can be found by getting your hands dirty in the codebase. You mentioned Qt Quick Controls' Button type, so it would help to look there.
Searching through Button.qml only gives results for menu width and height, which is not useful for us.
Let's look at its base type: BasicButton. No mention of width or height there, either.
If you are familiar with Qt Quick Controls, you'll remember that the controls usually have an associated style, and the components in these styles often determine the size of the control, which is very similar to what you want to achieve.
But let's assume you're not familiar with that, because it's still possible to find out what you want to know, you just need to have more patience. So, now would be a good time to go to your console and run git grep Button
in qt5/qtquickcontrols
. If you do that, you'll get a lot of results. I'm not going to go through all of them, because that's the point of this exercise: to sharpen your ability to find what you're looking for. A lot of the results that you'll see are not directly related to Button
, however.
Let's also assume that you went through the results and spotted the ButtonStyle.qml
matches. These are the only results that sound interesting to us, so open that file. Looking at the components, we see background and label. Notice that they're both specifying implicitWidth and implicitHeight... interesting. Read the documentation for these:
Defines the natural width or height of the Item if no width or height is specified.
...
Setting the implicit size is useful for defining components that have a preferred size based on their content, for example:
// 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
}
}
We've already got a pretty good idea of what to do now, but let's confirm it by seeing how Button
's components 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
}
}
The recurring theme here is implicitWidth
and implicitHeight
, and we were able to deduce that by looking at the code. Of course it takes longer to do if you're not familiar with the code, but the more you do it, the easier it becomes, especially in the context of a specific framework.
Upvotes: 4