QML图标文字按钮

本文介绍如何在QML中创建一个结合了图标和文字的按钮组件,IconTextButton.qml提供了这种功能,使得在Qt应用的用户界面设计中能够更直观地展示操作选项。
摘要由CSDN通过智能技术生成

在这里插入图片描述
IconTextButton.qml

import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
import "../../js/Helper.js" as Helper

Rectangle {
  id: control
  width: 80
  height: 24
  radius: 12

  property bool isHorizontalCenter: false
  property bool checked: false
  property color defaultColor: "#444346"
  property color hoverColor: "#565558"
  property color pressedColor: "#68676A"
  property color checkedColor: "#68676A"
  property color disabledColor: "#444346"
  property color checkedHoverColor: "#68676A"
  property color checkedPressedColor: "#68676A"
  property color checkedDisabledColor: "#68676A"
  //在组件外部单独使用 Color 或 Gradient
  property var defaultGradient: Gradient {}
  property var hoverGradient: Gradient {}
  property var pressedGradient: Gradient {}
  property var checkedGradient: Gradient {}
  property var disabledGradient: Gradient {}
  property var checkedHoverGradient: Gradient {}
  property var checkedPressedGradient: Gradient {}
  property var checkedDisabledGradient: Gradient {}
  property color textDefaultColor: "#FFFFFF"
  property color textHoverColor: "#FFFFFF"
  property color textPressedColor: "#FFFFFF"
  property color textCheckedColor: "#FFFFFF"
  property color textDisabledColor: "#8F8E91"
  property color textCheckedHoverColor: "#FFFFFF"
  property color textCheckedPressedColor: "#FFFFFF"
  property color textCheckedDisabledColor: "#FFFFFF"
  property url iconsource: "qrc:/qmldemo.com/avkit/assets/icon24_thumbnail.png"

  property alias iconWidth: icon.width
  property alias iconHeight: icon.height
  property alias iconLeftMargin: iconLeftMargin.width
  property alias iconAndTextSpacing: row.spacing
  property alias text: titleText.text
  property alias textPointSize: titleText.font.pointSize
  property alias mouseArea: controlMouseArea

  Component.onCompleted: {
    defaultColor = color
    iconLeftMargin = isHorizontalCenter ? 0 - row.spacing : iconLeftMargin - row.spacing
  }

  state: enabled ? (checked ? "CHECKED" : "DEFAULT") : "DISABLED"
  states: [
    State{
      name: "DEFAULT"
      PropertyChanges {
        control {
          color: checked ? checkedColor : defaultColor
          gradient: checked ? checkedGradient : defaultGradient
        }
        titleText {
          color: checked ? textCheckedColor : textDefaultColor
        }
        icon {
          source: checked ? Helper.fileFullPathReNameExt(iconsource.toString(), "_checked") : iconsource
        }
      }
    },
    State{
      name: "HOVER"
      PropertyChanges {
        control {
          color: checked ? checkedHoverColor : hoverColor
          gradient: checked ? checkedHoverGradient : hoverGradient
        }
        titleText {
          color: checked ? textCheckedHoverColor : textHoverColor
        }
        icon {
          source: checked ? Helper.fileFullPathReNameExt(iconsource.toString(), "_checked_hover") : Helper.fileFullPathReNameExt(iconsource.toString(), "_hover")
        }
      }
    },
    State{
      name: "PRESSED"
      PropertyChanges {
        control {
          color: checked ? checkedPressedColor : pressedColor
          gradient: checked ? checkedPressedGradient : pressedGradient
        }
        titleText {
          color: checked ? textCheckedPressedColor : textPressedColor
        }
        icon {
          source: checked ? Helper.fileFullPathReNameExt(iconsource.toString(), "_checked_pressed") : Helper.fileFullPathReNameExt(iconsource.toString(), "_pressed")
        }
      }
    },
    State{
      name: "DISABLED"
      PropertyChanges {
        control {
          color: checked ? checkedDisabledColor : disabledColor
          gradient: checked ? checkedDisabledGradient : disabledGradient
        }
        titleText {
          color: checked ? textCheckedDisabledColor : textDisabledColor
        }
        icon {
          source: checked ? Helper.fileFullPathReNameExt(iconsource.toString(), "_checked_disabled") : Helper.fileFullPathReNameExt(iconsource.toString(), "_disabled")
        }
      }
    },
    State{
      name: "CHECKED"
      PropertyChanges {
        control {
          color: checkedColor
          gradient: checkedGradient
        }
        titleText {
          color: textCheckedColor
        }
        icon {
          source: Helper.fileFullPathReNameExt(iconsource.toString(), "_checked")
        }
      }
    }
  ]

  Rectangle {
    color: "transparent"
    anchors.fill: isHorizontalCenter ? undefined : parent
    anchors.centerIn: isHorizontalCenter ? parent : undefined
    height: icon.height
    width: icon.width + titleText.width + row.spacing

    Row{
      id: row
      anchors.fill: parent
      spacing: 2
      Text {
        id:iconLeftMargin
      }
      Image {
        id: icon
        width: 24
        height: 24
        fillMode: Image.Tile
        horizontalAlignment: Image.AlignLeft
        verticalAlignment: Image.AlignTop
        anchors.verticalCenter: parent.verticalCenter
        onStatusChanged: {
          if (status === Image.Error) {
            source = iconsource
          }
        }
      }
      Text {
        id: titleText
        anchors.verticalCenter: parent.verticalCenter
        text: qsTr("my text")
        font.pointSize: 10
      }
    }
  }

  MouseArea {
    id: controlMouseArea
    anchors.fill: parent
    enabled: control.enabled
    hoverEnabled: true
    onPressed: {
      control.state = "PRESSED"
    }
    onEntered: {
      control.state = "HOVER"
    }
    onExited: {
      control.state = "DEFAULT"
    }
  }
}

