方法一:

描述:一开始我要实现的目的就是,在一个窗体上有多个可编辑控件(比如QLineEdit、QTextEdit等),当哪个控件获得焦点,哪个控件的背景就高亮用来起提示作用,查了下文档应该用focusInEvent()和focusOutEvent(), 在实际过程中,我犯了十分严重的错误,最开始的时候我是这样做的:我重写了窗体QWidget的这两个函数,然后再在函数体中把QFocusEvent事件传递给窗体上的QLineEdit控件:

void Widget::focusInEvent(QFocusEvent *event)
{QLineEdit::focusInEvent(event);.....
}

编译的时候报错,说是没有调用对象什么的,后来问了下朋友才得到了完美的答案:

既然是要控件得到焦点改变动作,则应该重写该控件的focusInEvent()和focusOutEvent(),即重写QLineEdit类,再重新定义这两个处理函数,然后再在主程序中,include 我们自己重写的QLineEdit头文件,具体代码如下:

// MYLINEEDIT_H
#ifndef MYLINEEDIT_H
#define MYLINEEDIT_H
#include <QLineEdit>
class MyLineEdit : public QLineEdit
{Q_OBJECTpublic:MyLineEdit(QWidget *parent=0);~MyLineEdit();protected:virtual void focusInEvent(QFocusEvent *e);virtual void focusOutEvent(QFocusEvent *e);
};
#endif // MYLINEEDIT_H
`//myLineEdit.cpp
#include "myLineEdit.h"MyLineEdit::MyLineEdit(QWidget *parent):QLineEdit(parent)
{}MyLineEdit::~MyLineEdit()
{}void MyLineEdit::focusInEvent(QFocusEvent *e)
{QPalette p=QPalette();p.setColor(QPalette::Base,Qt::green);    //QPalette::Base 对可编辑输入框有效,还有其他类型,具体的查看文档setPalette(p);
}void MyLineEdit::focusOutEvent(QFocusEvent *e)
{QPalette p1=QPalette();p1.setColor(QPalette::Base,Qt::white);setPalette(p1);
}//widget.cpp
#include "widget.h"
#include "ui_widget.h"
#include "MyLineEdit.h"
#include <QGridLayout>
#include <QMessageBox>
Widget::Widget(QWidget *parent) :QWidget(parent),ui(new Ui::Widget)
{ui->setupUi(this);init();
}
Widget::~Widget()
{delete ui;
}
void Widget::init()
{lineEdit1=new MyLineEdit(this);lineEdit2=new MyLineEdit(this);gridLayout=new QGridLayout;gridLayout->addWidget(lineEdit1,0,0);gridLayout->addWidget(lineEdit2,1,0);setLayout(gridLayout);
}

方法二:

前面实现了QLineEdit获得焦点高亮显示与失去焦点恢复原样的操作,是通过重新继承该类,再重构该事件函数的方式。这里要实现的功能也是一样的,而是通过另外不同的方式——事件过滤器(eventFilter)。

Qt的事件模型中提供的事件过滤功能使得一个QObject对象可以监视另一个QObject对象中的事件,通过在一个QObject对象中安装事件过滤器可以在事件到达该对象前捕获事件,从而起到监视该对象事件的效果。

实现类似功能的另一种方式是通过分别继承不同的控件类,并重构各控件的事件响应函数,但若窗体中包含大量不同的控件时,每一个控件都必须重新继承,然后分别重构不同的事件函数,实现比较复杂。事件过滤器可以实现在窗体中监视全部控件的不同事件,方便实现功能扩展。

#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
namespace Ui {
class Widget;
}
class Widget : public QWidget
{Q_OBJECTpublic:explicit Widget(QWidget *parent = 0);~Widget();public slots:bool eventFilter(QObject *,QEvent *);    //注意这里private:Ui::Widget *ui;
};
#endif // WIDGET_H
`#include "widget.h"
#include "ui_widget.h"
#include <QPalette>
Widget::Widget(QWidget *parent) :QWidget(parent),ui(new Ui::Widget)
{ui->setupUi(this);ui->lineEdit1->installEventFilter(this);  //在窗体上为lineEdit1安装过滤器ui->lineEdit2->installEventFilter(this);  //在窗体上为lineEdit2安装过滤器
}Widget::~Widget()
{delete ui;
}bool Widget::eventFilter(QObject *watched, QEvent *event)
{if (watched==ui->lineEdit1)         //首先判断控件(这里指 lineEdit1){if (event->type()==QEvent::FocusIn)     //然后再判断控件的具体事件 (这里指获得焦点事件){QPalette p=QPalette();p.setColor(QPalette::Base,Qt::green);ui->lineEdit1->setPalette(p);}else if (event->type()==QEvent::FocusOut)    // 这里指 lineEdit1 控件的失去焦点事件{QPalette p=QPalette();p.setColor(QPalette::Base,Qt::white);ui->lineEdit1->setPalette(p);}}if (watched==ui->lineEdit2)           //这里来处理 lineEdit2 , 和处理lineEdit1 是一样的{if (event->type()==QEvent::FocusIn){QPalette p=QPalette();p.setColor(QPalette::Base,Qt::green);ui->lineEdit2->setPalette(p);}else if (event->type()==QEvent::FocusOut){QPalette p=QPalette();p.setColor(QPalette::Base,Qt::white);ui->lineEdit2->setPalette(p);}}return QWidget::eventFilter(watched,event);     // 最后将事件交给上层对话框
}

