QT 重写控件(QPushButton为例)实现背景图片的切换和鼠标样式切换

简介: 一般在QT开发中,使用setCursor()给控件设置鼠标的样式效果(一般是手型和箭头的切换),一般情况下,这个函数也是起作用的,但是一旦调用了全局QApplication::setOverrideCursor()设置鼠标效果后,在使用setCursor给控件设置鼠标样式就不起效果了,这是QT的机制

设置鼠标样式不起作用的可能原因

一般在QT开发中,使用setCursor()给控件设置鼠标的样式效果(一般是手型和箭头的切换),一般情况下,这个函数也是起作用的,但是一旦调用了全局QApplication::setOverrideCursor()设置鼠标效果后,在使用setCursor给控件设置鼠标样式就不起效果了,这是QT的机制


解决思路

目前能想到的一种解决思路就是重写控件,并重写控件鼠标的相关事件,下面以重写QPushButton为例,当然代码是从网上找的,Qt自定义按钮及不同状态下图片的切换,我参考该博客是为了实现按钮背景图片的切换,发现使用该博客,在我的电脑上会出现有的按钮进入时,会同时触发进入事件和离开事件,目前还不知道原因,所以就没使用该博客绘制按钮的图片,还是老老实实的使用setStyleSheet来设置按钮的背景图片的样式,以下是修改后的代码(注释的相关代码是设置背景图片的,我没有****用),这里还是感谢该博主提供的思路

头文件

#ifndef QTXPUSHBUTTON_H
#define QTXPUSHBUTTON_H
#include <QPushButton>
//有的按钮进入按钮时,会同时触发进入事件和离开事件,暂时不知道啥原因(BUG),图片样式使用样式表设置
//不在各个事件里设置图片,目前只用于设置鼠标样式
class QtXPushButton : public QPushButton
{
    Q_OBJECT
public:
    enum XBUTTONSTATE
    {
        NORMAL = 0X01,//正常状态
        HOVER = 0X02,//鼠标滑过状态
        SELECTED = 0X04,//选中状态
        DISABLE = 0X08//禁止点击状态
    };
    QtXPushButton(QString strImagePath="", QWidget *parent = nullptr);
    ~QtXPushButton();
    //设置正常图标
    void SetNormalPixmap(QString strImagePath);
    //设置鼠标滑动图片
    void SetHoverPixmap(QString strImagePath);
    //设置选中状态图片
    void SetSelectedPixmap(QString strImagePath);
    //设置禁止点击图标
    void SetDisablePixmap(QString strImagePath);
    //设置按钮当前状态
    void SetBtnState(XBUTTONSTATE state);
    //设置图片大小
    void SetSize(QSize sz);
protected:
    virtual void paintEvent(QPaintEvent *event);
    virtual void enterEvent(QEvent *event);
    virtual void mouseReleaseEvent(QMouseEvent *event);
    virtual void mousePressEvent(QMouseEvent *event);
    virtual void leaveEvent(QEvent *event);
private:
    QtXPushButton(const QtXPushButton& btn);
    QtXPushButton& operator=(const QtXPushButton& btn);
private:
    QPixmap m_NormalPix;//正常图标
    QPixmap m_HoverPix;//鼠标滑动图标
    QPixmap m_SelectedPix;//选中状态图标
    QPixmap m_DisablePix;//禁止点击图标
    //包含1则启动正常图标,包含2启用滑动图标,
    //包含4启用选中状态图标,包含8启用禁止点击图标,默认标为1.
    int m_iMask;
    XBUTTONSTATE m_curState;//当前状态
    XBUTTONSTATE m_lastState;//上一次状态
};
#endif // QTXPUSHBUTTON_H

cpp

