Qt 之 自定义按钮 在鼠标 悬浮、按下、松开后的效果--三种实现方式

7 篇文章 0 订阅
6 篇文章 0 订阅

简介

本文介绍了Qt中的按钮实现响应鼠标悬浮、按下、松开后的效果,在三种状态下,按钮改变不同的背景图片。

方式1:通过设置setStyleSheet的方式去实现;

方式2:通过继承QPushButton去实现一个自定义的按钮;

方式3:在主界面中给按钮安装事件过滤器的方式去实现

程序

方式1:通过设置setStyleSheet的方式去实现;

    QPushButton *pButton= new QPushButton();
    QString styleSheet = QString("QPushButton{background:url(%1); background-color:transparent;border: none; }"  //正常
            "QPushButton:hover{background:url(%2); background-color:transparent; }"  //滑过
            "QPushButton:pressed{background:url(%3); background-color:transparent; }") //按下
            .arg(":/icons/images/c1.png")
            .arg(":/icons/images/c.png")
            .arg(":/icons/images/暂停.png");
        pButton->setStyleSheet(styleSheet);

 

方式2:通过继承QPushButton去实现一个自定义的按钮;

继承QPushButton类后,重写了event()方法

bool MyPushButton::event(QEvent *event)
{
    switch (event->type())
    {
    case QEvent::Enter:
        this->setIcon(QIcon(":/icons/images/c.png"));
        break;
    case QEvent::Leave:
        this->setIcon(QIcon(":/icons/images/c1.png"));
        break;
    case QEvent::MouseButtonPress:
        this->setIcon(QIcon(":/icons/images/暂停.png"));
        break;
    case QEvent::MouseButtonRelease:
        this->setIcon(QIcon(":/icons/images/c1.png"));
        break;
    default:
        break;
    }
    return QPushButton::event(event);
}

方式3:在主界面中给按钮安装事件过滤器的方式去实现

bool MainWindow::eventFilter(QObject *obj, QEvent *event)
{
    switch (event->type()) {
    case QEvent::HoverEnter:
        if(obj == pButton_)
            pButton_->setIcon(QIcon(":/icons/images/c1.png"));
        break;
    case QEvent::HoverLeave:
        if(obj == pButton_)
            pButton_->setIcon(QIcon(":/icons/images/c.png"));
        break;
    case QEvent::MouseButtonPress:
        if(obj == pButton_)
            pButton_->setIcon(QIcon(":/icons/images/暂停.png"));
        break;
    case QEvent::MouseButtonRelease:
        if(obj == pButton_)
            pButton_->setIcon(QIcon(":/icons/images/c1.png"));
        break;
    default:
        break;
    }
    return QWidget::eventFilter(obj, event);
}

总结

三种方式都能实现一个按钮在悬浮、按下、松开后显示不同的背景图片的效果。其中第一种方式实现起来最为简单,如果仅仅是按钮外观的切换,采用该方法最为合理,符合MVC设计理念;第二种方法和第三种方式更具有灵活性,但难度也相对较大,这两种方法常用来实现一些更特殊的按钮操作。

源码

完整的演示源码

链接:https://pan.baidu.com/s/1dQBj0hNUcI3sQ1BnehWtVw?pwd=ptty 
提取码:ptty

  • 3
    点赞
  • 42
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
你可以通过继承QPushButton类,重写其鼠标事件函数,实现该功能。具体步骤如下: 1. 定义一个新的类,继承QPushButton类。 2. 在类中定义一个QRect对象,用于记录按钮边缘区域。 3. 重写鼠标进入和移动事件,判断鼠标是否位于按钮边缘区域,如果是则改变鼠标光标,并显示拉伸效果。 4. 重写鼠标按下和移动事件,判断鼠标是否处于拉伸状态,如果是则根据鼠标移动距离改变按钮大小。 5. 重写鼠标释放事件,结束拉伸状态。 下面给出一个简单的示例代码,实现了上述功能: ``` class ResizableButton : public QPushButton { public: ResizableButton(QWidget *parent = nullptr) : QPushButton(parent) { setCursor(Qt::ArrowCursor); } protected: void enterEvent(QEvent *event) override { QRect rect = edgeRect(); if (rect.contains(mapFromGlobal(QCursor::pos()))) { setCursor(Qt::SizeFDiagCursor); m_isResizing = true; } } void leaveEvent(QEvent *event) override { setCursor(Qt::ArrowCursor); m_isResizing = false; } void mousePressEvent(QMouseEvent *event) override { if (m_isResizing) m_startSize = size(); } void mouseMoveEvent(QMouseEvent *event) override { if (m_isResizing) { QSize delta = event->pos() - m_lastPos; QSize newSize = m_startSize + delta; setFixedSize(newSize); } m_lastPos = event->pos(); } void mouseReleaseEvent(QMouseEvent *event) override { m_isResizing = false; } private: QRect edgeRect() const { int margin = 5; QRect rect = rect().adjusted(margin, margin, -margin, -margin); rect.moveTopLeft(mapToGlobal(rect.topLeft())); return rect; } bool m_isResizing = false; QPoint m_lastPos; QSize m_startSize; }; ``` 在上述代码中,edgeRect()函数用于计算按钮边缘区域,m_isResizing、m_lastPos和m_startSize变量分别记录拉伸状态、鼠标最后位置和拉伸开始时的按钮大小。在鼠标移动事件中,根据鼠标移动距离计算新的按钮大小,并调用setFixedSize()函数设置大小。注意,这里使用setFixedSize()函数而不是resize()函数,是为了避免按钮大小超出边缘区域。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值