QT QML自定义按钮 - 动态更改文本和图像的相对位置

时间:2014-01-15 13:58:33

标签: qt qml qt5 qtquick2

在QML上创建的按钮上,需要动态更改图像和文本的相对位置。所以我创建了一个布局属性来改变这个位置。当我用任何位置初始化按钮时它工作正常,但是当我以编程方式更改位置时出现错误。

  • layout = 0:图片位于文字顶部
  • layout = 1:图片顶部的文字
  • layout = 2:图片右侧的文字
  • layout = 3:文字右侧的图片
  • layout = 4:图片前面的文字

当我将布局从0更改为1时,反之亦然,没有错误 当我将布局从2更改为3时,反之亦然,没有错误 如果我在任何布局更改之间将布局更改为5。当我将布局更改为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 个答案:

答案 0 :(得分:0)

如果添加更多调试输出,您可以观察属性更改的顺序,然后设置新的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;
    }
}