QML编写自定义控件:自定义按钮

从0开始自定义一个按钮,按钮应该有如下功能:

1、按钮上有文字、按下时文字要有下沉的效果

2、按钮有交互效果,悬浮、按下按钮的颜色要变化

3、可以设置说明文字

4、按钮按下会发出信号

下面依次来实现

首先选择Rectangle作为按钮的区域,也可以用Item,不过Item没有颜色属性,还要在Item下面套一个Rectangle。设置圆角为6

给区域加上鼠标区域,并根据鼠标是否进入按钮区域、鼠标是否按下来设置区域的不同颜色

import QtQuick 2.0
import QtQuick.Controls 2.2

Rectangle
{
    id:root
    width:400
    height:50
    radius:6
    color: rect_mouse.pressed ? "#01968c" : (rect_mouse.containsMouse ? "#20c9b3" : "#00beac")

    MouseArea
    {
        id:rect_mouse
        anchors.fill: parent
        hoverEnabled: true //是否处理悬浮事件,默认false,只有按下鼠标键时才处理鼠标事件,为true时即使没有按下鼠标键也会作相应的处理
        preventStealing:true//默认为false,为true时可以防止当前鼠标事件被其它对象拦截。
        propagateComposedEvents:true//默认为 false,当设置为 true 时,就可以将事件传递给重叠的其他鼠标区域了
        enabled: true
        cursorShape: Qt.PointingHandCursor//鼠标进入区域鼠标指针变成手型
    }
}

 功能2实现了,下面再加上一标签用来放按文字

import QtQuick 2.0
import QtQuick.Controls 2.2

Rectangle
{
    id:root
    width:400
    height:50
    radius:6
    color: rect_mouse.pressed ? "#01968c" : (rect_mouse.containsMouse ? "#20c9b3" : "#00beac")
    property alias text:rect_text.text

    Text
    {
        id:rect_text
        font.pointSize: 16
        font.bold: true
        color:"#ffffff"
        anchors.horizontalCenter:parent.horizontalCenter
        anchors.verticalCenter: parent.verticalCenter
        anchors.verticalCenterOffset: 0
    }

    MouseArea
    {
        id:rect_mouse
        anchors.fill: parent
        hoverEnabled: true //是否处理悬浮事件,默认false,只有按下鼠标键时才处理鼠标事件,为true时即使没有按下鼠标键也会作相应的处理
        preventStealing:true//默认为false,为true时可以防止当前鼠标事件被其它对象拦截。
        propagateComposedEvents:true//默认为 false,当设置为 true 时,就可以将事件传递给重叠的其他鼠标区域了
        enabled: true
        cursorShape: Qt.PointingHandCursor//鼠标进入区域鼠标指针变成手型
    }
}

文字居于按钮中央,给标签起个别名property alias text:rect_text.text,这样在外部设置text的属性就可以修改按钮的文字

下面加上按下按钮时文字的下沉效果

import QtQuick 2.0
import QtQuick.Controls 2.2

Rectangle
{
    id:root
    width:400
    height:50
    radius:6
    property alias text:rect_text.text
    color: rect_mouse.pressed ? "#01968c" : (rect_mouse.containsMouse ? "#20c9b3" : "#00beac")

    Text
    {
        id:rect_text
        font.pointSize: 16
        font.bold: true
        color:"#ffffff"
        anchors.horizontalCenter:parent.horizontalCenter
        anchors.verticalCenter: parent.verticalCenter
        anchors.verticalCenterOffset: 0
    }

    MouseArea
    {
        id:rect_mouse
        anchors.fill: parent
        hoverEnabled: true //是否处理悬浮事件,默认false,只有按下鼠标键时才处理鼠标事件,为true时即使没有按下鼠标键也会作相应的处理
        preventStealing:true//默认为false,为true时可以防止当前鼠标事件被其它对象拦截。
        propagateComposedEvents:true//默认为 false,当设置为 true 时,就可以将事件传递给重叠的其他鼠标区域了
        enabled: true
        cursorShape: Qt.PointingHandCursor

        onPressed:
        {
            rect_text.anchors.verticalCenterOffset = 5
        }

        onReleased:
        {
            rect_text.anchors.verticalCenterOffset = 0
        }
    }
}

 当鼠标按下时将文字垂直向下移动一点,松开时恢复就可以得到下沉效果

 然后是按钮的说明文字,即鼠标移动到按钮上时,显示出按钮的说明文字,这个可用用现成的ToolTip组件

    ToolTip
    {
        id:btn_tip
        font.pointSize: 14
        delay: 500
        timeout: 2000
        x:parent.width/2
        y:parent.height
    }

最后定义一个信号,当按钮按下时发出这个信号,外部调用时关联这个信号即可,要注意信号要小写字母开头

完整代码:

import QtQuick 2.0
import QtQuick.Controls 2.2

Rectangle
{
    id:root
    width:400
    height:50
    radius:6
    property alias text:rect_text.text
    property alias tip_text:btn_tip.text
    color: rect_mouse.pressed ? "#01968c" : (rect_mouse.containsMouse ? "#20c9b3" : "#00beac")

    signal btnclicked

    Text
    {
        id:rect_text
        font.pointSize: 16
        font.bold: true
        color:"#ffffff"
        anchors.horizontalCenter:parent.horizontalCenter
        anchors.verticalCenter: parent.verticalCenter
        anchors.verticalCenterOffset: 0
    }

    ToolTip
    {
        id:btn_tip
        font.pointSize: 14
        delay: 500
        timeout: 2000
        x:parent.width/2
        y:parent.height
    }

    MouseArea
    {
        id:rect_mouse
        anchors.fill: parent
        hoverEnabled: true //是否处理悬浮事件,默认false,只有按下鼠标键时才处理鼠标事件,为true时即使没有按下鼠标键也会作相应的处理
        preventStealing:true//默认为false,为true时可以防止当前鼠标事件被其它对象拦截。
        propagateComposedEvents:true//默认为 false,当设置为 true 时,就可以将事件传递给重叠的其他鼠标区域了
        enabled: true
        cursorShape: Qt.PointingHandCursor

        onPressed:
        {
            rect_text.anchors.verticalCenterOffset = 5
        }

        onEntered:
        {
            if(btn_tip.text != "")
                btn_tip.open()
        }

        onReleased:
        {
            if(rect_mouse.containsMouse)//鼠标在按钮范围才有效
                root.btnclicked()

            rect_text.anchors.verticalCenterOffset = 0
        }

        onExited://鼠标离开时关闭
        {
            btn_tip.close()
        }
    }
}

测试:

    Button
    {
        text:"按钮测试"
        tip_text:"这是一个按钮"

        onBtnclicked://信号首字母大写
        {
            console.log("按钮被按下")
        }
    }

效果:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值