开关按钮大家应该很熟悉,在设置里面经常遇到,切换时候的滑动效果比较帅气。通常说的开关按钮,有两个状态:on、off。大部分的开关按钮控件,基本上有两大类,第一类是纯代码绘制,这种对代码的掌控度要求比较高,但是灵活性比较好。第二类是贴图,专业的美工做好的各种状态的背景图片,只需要用代码将该图片画到界面上即可。下面,先介绍一种利用贴图来实现的开关按钮。想看纯代码实现的开关按钮请移步:
https://blog.csdn.net/u012959478/article/details/140430844
一、简述
使用QT实现图片开关控件,即各种状态的背景图片实现开关按钮。
二、 设计思路
在Qt中,可以通过继承QWidget类来创建一个自定义的图片开关控件。以下是一个简单的自定义控件示例,它可以显示一个带有两种状态的图片(开启和关闭),并且可以通过鼠标点击进行切换状态。
实现带贴图的开关按钮可以按照以下步骤进行:
- 导入需要使用的贴图文件,并添加到项目资源中。
- 设计一个开关按钮。
- 设置按钮的初始状态,并加载对应的贴图。
- 在按钮的点击事件中,切换按钮的状态,并更新贴图。
- 根据按钮的状态,执行相应的操作。
三、效果
四、核心代码
1、头文件
#ifndef IMAGESWITCH_H
#define IMAGESWITCH_H
#include <QWidget>
class ImageSwitch : public QWidget
{
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:
//默认尺寸和最小尺寸
QSize sizeHint() const;
QSize minimumSizeHint() const;
//获取和设置是否选中
bool getChecked() const;
void setChecked(bool isChecked);
//获取和设置按钮样式
ButtonStyle getButtonStyle() const;
void setButtonStyle(const ImageSwitch::ButtonStyle &buttonStyle);
Q_SIGNALS:
void checkedChanged(bool checked);
};
#endif // IMAGESWITCH_H
2、实现代码
#include "imageswitch.h"
#include <QPainter>
ImageSwitch::ImageSwitch(QWidget *parent) : QWidget(parent)
{
isChecked = false;
buttonStyle = ButtonStyle_2;
imgOffFile = ":/image/imageswitch/btncheckoff2.png";
imgOnFile = ":/image/imageswitch/btncheckon2.png";
imgFile = imgOffFile;
}
void ImageSwitch::mousePressEvent(QMouseEvent *)
{
imgFile = isChecked ? imgOffFile : imgOnFile;
isChecked = !isChecked;
Q_EMIT checkedChanged(isChecked);
this->update();
}
void ImageSwitch::paintEvent(QPaintEvent *)
{
QPainter painter(this);
painter.setRenderHints(QPainter::SmoothPixmapTransform);
QImage img(imgFile);
img = img.scaled(this->size(), Qt::KeepAspectRatio, Qt::SmoothTransformation);
//按照比例自动居中绘制
int pixX = rect().center().x() - img.width() / 2;
int pixY = rect().center().y() - img.height() / 2;
QPoint point(pixX, pixY);
painter.drawImage(point, img);
}
QSize ImageSwitch::sizeHint() const
{
return QSize(87, 28);
}
QSize ImageSwitch::minimumSizeHint() const
{
return QSize(87, 28);
}
bool ImageSwitch::getChecked() const
{
return isChecked;
}
void ImageSwitch::setChecked(bool isChecked)
{
if (this->isChecked != isChecked) {
this->isChecked = isChecked;
imgFile = isChecked ? imgOnFile : imgOffFile;
this->update();
}
}
ImageSwitch::ButtonStyle ImageSwitch::getButtonStyle() const
{
return this->buttonStyle;
}
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();
}
}
这个自定义控件ImageSwitch
提供了基本的开关功能,通过鼠标点击可以在开启和关闭状态之间切换,并且在状态改变时发出一个信号,允许父控件或主窗口作出相应的处理。你可以根据需要对控件进行自定义和扩展。
五、使用示例
以下是一个简单的示例代码,演示了如何在Qt中使用此控件:
#include "frmimageswitch.h"
#include "ui_frmimageswitch.h"
#include "qdebug.h"
frmImageSwitch::frmImageSwitch(QWidget *parent) : QWidget(parent), ui(new Ui::frmImageSwitch)
{
ui->setupUi(this);
this->initForm();
}
frmImageSwitch::~frmImageSwitch()
{
delete ui;
}
void frmImageSwitch::initForm()
{
ui->imageSwitch1->setChecked(true);
ui->imageSwitch2->setChecked(true);
ui->imageSwitch3->setChecked(true);
ui->imageSwitch1->setFixedSize(160,60);
ui->imageSwitch2->setFixedSize(160,60);
ui->imageSwitch3->setFixedSize(160,60);
ui->imageSwitch1->setButtonStyle(ImageSwitch::ButtonStyle_1);
ui->imageSwitch2->setButtonStyle(ImageSwitch::ButtonStyle_2);
ui->imageSwitch3->setButtonStyle(ImageSwitch::ButtonStyle_3);
//绑定选中切换信号
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 frmImageSwitch::checkedChanged(bool checked)
{
qDebug() << sender() << checked;
}
在上面的示例中,按钮的初始状态为开启,通过设置按钮的 setchecked 进行状态切换。在切换状态时,根据按钮的状态加载对应的贴图,并设置贴图的大小。同时,根据按钮的状态进行相应的操作。需要注意的是,示例中的 on.png 和 off.png 是虚拟的贴图文件,请根据实际情况导入和设置贴图。
谢谢你的关注和阅读,希望我的回答能帮到你。如果还有其他问题,欢迎随时向我提问。祝你一切顺利!