function fileFullPathReNameExt(fileFullPath, nameExt) {
  var fileName = fileFullPath.split("/").pop()
  var fileExt = fileName.split(".").pop()
  var fileWithoutExt = fileName.slice(0, -fileExt.length - 1)
  var lastSlashIndex = fileFullPath.lastIndexOf("/")
  var path = fileFullPath.substring(0, lastSlashIndex)
  var newFileFullPath = path + "/" + fileWithoutExt + nameExt + "." + fileExt
  return newFileFullPath
}
      IconTextButton {
        id: goHome
        width: 80
        height: 24
        radius: 12
        antialiasing: true
        text: "Home"
        defaultColor: "#272C37"
        iconLeftMargin: 5
        anchors.verticalCenter: parent.verticalCenter
        anchors.right: parent.right
        anchors.rightMargin: 175
        hoverColor: "#2B313F"
        pressedColor: "#272C37"
        visible: mainBodyTabPage.currentIndex != 0
        mouseArea {
          onClicked: {
            mainBodyTabPage.currentIndex = 0
          }
        }
      }
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
import "../../js/Helper.js" as Helper

Rectangle {
  id: control
  width: 80
  height: 24
  radius: 12

  property bool checked: false
  property bool isVertical: false
  property bool isInversion: false
  property url iconSource: ""
  property real iconTextSpacing: 2
  property alias text: rowtitletext
  property alias verticalText: columntitletext
  property alias mouseArea: controlMouseArea
  property alias baseColor: bc

  Component.onCompleted: {
    if(iconSource === "" || (rowtitletext.text === "" && !isVertical) || (columntitletext.text === "" && isVertical))
      iconTextSpacing = 0
  }

  BaseColor {
    id: bc
  }

  state: enabled ? (checked ? "CHECKED" : "DEFAULT") : "DISABLED"
  states: [
    State{
      name: "DEFAULT"
      PropertyChanges {
        control {
          color: checked ? bc.checkedColor : bc.defaultColor
          border.color: checked ? bc.borderCheckedColor : bc.borderDefaultColor
          gradient: checked ? bc.checkedGradient : bc.defaultGradient
        }
        rowtitletext {
          color: checked ? bc.textCheckedColor : bc.textDefaultColor
        }
        columntitletext {
          color: checked ? bc.textCheckedColor : bc.textDefaultColor
        }
        rowicon {
          source: checked ? Helper.fileFullPathReNameExt(iconSource.toString(), "_checked") : iconSource
        }
        columnicon {
          source: checked ? Helper.fileFullPathReNameExt(iconSource.toString(), "_checked") : iconSource
        }
      }
    },
    State{
      name: "HOVER"
      PropertyChanges {
        control {
          color: checked ? bc.checkedHoverColor : bc.hoverColor
          border.color: checked ? bc.borderCheckedHoverColor : bc.borderHoverColor
          gradient: checked ? bc.checkedHoverGradient : bc.hoverGradient
        }
        rowtitletext {
          color: checked ? bc.textCheckedHoverColor : bc.textHoverColor
        }
        columntitletext {
          color: checked ? bc.textCheckedHoverColor : bc.textHoverColor
        }
        rowicon {
          source: checked ? Helper.fileFullPathReNameExt(iconSource.toString(), "_checked_hover") : Helper.fileFullPathReNameExt(iconSource.toString(), "_hover")
        }
        columnicon {
          source: checked ? Helper.fileFullPathReNameExt(iconSource.toString(), "_checked_hover") : Helper.fileFullPathReNameExt(iconSource.toString(), "_hover")
        }
      }
    },
    State{
      name: "PRESSED"
      PropertyChanges {
        control {
          color: checked ? bc.checkedPressedColor : bc.pressedColor
          border.color: checked ? bc.borderCheckedPresseColor : bc.borderPresseColor
          gradient: checked ? bc.checkedPressedGradient : bc.pressedGradient
        }
        rowtitletext {
          color: checked ? bc.textCheckedPressedColor : bc.textPressedColor
        }
        columntitletext {
          color: checked ? bc.textCheckedPressedColor : bc.textPressedColor
        }
        rowicon {
          source: checked ? Helper.fileFullPathReNameExt(iconSource.toString(), "_checked_pressed") : Helper.fileFullPathReNameExt(iconSource.toString(), "_pressed")
        }
        columnicon {
          source: checked ? Helper.fileFullPathReNameExt(iconSource.toString(), "_checked_pressed") : Helper.fileFullPathReNameExt(iconSource.toString(), "_pressed")
        }
      }
    },
    State{
      name: "DISABLED"
      PropertyChanges {
        control {
          color: checked ? bc.checkedDisabledColor : bc.disabledColor
          border.color: checked ? bc.borderCheckedDisabledColor : bc.borderDisabledColor
          gradient: checked ? bc.checkedDisabledGradient : bc.disabledGradient
        }
        rowtitletext {
          color: checked ? bc.textCheckedDisabledColor : bc.textDisabledColor
        }
        columntitletext {
          color: checked ? bc.textCheckedDisabledColor : bc.textDisabledColor
        }
        rowicon {
          source: checked ? Helper.fileFullPathReNameExt(iconSource.toString(), "_checked_disabled") : Helper.fileFullPathReNameExt(iconSource.toString(), "_disabled")
        }
        columnicon {
          source: checked ? Helper.fileFullPathReNameExt(iconSource.toString(), "_checked_disabled") : Helper.fileFullPathReNameExt(iconSource.toString(), "_disabled")
        }
      }
    },
    State{
      name: "CHECKED"
      PropertyChanges {
        control {
          color: bc.checkedColor
          border.color: bc.borderCheckedColor
          gradient: bc.checkedGradient
        }
        rowtitletext {
          color: bc.textCheckedColor
        }
        columntitletext {
          color: bc.textCheckedColor
        }
        rowicon {
          source: Helper.fileFullPathReNameExt(iconSource.toString(), "_checked")
        }
        columnicon {
          source: Helper.fileFullPathReNameExt(iconSource.toString(), "_checked")
        }
      }
    }
  ]

  Item {
    anchors.centerIn: parent
    height: !isVertical ? (rowicon.height > rowtitletext.height ? rowicon.height : rowtitletext.height) : (columnicon.height + columntitletext.height + iconTextSpacing)
    width: !isVertical ? (rowicon.width + rowtitletext.width + iconTextSpacing) : (columnicon.width > columntitletext.width ? columnicon.width : columntitletext.width)
    Row {
      id: row
      anchors.fill: parent
      spacing: iconTextSpacing
      visible: !isVertical
      LayoutMirroring.enabled: isInversion
      Image {
        id: rowicon
        fillMode: Image.Tile
        horizontalAlignment: Image.AlignLeft
        verticalAlignment: Image.AlignTop
        anchors.verticalCenter: parent.verticalCenter
        onStatusChanged: {
          if (status === Image.Error) {
            source = iconSource
          }
        }
      }
      Text {
        id: rowtitletext
        anchors.verticalCenter: parent.verticalCenter
        text: ""
      }
    }
    ColumnLayout {
      id: column
      anchors.fill: parent
      spacing: iconTextSpacing
      visible: isVertical
      LayoutMirroring.enabled: true
      Image {
        id: columnicon
        fillMode: Image.Tile
        horizontalAlignment: Image.AlignLeft
        verticalAlignment: Image.AlignTop
        anchors.horizontalCenter: parent.horizontalCenter
        onStatusChanged: {
          if (status === Image.Error) {
            source = iconSource
          }
        }
        // Layout.alignment: Qt.AlignBottom
      }
      Text {
        id: columntitletext
        anchors.horizontalCenter: parent.horizontalCenter
        text: ""
        // Layout.alignment: Qt.AlignBottom
      }
    }
  }

  MouseArea {
    id: controlMouseArea
    anchors.fill: parent
    enabled: control.enabled
    hoverEnabled: true
    onPressed: {
      control.state = "PRESSED"
    }
    onEntered: {
      control.state = "HOVER"
    }
    onExited: {
      control.state = "DEFAULT"
    }
  }

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值