另外,我在一本书上看到作者有一个例子是关于动态按钮的:鼠标未按下时没有任何反应,当鼠标左键按下时图片变大,松开鼠标后又恢复原来的状态。其实这个效果和我这个例子是一个道理,也就是监听按钮的按下事件(QEvent::MouseButtonPress)和释放事件(QEvent::MouseButtonRelease)

bool EventFilter::eventFilter(QObject *watched,QEvent *event)
{if (watched==Label1){if (event->type()==QEvent::MouseButtonPress){QMouseEvent *mouseEvent=static_cast<QMouseEvent *>event;if (mouseEvent->buttons() && Qt::LeftButton){  // 更换一张大一点的图片    ..........}if (event->type()==QEvent::MouseButtonRelease){    // 重新换回最初那张图片 ...........}return QWidget::eventFilter(watched,event);
}

/**********************重写QPushbutton

设置鼠标样式不起作用的可能原因
一般在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;
}

Qt-Focus事件处理,重写qpushbutton实现背景切换鼠标样式及eventFilter的用法相关推荐

  1. QT重写QPushButton的背景图片及填充

    QT重写QPushButton的背景图片及填充 刚学习完QT的基本使用,使用已知知识重写QPushButton类 刚学习完QT的基本使用,使用已知知识重写QPushButton类 因为要使用QT来实现 ...

  2. Qt学习总结之QPushbutton详解

    一.简述 按钮,界面中常用的控件,默认矩形. QPushButton的子类:QCommandLinkButton 父类:QAbstractButton.QAbstractButton的父类是QWidg ...

  3. QtWidgets.QPushButton()设置背景图片

    目录 QPushButton使用setStyleSheet设置背景图片 和css一样设置setStyleSheet 转载:pyqt5实现按钮添加背景图片以及背景图片的切换 QPushButton使用s ...

  4. 纯CSS3模拟iPhone X背景切换动画

    尽管iPhone已经没有像以前那么火了,但是苹果的UI设计还是可以肯定的.今天我们要给大家分享一款基于纯CSS3的iPhone X背景切换动画,整体的切换动画以淡入淡出为主,iPhone X屏幕的背景 ...

  5. 【Scratch-外观模块】背景切换指令

    Scratch背景切换 指令解析 这个是针对我们舞台背景的外观模块指令,我们角色也是可以使用我们的这个指令改变我们的舞台背景 换成某个背景:舞台有多个背景时,使用之后会将我们的背景切换到我们指定的那个 ...

  6. js视频背景切换js特效代码

    下载地址 js视频背景切换特效代码,用缩略图控制网页全屏背景切换效果. dd:

  7. jQuery带背景切换登录注册表单

    jQuery带背景切换登录注册表单 原始HTML+CSS+JS页面设计,这是一个不错的登录网页制作,画面精明,非常适合初学者学习使用. 作品介绍 1.网页作品简介方面 :jQuery带背景切换登录注册 ...

  8. 基于QT的opencv照片美颜及背景更换

    基于QT的opencv照片美颜及背景更换 项目地址:QT美颜系统 一.软件架构 qt2.9.3 opencv3.4.16 二.安装教程 1.将opencv源文件中的cmake文件在qt中打开,通过ca ...

  9. QT tableWidget给单个表格添加背景颜色

    QT tableWidget给单个表格添加背景颜色 代码示例 QWidget *widget = new QWidget(); QString wStyle = QString("backg ...

最新文章

  1. JDBC编程专题4之JDBC驱动程序类型
  2. 计算机二级试题库office选择题,全国计算机二级MSoffice选择题题库2017
  3. JS函数浅析之constructor、prototype属性
  4. 从 npm 迁移至yarn
  5. java try catch_Java中关于try、catch、finally中的细节分析
  6. tomcat如何修改java版本_Java程序员必备——Tomcat配置技巧Top10
  7. HTML语言name,HTML a 标签的 name 属性
  8. leetcode 1723. 完成所有工作的最短时间(二分+剪枝+回溯)
  9. 脚踏实地,才能顶天立地!
  10. 下载虚拟化的mac 系统
  11. 嵌入式linux gif 缩放_嵌入式环境动力监控主机
  12. github的账号SSH设置
  13. ggplot2颜色设置
  14. vue的基础知识-vue基础入门
  15. 盖高辛氏衰,天下归之
  16. TortoiseHg的使用
  17. google api设计指南-简介
  18. 嵌入式知识框架之六-接口与总线(SPI\I2C\ USB\PCI\PCI-E\SD\SDIO\以太网接口)
  19. linux查看tomcat在,在陌生Linux环境查看Tomcat服务的方法
  20. 来到传统行业做程序员,从准备提桶跑路到引领技术风潮?背景

热门文章

  1. python将2个列表list合并到1个列表使用appenden_【新手入门】20个很实用的 Python 学习小技巧...
  2. python学习-元组的复习及进阶使用(iterable、indexing and slicing、sequence unpacking、immutable、named tuple)
  3. 福建省计算机学会 noip比赛,重磅!福州一三附学生领衔全省前九名!他们将代表福建参加全国比赛!...
  4. science图表_Science:组合图表绘制
  5. nfs服务器实现文件共享,NFS服务器及Samba服务配置实现文件共享(示例代码)
  6. c语言strchr的用法,C 库函数 - strchr()
  7. 后缀的形容词_高三语法总复习:名词形容词变名词的后缀
  8. no amd graphics driver怎么解决_《英雄联盟手游》卡顿怎么解决 游戏设置优化教程...
  9. mysql 缓存监控_MySql 缓存查询原理与缓存监控 和 索引监控
  10. Altium Designer 21 最全快捷键 分享 共1000多个|电子设计效率提高全靠它