1.定义一个按钮类 : class ImageSwitch
首先我们需要定义它的 成员函数:
1. 按钮的样式 enum ButtonStyle (枚举来定义)公有的定义给私有成员使用
2.我们需要重写它的绘画功能 : void paintEvent(QPaintEvent *event);//重写绘画的功能
3.我们需要重写它的鼠标按下的功能 void mousePressEvent(QMouseEvent *);//重写鼠标按下事件
4.我们需要定义一些私有成员:
按键的现在的状态是开启还是关闭: bool isChecked
它自己的样式: ButtonStyle buttonStyle;
按键关闭的图片 :QString imgOffFile;
按键打开的图片:QString imgOnFile;
现在展示的图片是那张:QString imgFile;
5.因为是私有成员,所以我们需要设置 公有的函数来访问 私有成员
//设置按键 是否开启 void setChecked(bool isChecked);
//设置按钮样式 void setButtonStyle(const ImageSwitch::ButtonStyle &buttonStyle);
6.信号函数:传输按钮的状态!
void checkedChanged(bool checked);// 传输现在的按钮的状态 (鼠标点击之后)
2.ui->设计界面
还需要,把widget 继承按钮类 ImageSwitch
(点击 widget 右键 -- 》点击 提升为 )
3.资源文件的加载(按键的三种样式)
image (放到资源里面了 , 自己下载!!)!!
4.所有的代码:
imageswitch.h
#ifndef IMAGESWITCH_H
#define IMAGESWITCH_H
#include <QWidget>
//QT使用以下两个宏来实现符号(函数或全局变量/对象)的导出和导入(跨平台不能用def文件了):
//Q_DECL_EXPORT // 必须添加到符号声明中(共享库项目)
//Q_DECL_IMPORT // 必须添加到符号声明中(使用共享库的客户项目)
//QT使用 QLibrary 类实现共享库的动态加载,即在运行时决定加载那个DLL程序,插件机制使用
#ifdef quc
class Q_DECL_EXPORT ImageSwitch : public QWidget
#else
class ImageSwitch : public QWidget
#endif
{
Q_OBJECT
Q_ENUMS(ButtonStyle)
Q_PROPERTY(bool isChecked READ getChecked WRITE setChecked)
Q_PROPERTY(ButtonStyle buttonStyle READ getButtonStyle WRITE setButtonStyle)
public:
enum ButtonStyle {
ButtonStyle_1 = 0, //开关样式1
ButtonStyle_2 = 1, //开关样式2
ButtonStyle_3 = 2 //开关样式3
};
explicit ImageSwitch(QWidget *parent = 0);
protected:
void mousePressEvent(QMouseEvent *);//重写鼠标按下事件
void paintEvent(QPaintEvent *event);//重写绘画的功能
private:
bool isChecked;//表示状态 按钮的状态
ButtonStyle buttonStyle;
QString imgOffFile;//按键关闭的图片
QString imgOnFile;//按键打开的图片
QString imgFile;//现在展示的图片是那张
public:
bool getChecked() const;//访问私有成员 isChecked
ButtonStyle getButtonStyle() const;//访问私有成员 buttonStyle;
QSize sizeHint() const;//
QSize minimumSizeHint() const;//
public Q_SLOTS://槽函数
//设置是否选中
void setChecked(bool isChecked);
//设置按钮样式
void setButtonStyle(const ImageSwitch::ButtonStyle &buttonStyle);
Q_SIGNALS:
void checkedChanged(bool checked);// 传输现在的按钮的状态
};
#endif // IMAGESWITCH_H
widget.h
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
namespace Ui {
class Widget;
}
class Widget : public QWidget
{
Q_OBJECT
public:
explicit Widget(QWidget *parent = 0);
~Widget();
private:
Ui::Widget *ui;
private slots:
void initForm();
void checkedChanged(bool checked);
};
#endif // WIDGET_H
imageswitch.cpp
#pragma execution_character_set("utf-8")
#include "imageswitch.h"
#include "qpainter.h"
#include "qdebug.h"
ImageSwitch::ImageSwitch(QWidget *parent) : QWidget(parent)//构造函数
{
isChecked = false;//开始的时候默认按钮的状态为 关闭
buttonStyle = ButtonStyle_2;//默认按钮的样式为 样式2
imgOffFile = ":/image/imageswitch/btncheckoff2.png"; //开始默认 按钮关闭状态的图片 为 样式2 的图片
imgOnFile = ":/image/imageswitch/btncheckon2.png"; //开始默认 按钮开启状态的图片 为 样式2 的图片
imgFile = imgOffFile;
}
void ImageSwitch::mousePressEvent(QMouseEvent *)//重写鼠标按下的事件
{
imgFile = isChecked ? imgOffFile : imgOnFile; //判断语句 三目运算符 假如是开启状态将变成关闭状态 关闭状态变成开启状态 (鼠标按下改变状态)
isChecked = !isChecked;//赋值 把按键的状态改变 变成现在的状态
emit checkedChanged(isChecked);//发出信号 激发函数
this->update();//更新窗口
}
//paintEvent函数执行时间:
//1、在构建窗体的时候执行
//2、在窗体update的时候执行
//3、系统认为窗口需要重新绘制的时候执行
void ImageSwitch::paintEvent(QPaintEvent *)//重写绘画的功能
{
QPainter painter(this);//定义一个画家类 选择父亲
painter.setRenderHints(QPainter::SmoothPixmapTransform);//QPainter::SmoothPixmapTransform:使用平滑的pixmap变换算法(双线性插值算法
QImage img(imgFile);//顶一个图片的对象,加载图片
img = img.scaled(this->size(), Qt::KeepAspectRatio, Qt::SmoothTransformation);//,Qt::KeepAspectRatio是在给定的矩形中保持长宽比, 第一个参数是图片的大小
//按照比例自动居中绘制
int pixX = rect().center().x() - img.width() / 2;//图片居中
int pixY = rect().center().y() - img.height() / 2;//图片居中
QPoint point(pixX, pixY);//定义一个点 ,这个点的是图片的开始放置的顶点 左上角
painter.drawImage(point, img);//窗口放置图片
}
bool ImageSwitch::getChecked() const //获取私有成员 isChecked 的值
{
return isChecked;
}
// (解释这个成员函数的 类外定义)
//首先 ButtonStyle 这个枚举在类里面 所以 需要用到ImageSwitch::ButtonStyle
//然后才是 类里面的成员 定义 加类的名字
ImageSwitch::ButtonStyle ImageSwitch::getButtonStyle() const //获取 私有成员 buttonStyle 的值
{
return this->buttonStyle;
}
//QSize 类代表一个矩形区域的大小,实现在 QtCore 共享库中。它可以认为是由一个整型的宽度和整型的高度组合而成的。
QSize ImageSwitch::sizeHint() const//返回一个矩形区域的大小
{
return QSize(87, 28);//宽87 长28
}
QSize ImageSwitch::minimumSizeHint() const
{
return QSize(87, 28);
}
void ImageSwitch::setChecked(bool isChecked)//设置按键的状态 并且实时更新窗口的图片
{
if (this->isChecked != isChecked) {//假如现在按钮的状态 和参数的状态不同 就改变现在状态 变为参数的状态
this->isChecked = isChecked;
imgFile = isChecked ? imgOnFile : imgOffFile;//图片的确定
this->update();//更新窗口
}
}
void ImageSwitch::setButtonStyle(const ImageSwitch::ButtonStyle &buttonStyle)//设置样式
{
if (this->buttonStyle != buttonStyle) {
this->buttonStyle = buttonStyle;
if (buttonStyle == ButtonStyle_1) {
imgOffFile = ":/image/imageswitch/btncheckoff1.png";
imgOnFile = ":/image/imageswitch/btncheckon1.png";
this->resize(87, 28);
} else if (buttonStyle == ButtonStyle_2) {
imgOffFile = ":/image/imageswitch/btncheckoff2.png";
imgOnFile = ":/image/imageswitch/btncheckon2.png";
this->resize(87, 28);
} else if (buttonStyle == ButtonStyle_3) {
imgOffFile = ":/image/imageswitch/btncheckoff3.png";
imgOnFile = ":/image/imageswitch/btncheckon3.png";
this->resize(96, 38);
}
imgFile = isChecked ? imgOnFile : imgOffFile;
setChecked(isChecked);
this->update();
updateGeometry();//用于告知包含该widget的layout:该widget的size hint已发生变化,layout会自动进行调整。
}
}
main.cpp
#include "widget.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Widget w;
w.show();
return a.exec();
}
widget.cpp
#include "widget.h"
#include "ui_widget.h"
#include <QDebug>
#include "imageswitch.h"
Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);
this->initForm();
}
Widget::~Widget()
{
delete ui;
}
void Widget::initForm()
{
ui->imageSwitch1->setChecked(true);//设置开始的状态
ui->imageSwitch2->setChecked(true);
ui->imageSwitch3->setChecked(true);
ui->imageSwitch1->setFixedSize(87, 30);//设置widget 的大小
ui->imageSwitch2->setFixedSize(87, 30);
ui->imageSwitch3->setFixedSize(87, 30);
ui->imageSwitch1->setButtonStyle(ImageSwitch::ButtonStyle_1);//设置按钮的样式
ui->imageSwitch2->setButtonStyle(ImageSwitch::ButtonStyle_2);
ui->imageSwitch3->setButtonStyle(ImageSwitch::ButtonStyle_3);
//两种写法
// //绑定选中切换信号
//QT4 版本之后的写法!!
// connect(ui->imageSwitch1, SIGNAL(checkedChanged(bool)), this, SLOT(checkedChanged(bool)));
// connect(ui->imageSwitch2, SIGNAL(checkedChanged(bool)), this, SLOT(checkedChanged(bool)));
// connect(ui->imageSwitch3, SIGNAL(checkedChanged(bool)), this, SLOT(checkedChanged(bool)));
void(ImageSwitch:: * anniu)(bool)=&ImageSwitch::checkedChanged;
void(Widget:: * jieshou)(bool)=&Widget::checkedChanged;
connect(ui->imageSwitch1,anniu,this,jieshou);
connect(ui->imageSwitch2,anniu,this,jieshou);
connect(ui->imageSwitch3,anniu,this,jieshou);
}
void Widget::checkedChanged(bool checked)
{
qDebug() << sender() << checked;
}