QT QML 自定义按钮 - 动态改变文本和图像的相对位置
Posted
技术标签:
【中文标题】QT QML 自定义按钮 - 动态改变文本和图像的相对位置【英文标题】:QT QML Custom Button - Dynamically changing the relative position of text and image 【发布时间】:2014-01-15 13:58:33 【问题描述】:在 QML 上创建的按钮上,图像和文本的相对位置需要动态更改。所以我创建了一个布局属性来改变这个位置。当我用任何位置初始化按钮时,它都可以正常工作,但是当我以编程方式更改位置时,会出现错误。
layout
= 0: 图片在文字之上
layout
= 1:图片顶部的文字
layout
= 2:图片右侧的文字
layout
= 3:文字右侧的图片
layout
= 4:图片前面的文字
当我将布局从 0 更改为 1 时,反之亦然,没有错误。 当我将布局从 2 更改为 3 时,反之亦然,没有错误。 如果我在任何布局更改之间将布局更改为 5。当我将 Layout 更改为 5 时,所有锚属性都会重置。
很明显,锚属性绑定有问题,但我不知道它是什么。如果有人有有效的代码或可以告诉我有什么问题,我将不胜感激。
代码:
Rectangle
Gradient
id:myGradient
GradientStop position: 0.0; color: neoButton.color
GradientStop position: 1.0; color: Qt.darker(neoButton.color,1.5)
Gradient
id:myDarkyGradient
GradientStop position: 0.0; color: Qt.darker(neoButton.color,1.7)
GradientStop position: 1.0; color: Qt.darker(neoButton.color,1.7)
property string image
property color fontColor
property int fontSize:70
property int layout:2
property string text:"Button"
clip: true
id:neoButton
width: 300
height: 160
x:50
y:50
border.color : "black"
border.width: 1
radius: 5
Rectangle
anchors.horizontalCenter: parent.horizontalCenter
anchors.verticalCenter: parent.verticalCenter
implicitWidth:
if((neoButton.layout==0)||(neoButton.layout==1)||(neoButton.layout==4))
return Math.max(buttonLabel.implicitWidth, buttonImage.implicitWidth)
else
return buttonLabel.implicitWidth+buttonImage.implicitWidth
implicitHeight:
if((neoButton.layout==0)||(neoButton.layout==1))
return buttonLabel.implicitHeight + buttonImage.implicitHeight
else
return Math.max(buttonLabel.implicitHeight, buttonImage.implicitHeight)
color: "blue"
Image
id:buttonImage
anchors.horizontalCenter:
if((neoButton.layout==0)||(neoButton.layout==1)||(neoButton.layout==4))
console.log("Image horizontalCenter:parent.horizontalCenter" )
return parent.horizontalCenter
else
console.log("Image horizontalCenter:undefined" )
return undefined
anchors.verticalCenter:
if((neoButton.layout==2)||(neoButton.layout==3)||(neoButton.layout==4))
console.log("Image verticalCenter:parent.verticalCenter" )
return parent.verticalCenter
else
console.log("Image verticalCenter:undefined" )
return undefined
source:"file:///D:/QT Projects/build-PutCppAndQmlTogether-Desktop_Qt_5_1_1_MinGW_32bit-Debug/MyTempFiles/Images/B_0_0_0.png"
anchors.top:
if(neoButton.layout == 1)
console.log("Image top:buttonLabel.bottom" )
return buttonLabel.bottom
else if(neoButton.layout == 0)
console.log("Image top:parent.top" )
return parent.top
else
console.log("Image top:undefined" )
return undefined
anchors.left:
if(neoButton.layout == 3)
return buttonLabel.right
else if(neoButton.layout == 2)
return parent.left
else
return undefined
Text
id: buttonLabel
font.pixelSize:20
anchors.horizontalCenter:
if((neoButton.layout==0)||(neoButton.layout==1)||(neoButton.layout==4))
return parent.horizontalCenter
else
return undefined
anchors.verticalCenter:
if((neoButton.layout==2)||(neoButton.layout==3)||(neoButton.layout==4))
return parent.verticalCenter
else
return undefined
anchors.top:
if(neoButton.layout == 0)
return buttonImage.bottom
else if(neoButton.layout == 1)
return parent.top
else
return undefined
anchors.left:
if(neoButton.layout == 2)
return buttonImage.right
else if(neoButton.layout == 3)
return parent.left
else
return undefined
text: neoButton.text
signal buttonClick()
onButtonClick:
console.log(buttonLabel.text + " clicked" )
layout=2
MouseArea
id:buttonMouseArea
anchors.fill: parent
onClicked: parent.buttonClick()
hoverEnabled: true
onEntered:
parent.border.width= 2
onCanceled:
parent.border.width= 1
onExited:
parent.border.width= 1
gradient: buttonMouseArea.pressed ? myDarkyGradient : myGradient
【问题讨论】:
【参考方案1】:如果再添加一些调试输出,可以观察属性变化的顺序,然后设置一个新的layout
。
示例 0 -> 2
/* Console log output
'Text Button' clicked: Change layout 0 to 2
Label horizontalCenter: undefined
Label verticalCenter: parent.verticalCenter
Label top: undefined
Label left: buttonImage.right
Image horizontalCenter:undefined
Image verticalCenter:parent.verticalCenter
Image top: undefined
Image left: parent.left
Rectangle implicitWidth: Sum
Rectangle implicitHeight: Max
*/
这意味着最后重新计算外部矩形。因此,所有其他对齐都相对于旧矩形发生。
要重置锚点,我会实现自动生成的函数“onLayoutChanged”:
onLayoutChanged:
console.log("Layout changed to new id: " + layout + ". Time to reset alignments using javascript")
switch(layout)
case 0:
// do stuff
break;
case 1:
// do stuff
break;
case 2:
// do stuff
break;
case 3:
// do stuff
break;
case 4:
// do stuff
break;
default:
console.log("Invalid layout id.")
break;
【讨论】:
谢谢,这比我做的要好得多。但是在初始化按钮时不会调用此方法。最好的方法是什么? 将逻辑导出到新的 JavaScript 函数setLayout(layoutId)
并从 onLayoutChanged
和 Component.onCompleted
调用它(参见 qt-project.org/doc/qt-5.0/qtqml/…)。
现在它可以工作了,我只需要在设置新的锚之前清除以前的锚。非常感谢。以上是关于QT QML 自定义按钮 - 动态改变文本和图像的相对位置的主要内容,如果未能解决你的问题,请参考以下文章
使用 Qt.createQmlObject() 创建自定义 qml 对象实例
Qt5 / PyQt5 : 带有 QML 前端和 Python 后端的自定义 QML 组件
BlackBerry Cascades 中的 QML 字符串