QT实现图片开关控件-自定义控件

        开关按钮大家应该很熟悉,在设置里面经常遇到,切换时候的滑动效果比较帅气。通常说的开关按钮,有两个状态:on、off。大部分的开关按钮控件,基本上有两大类,第一类是纯代码绘制,这种对代码的掌控度要求比较高,但是灵活性比较好。第二类是贴图,专业的美工做好的各种状态的背景图片,只需要用代码将该图片画到界面上即可。下面,先介绍一种利用贴图来实现的开关按钮。

一、简述

         使用QT实现图片开关控件,即各种状态的背景图片实现开关按钮。

二、 设计思路

        在Qt中,可以通过继承QWidget类来创建一个自定义的图片开关控件。以下是一个简单的自定义控件示例,它可以显示一个带有两种状态的图片(开启和关闭),并且可以通过鼠标点击进行切换状态。        

实现带贴图的开关按钮可以按照以下步骤进行:

  1. 导入需要使用的贴图文件,并添加到项目资源中。
  2. 设计一个开关按钮。
  3. 设置按钮的初始状态,并加载对应的贴图。
  4. 在按钮的点击事件中,切换按钮的状态,并更新贴图。
  5. 根据按钮的状态,执行相应的操作。
三、效果 

四、核心代码  
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 是虚拟的贴图文件,请根据实际情况导入和设置贴图。

        谢谢你的关注和阅读,希望我的回答能帮到你。如果还有其他问题,欢迎随时向我提问。祝你一切顺利!

六、源代码下载
  • 6
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Qt是一个跨平台的C++应用程序开发框架,提供了丰富的件和功能,可以用于开发各种类型的应用程序。 在实现表格树件时,如果需要支持多级表头,可以借助Qt的QHeaderView类来实现。QHeaderView类是Qt中用于表格或树型视图的表头件,它可以显示列或行的标题,并且支持拖动和调整列宽度。 首先,创建一个QTreeView件作为表格树件的显示部分。然后,创建一个QHeaderView对象作为表格树件的表头,使用setModel()函数将表头设置给表格树件。接下来,设置表头的显示模式为水平模式,使用setSectionResizeMode()函数设置每一列的调整方式,例如,可以设置为可以自动调整大小或者禁止调整大小。 为了支持多级表头,可以使用QHeaderView的addSection()函数来添加多级表头。逐级添加表头时,需要设置每一级表头的标签、起始列、列数和对齐方式。可以使用setHeaderData()函数为每一级的表头设置样式。 接着,使用setHeaderHidden()函数将QTreeView的默认表头隐藏起来,这样就只展示了我们自定义的多级表头。同时,可以使用setRootIsDecorated()函数将树节点的展开和收缩图标隐藏起来,以使得表格树件更加美观。 最后,将数据模型设置给QTreeView件,通过添加树节点和设置节点的父子关系,来组织表格树的数据结构。数据模型可以继承自QAbstractItemModel类,实现相关的接口函数,以提供数据的展示和操作。 通过以上步骤,我们就可以实现一个支持多级表头的表格树件。用户可以通过拖动和调整表头以调整列宽度,同时展示复杂的表头结构,方便显示和操作大量数据。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值