商丘网站建设价格,在xampp下搭建本地网站,重庆专业网站推广报价,淘宝买模板注浆做网站一、场景
常常会需要实现点击/hover时修改图片#xff0c;可能是一个QPushButton、QLabel、QToolButton……
由于Qt bug#xff0c;QIcon/QSS只能实现常规态、按下态的图标切换#xff0c;hover态的图片设置无效。 解决思路无非是安装事件过滤器、自定义类并重实现事件。 …一、场景
常常会需要实现点击/hover时修改图片可能是一个QPushButton、QLabel、QToolButton……
由于Qt bugQIcon/QSS只能实现常规态、按下态的图标切换hover态的图片设置无效。 解决思路无非是安装事件过滤器、自定义类并重实现事件。
然而总要为这些鸡毛蒜皮的操作“小动干戈”会让人不爽。 这里选择更通用的类模板来简化操作。
二、实现说明 Q_OBJECT不能在类模板中使用导致我们不能在模板类中设置信号。不过也不是刚需上面的场景回调函数足够用了。 如果一定要使用信号那么就要用一个类来代理信号的发送。 比如下面定义了InteractiveSignalSender只用于发送信号。 绑定时信号发送者需要调getSignalSender() 注意只能通过组合的方式。如果通过多继承的方式例如让模板类继承QObject会出现重复继承QObject因为WidgetType也继承自QObjectQObject不支持多重继承会有问题。 如果需要在Qt Deigner中使用需要提升那么可以单独写个头文件来放入模板实例例如 // InteractivePushButton.h
#pragma once
#include interactiveTemplate.husing InteractivePushButton InteractiveQPushButton;然后添加该头文件选择提升为InteractivePushButton即可。
三、实现
使用例子
ui.btnFeedback-setEnterCallback([] { ui.btnFeedback-setIcon(QIcon(:/img/hover.png)); });
ui.btnFeedback-setLeaveCallback([] { ui.btnFeedback-setIcon(QIcon(:/img/simple.png)); });
ui.btnFeedback-setClickCallback([] { ui.btnFeedback-setIcon(QIcon(:/imgpressed.png)); });connect(ui.btnFeedback-signalSender(), InteractiveSignalSender::signalEnter, this, [] {});
模板实现如下 InteractiveTemplate.h
#pragma once#include QWidgetclass InteractiveSignalSender : public QObject {Q_OBJECT
public:explicit InteractiveSignalSender(QObject *parent) : QObject(parent){}Q_SIGNALS:void signalEnter();
Q_SIGNALS:void signalLeave();
};template typename WidgetType
class Interactive : public WidgetType {
public:explicit Interactive(QWidget *parent nullptr);void setEnterCallback(std::functionvoid() callback);void setLeaveCallback(std::functionvoid() callback);void setClickCallback(std::functionvoid() callback);InteractiveSignalSender *signalSender();protected:void mousePressEvent(QMouseEvent *event) override;void enterEvent(QEvent *event) override;void leaveEvent(QEvent *event) override;
private:std::functionvoid() m_enterCallback nullptr;std::functionvoid() m_leaveCallback nullptr;std::functionvoid() m_clickCallback nullptr;InteractiveSignalSender *m_signalSender new InteractiveSignalSender(this);static_assert(std::is_base_ofQWidget, WidgetType::value, WidgetType must be a QWidget);
};template typename WidgetType
InteractiveWidgetType::Interactive(QWidget *parent) : WidgetType(parent)
{
}template typename WidgetType
InteractiveSignalSender *
InteractiveWidgetType::signalSender()
{return m_signalSender;
}template typename WidgetType
void
InteractiveWidgetType::setEnterCallback(std::functionvoid() callback)
{m_enterCallback callback;
}template typename WidgetType
void
InteractiveWidgetType::setLeaveCallback(std::functionvoid() callback)
{m_leaveCallback callback;
}template typename WidgetType
void
InteractiveWidgetType::setClickCallback(std::functionvoid() callback)
{m_clickCallback callback;
}template typename WidgetType
void
InteractiveWidgetType::mousePressEvent(QMouseEvent *event)
{if (m_clickCallback) {m_clickCallback();}WidgetType::mousePressEvent(event);
}template typename WidgetType
void
InteractiveWidgetType::enterEvent(QEvent *event)
{emit m_signalSender-signalEnter();if (m_enterCallback) {m_enterCallback();}WidgetType::enterEvent(event);
}template typename WidgetType
void
InteractiveWidgetType::leaveEvent(QEvent *event)
{emit m_signalSender-signalLeave();if (m_leaveCallback) {m_leaveCallback();}WidgetType::leaveEvent(event);
}