#include <QBitmap>
#include <QPainter>
#include <QDebug>
#include <QStyleOption>
#include <QApplication>
#include "qtxpushbutton.h"
QtXPushButton::QtXPushButton(QString strImagePath, QWidget *parent)
    :QPushButton(parent)
{
    //    m_NormalPix.load(strImagePath);
    //    setFixedSize(m_NormalPix.size());
    //    setMask(QBitmap(m_NormalPix.mask()));
    //    m_iMask = XBUTTONSTATE::NORMAL;
    //    m_curState = XBUTTONSTATE::NORMAL;
    //    m_lastState = XBUTTONSTATE::NORMAL;
}
QtXPushButton::~QtXPushButton()
{
}
void QtXPushButton::SetNormalPixmap(QString strImagePath)
{
    m_NormalPix.load(strImagePath);
    m_iMask |= XBUTTONSTATE::NORMAL;
}
void QtXPushButton::SetHoverPixmap(QString strImagePath)
{
    m_HoverPix.load(strImagePath);
    m_iMask |= XBUTTONSTATE::HOVER;
}
void QtXPushButton::SetSelectedPixmap(QString strImagePath)
{
    m_SelectedPix.load(strImagePath);
    m_iMask |= XBUTTONSTATE::SELECTED;
}
void QtXPushButton::SetDisablePixmap(QString strImagePath)
{
    m_DisablePix.load(strImagePath);
    m_iMask |= XBUTTONSTATE::DISABLE;
}
void QtXPushButton::SetBtnState(QtXPushButton::XBUTTONSTATE state)
{
    m_lastState = m_curState;
    m_curState = state;
}
void QtXPushButton::SetSize(QSize sz)
{
    m_NormalPix = m_NormalPix.scaled(sz);
    int iValue = m_iMask&XBUTTONSTATE::HOVER;
    if (iValue != 0)
    {
        m_HoverPix = m_HoverPix.scaled(sz);
    }
    iValue = m_iMask&XBUTTONSTATE::SELECTED;
    if (iValue != 0)
    {
        m_SelectedPix = m_SelectedPix.scaled(sz);
    }
    iValue = m_iMask&XBUTTONSTATE::DISABLE;
    if (iValue != 0)
    {
        m_DisablePix = m_DisablePix.scaled(sz);
    }
}
void QtXPushButton::paintEvent(QPaintEvent *event)
{
    //需要在paintEvent添加以下代码,否则设置按钮的样式表不起效果
    QStyleOption o;
    o.initFrom(this);
    QPainter p(this);
    style()->drawPrimitive(QStyle::PE_Widget, &o, &p, this);
    //    QPixmap drawPix;
    //    if (m_curState == XBUTTONSTATE::NORMAL)
    //    {
    //        drawPix = m_NormalPix;
    //    }
    //    else if (m_curState == XBUTTONSTATE::HOVER)
    //    {
    //        int iValue = m_iMask&XBUTTONSTATE::HOVER;
    //        drawPix = (0 == iValue) ? m_NormalPix : m_HoverPix;
    //    }
    //    else if (m_curState == XBUTTONSTATE::SELECTED)
    //    {
    //        int iValue = m_iMask&XBUTTONSTATE::SELECTED;
    //        drawPix = (0 == iValue) ? m_NormalPix : m_SelectedPix;
    //    }
    //    else if (m_curState == XBUTTONSTATE::DISABLE)
    //    {
    //        int iValue = m_iMask&XBUTTONSTATE::DISABLE;
    //        drawPix = (0 == iValue) ? m_NormalPix : m_DisablePix;
    //    }
    //    QPainter painter(this);
    //    painter.drawPixmap(0, 0, drawPix);
}
void QtXPushButton::enterEvent(QEvent *event)
{
    QApplication::setOverrideCursor(Qt::PointingHandCursor);
    //    SetBtnState(XBUTTONSTATE::HOVER);
    QPushButton::enterEvent(event);
    //    update();
}
void QtXPushButton::mouseReleaseEvent(QMouseEvent *event)
{
    QApplication::setOverrideCursor(Qt::ArrowCursor);
    //    m_curState =XBUTTONSTATE::NORMAL;
    QPushButton::mouseReleaseEvent(event);
    //    update();
}
void QtXPushButton::mousePressEvent(QMouseEvent *event)
{
    QApplication::setOverrideCursor(Qt::PointingHandCursor);
    //   SetBtnState(XBUTTONSTATE::SELECTED);
    QPushButton::mousePressEvent(event);
    //   update();
}
void QtXPushButton::leaveEvent(QEvent *event)
{
    QApplication::setOverrideCursor(Qt::ArrowCursor);
    //    m_curState =XBUTTONSTATE::NORMAL;
    QPushButton::leaveEvent(event);
    //    update();
}
QtXPushButton &QtXPushButton::operator=(const QtXPushButton &btn)
{
    return *this;
}

最后,如果大家有什么其他好的方式,也希望能留言,给博主一个建议,博主也是C++的新手


相关文章
|
29天前
|
计算机视觉 数据格式
使用opencv在Qt控件上播放mp4文件
使用opencv在Qt控件上播放mp4文件
29 2
|
2月前
|
算法 API C++
【Qt UI】QT 窗口/控件置顶方法详解
【Qt UI】QT 窗口/控件置顶方法详解
56 0
|
2月前
|
算法 前端开发 C++
【Qt UI相关】Qt设置窗体或控件的背景色透明
【Qt UI相关】Qt设置窗体或控件的背景色透明
22 0
|
2月前
|
存储 机器学习/深度学习 人工智能
Qt魔法书:打造自定义鼠标键盘脚本(二)
Qt魔法书:打造自定义鼠标键盘脚本
35 0
|
21天前
|
开发框架 数据可视化 前端开发
【Qt 学习笔记】Qt控件概述
【Qt 学习笔记】Qt控件概述
21 0
|
21天前
|
图形学 Python 容器
【PyQt5桌面应用开发】3.Qt Designer快速入门(控件详解)
【PyQt5桌面应用开发】3.Qt Designer快速入门(控件详解)
40 0
|
29天前
QT中edit控件限制输入数值以及进制转换方法
QT中edit控件限制输入数值以及进制转换方法
|
编译器 C语言 开发者
Qt Quick 常见控件与子控件布局规则
Qt Quick 常见控件与子控件布局规则
43 1
|
2月前
|
开发框架 Linux API
Qt魔法书:打造自定义鼠标键盘脚本(一)
Qt魔法书:打造自定义鼠标键盘脚本
23 0
|
3月前
|
容器
QT基础入门——界面布局和常用控件(四)
QT基础入门——界面布局和常用控件(四)
38 0
QT基础入门——界面布局和常用控件(四)

推荐镜像

更多