智能灯设置 - 开关状态和亮度控制

本代码实现了一个智能灯设置界面,包括开关控制、亮度调节和状态保存功能。

代码实现

#ifndef SWITCHFORM_H
#define SWITCHFORM_H

#include <QWidget>
#include <QTimer>
#include <QColor>

namespace Ui {
class SwitchForm;
}

class SwitchForm : public QWidget
{
    Q_OBJECT

public:
    explicit SwitchForm(QWidget *parent = nullptr);

signals:
    void statusChanged(bool checked);


public slots:
    void updateValue();

private:
    void drawBackGround(QPainter *painter);
    void drawSlider(QPainter *painter);

protected:
    void paintEvent(QPaintEvent *ev);
    void mousePressEvent(QMouseEvent *ev);

private:

    int m_space;                //滑块距离边界距离
    int m_radius;               //圆角角度

    bool m_checked;             //是否选中
    bool m_showText;            //是否显示文字
    bool m_showCircle;          //是否显示圆圈
    bool m_animation;           //是否使用动画

    QColor m_bgColorOn;         //打开时候的背景色
    QColor m_bgColorOff;        //关闭时候的背景色
    QColor m_sliderColorOn;     //打开时候滑块颜色
    QColor m_sliderColorOff;    //关闭时候滑块颜色
    QColor m_textColor;         //文字颜色

    QString m_textOn;           //打开时候的文字
    QString m_textOff;          //关闭时候的文字

    QTimer  *m_timer;            //动画定时器
    int     m_step;             //动画步长
    int     m_startX;           //滑块开始X轴坐标
    int     m_endX;             //滑块结束X轴坐标

public:
    int space()                 const;
    int radius()                const;
    bool checked()              const;
    bool showText()             const;
    bool showCircel()           const;
    bool animation()            const;

    QColor bgColorOn()          const;
    QColor bgColorOff()         const;
    QColor sliderColorOn()      const;
    QColor sliderColorOff()     const;
    QColor textColor()          const;

    QString textOn()            const;
    QString textOff()           const;

    int step()                  const;
    int startX()                const;
    int endX()                  const;

public Q_SLOTS:
    void setSpace(int space);
    void setRadius(int radius);
    void setChecked(bool checked);
    void setShowText(bool show);
    void setShowCircle(bool show);
    void setAnimation(bool ok);

    void setBgColorOn(const QColor &color);
    void setBgColorOff(const QColor &color);
    void setSliderColorOn(const QColor &color);
    void setSliderColorOff(const QColor &color);
    void setTextColor(const QColor &color);

    void setTextOn(const QString &text);
    void setTextOff(const QString &text);
public slots:
    bool getstate();

};

bool getStatus();

#endif // SWITCHFORM_H



#include 'switchform.h'
#include 'ui_switchform.h'
#include <QPainter>

SwitchForm::SwitchForm(QWidget *parent) :
    QWidget(parent)
{
    m_space = 2;
    m_radius = 5;
    m_checked = false;
    m_showText = true;
    m_showText = false;
    m_animation = true;

    m_bgColorOn = QColor(102, 205, 170);//设置按钮内部颜色
    m_bgColorOff = QColor(190, 190, 190);

    m_sliderColorOn = QColor(255, 255, 255);
    m_sliderColorOff = QColor(255, 255, 255);

    m_textColor = QColor(255, 255, 255);

    m_textOn = '开启'//设置按钮中的文字
    m_textOff = '关闭';

    m_step = 0;
    m_startX = 0;
    m_endX = 0;

    m_timer = new QTimer(this);
    m_timer->setInterval(30);
    connect(m_timer, SIGNAL(timeout()), this, SLOT(updateValue()));
}

void SwitchForm::drawBackGround(QPainter *painter)
{
    painter->save();
    painter->setPen(Qt::NoPen);

    QColor bgColor = m_checked ? m_bgColorOn : m_bgColorOff;
    if (isEnabled()) {
        bgColor.setAlpha(150);
    }

    painter->setBrush(bgColor);

    QRect rect(0, 0, width(), height());
    int side = qMin(width(), height());

    //左侧半圆
    QPainterPath path1;
    path1.addEllipse(rect.x(), rect.y(), side, side);

    //右侧半圆
    QPainterPath path2;
    path2.addEllipse(rect.width() - side, rect.y(), side, side);

    //中间的矩形
    QPainterPath path3;
    path3.addRect(rect.x() + side / 2, rect.y(), rect.width() - side, height());

    QPainterPath path = path1 + path2 + path3;
    painter->drawPath(path);

    //绘制文本

    //滑块半径
    int sliderWidth = qMin(height(), width()) - m_space * 2 - 5;
    if (m_checked){
        QRect textRect(0, 0, width() - sliderWidth, height());
        painter->setPen(QPen(m_textColor));
        painter->drawText(textRect, Qt::AlignCenter, m_textOn);
    } else {
        QRect textRect(sliderWidth, 0, width() - sliderWidth, height());
        painter->setPen(QPen(m_textColor));
        painter->drawText(textRect, Qt::AlignCenter, m_textOff);
    }

    painter->restore();
}

void SwitchForm::drawSlider(QPainter *painter)
{
    painter->save();
    painter->setPen(Qt::NoPen);

    QColor color = m_checked ? m_sliderColorOn : m_sliderColorOff;

    painter->setBrush(QBrush(color));

    int sliderWidth = qMin(width(), height()) - m_space * 2;
    int sliderX = m_checked ? width() - sliderWidth - m_space : m_space; // 修改滑块的X轴坐标
    QRect rect(sliderX, m_space, sliderWidth, sliderWidth);
    painter->drawEllipse(rect);

    painter->restore();
}

void SwitchForm::paintEvent(QPaintEvent *ev)
{
    //启用反锯齿
    QPainter painter(this);
    painter.setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing);

    //绘制背景
    drawBackGround(&painter);

    //绘制滑块
    drawSlider(&painter);
}


void SwitchForm::mousePressEvent(QMouseEvent *ev)
{
    Q_UNUSED(ev)

    m_checked = !m_checked;
    emit statusChanged(m_checked);

    // 计算步长
    m_step = qAbs(m_endX - m_startX) / 10; // 修改步长的计算方式

    // 判断是否使用动画
    if (m_animation) {
        m_timer->start();
    } else {
        m_startX = m_endX;
        update();
    }
}

void SwitchForm::updateValue()
{
    if (m_checked) {
        if (m_startX < m_endX) {
            m_startX += m_step;
        } else {
            m_startX = m_endX;
            m_timer->stop();
        }
    } else {
        if (m_startX > m_endX) {
            m_startX -= m_step;
        } else {
            m_startX = m_endX;
            m_timer->stop();
        }
    }

    update();
}

int SwitchForm::space() const
{
    return m_space;
}

bool SwitchForm::checked() const
{
    return m_checked;
}

bool SwitchForm::showText() const
{
    return m_showText;
}

bool SwitchForm::showCircel() const
{
    return m_showCircle;
}

bool SwitchForm::animation() const
{
    return m_animation;
}

QColor SwitchForm::bgColorOn() const
{
    return m_bgColorOn;
}

QColor SwitchForm::bgColorOff() const
{
    return m_bgColorOff;
}

QColor SwitchForm::sliderColorOn() const
{
    return m_sliderColorOn;
}

QColor SwitchForm::sliderColorOff() const
{
    return m_sliderColorOff;
}

QColor SwitchForm::textColor() const
{
    return m_textColor;
}

QString SwitchForm::textOn() const
{
    return m_textOn;
}

QString SwitchForm::textOff() const
{
    return m_textOff;
}

int SwitchForm::step() const
{
    return m_step;
}

int SwitchForm::startX() const
{
    return m_startX;
}

int SwitchForm::endX() const
{
    return m_endX;
}

void SwitchForm::setSpace(int space)
{
    if (m_space != space) {
        m_space = space;
        update();
    }
}

void SwitchForm::setRadius(int radius)
{
    if (m_radius != radius) {
        m_radius = radius;
        update();
    }
}

void SwitchForm::setChecked(bool checked)
{
    if (m_checked != checked) {
        m_checked = checked;
        update();
    }
}

void SwitchForm::setShowText(bool show)
{
    if (m_showText != show) {
        m_showText = show;
        update();
    }
}

void SwitchForm::setShowCircle(bool show)
{
    if (m_showCircle != show) {
        m_showCircle = show;
        update();
    }
}

void SwitchForm::setAnimation(bool ok)
{
    if (m_animation != ok) {
        m_animation = ok;
        update();
    }
}

void SwitchForm::setBgColorOn(const QColor &color)
{
    if (m_bgColorOn != color) {
        m_bgColorOn = color;
        update();
    }
}

void SwitchForm::setBgColorOff(const QColor &color)
{
    if (m_bgColorOff != color) {
        m_bgColorOff = color;
        update();
    }
}

void SwitchForm::setSliderColorOn(const QColor &color)
{
    if (m_sliderColorOn != color) {
        m_sliderColorOn = color;
        update();
    }
}

void SwitchForm::setSliderColorOff(const QColor &color)
{
    if (m_sliderColorOff != color) {
        m_sliderColorOff = color;
        update();
    }
}

void SwitchForm::setTextColor(const QColor &color)
{
    if (m_textColor != color) {
        m_textColor = color;
        update();
    }
}

void SwitchForm::setTextOn(const QString &text)
{
    if (m_textOn != text) {
        m_textOn = text;
        update();
    }
}

void SwitchForm::setTextOff(const QString &text)
{
    if (m_textOff != text) {
        m_textOff = text;
        update();
    }
}

bool SwitchForm::getstate()
{
    return m_checked;
}


#include 'lights.h'
#include 'ui_lights.h'
#include 'switchform.h'
#include 'sqlite.h'
#include <QSqlQuery>
#include <QSqlDatabase>
#include <QSqlError>
#include <QCloseEvent>
#include <QDebug>

Lights::Lights(int userid,QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Lights),
    userid(userid)      //保证userid无变化
{
    ui->setupUi(this);
    lightsWidget();
    //连接开关组件的信号和自定义的槽函数
    connect(ui->SwitchStatus,&SwitchForm::statusChanged,this,&Lights::switchButton_status);

    // 连接完成按钮的clicked信号和自定义的槽函数
    connect(ui->Finished, &QPushButton::clicked, this,[=]{
        if(flag)
        {
            QString brighteness = QString::number(ui->ctrlform->getValue());
            qDebug()<<brighteness<<userid;
            updateSmartHomeStatus(userid,QString('智能灯'),QString('开启'),brighteness);
        }else
        {
            qDebug()<<'智能灯未打开!';
            updateSmartHomeStatus(userid,QString('智能灯'),QString('关闭'),QString('0'));
        }
    });
    // 加载上次更改的状态
    loadLastStatus();


}

Lights::~Lights()
{
    delete ui;
}

void Lights::lightsWidget()
{
    setWindowTitle('智能灯设置');
    //设置ui组件背景
    setAutoFillBackground(true);
    QPalette palette=this->palette();
    QPixmap pixmap(':/user/image/image/light.jpg');
    palette.setBrush(QPalette::Window, QBrush(pixmap));
    setPalette(palette);
    setFixedSize(600,400);
}

bool Lights::switchButton_status(bool checked)
{
    qDebug()<<checked;
    flag=checked;
    // 更新UI界面上的状态
    if (checked) {
        ui->ctrlform->setEnabled(true);
    } else {
        ui->ctrlform->setEnabled(false);
    }
    return flag;
}

void Lights::showEvent(QShowEvent *event)
{
    // 当页面显示时,加载上次更改的状态
    loadLastStatus();
    event->accept();
}

void Lights::hideEvent(QHideEvent *event)
{
    saveLastStatus();
    event->accept();
}

void Lights::closeEvent(QCloseEvent *event)
{
    // 隐藏窗口而不是关闭
    hide();
    event->ignore();
}

void Lights::loadLastStatus()
{
    qDebug()<<this->userid;
    QString state = getLastState(this->userid);
    QString brightness = getLastBrightness(this->userid);
    qDebug()<<'1'<<state;
    if (state=='开启')
    {
        ui->SwitchStatus->setChecked(true);
        ui->ctrlform->setEnabled(true);
        ui->ctrlform->setValue(brightness.toInt());
    }
    else
    {
        ui->SwitchStatus->setChecked(false);
        ui->ctrlform->setEnabled(false);
        ui->ctrlform->setValue(0);
    }
    qDebug()<<brightness.toInt();
}

void Lights::saveLastStatus()
{
    qDebug()<<this->flag;
    QString status=QString(ui->SwitchStatus->getstate());
    QString brightness = QString::number(ui->ctrlform->getValue());
    updateLastBrightness(this->userid, brightness, status);
}


QString Lights::getLastBrightness(int userid)
{
    Sqlite::sqlite_init();
    QString queryStr = QString('SELECT value FROM Status WHERE uid = %1 AND device_name = '智能灯' ORDER BY sid DESC LIMIT 1').arg(userid);
    qDebug()<<queryStr<<userid;
    QSqlQuery query;
    qDebug ()<<query.exec(queryStr);
    if (query.exec(queryStr) && query.next())
    {
        return query.value(0).toString();
    }
    else
    {
        qDebug() << '得到上一次亮度错误: ' << query.lastError().text();
        return '';
    }
}

QString Lights::getLastState(int userid)
{
    Sqlite::sqlite_init();
    QString queryStr = QString('SELECT device_state FROM Status WHERE uid = %1 AND device_name = '智能灯' ORDER BY sid DESC LIMIT 1').arg(userid);
    qDebug()<<queryStr<<userid;
    QSqlQuery query;
    qDebug ()<<query.exec(queryStr);
    if (query.exec(queryStr) && query.next())
    {
        qDebug()<<'a'<<query.value(0);
        return query.value(0).toString();
    }
    else
    {
        qDebug() << '得到上一次状态错误: ' << query.lastError().text();
        return '';
    }
}

void Lights::updateLastBrightness(int userid,QString brightness,QString state)
{
    Sqlite::sqlite_init();
    QString queryStr = QString('UPDATE Status SET value = '%1' AND device_state = '%2' WHERE uid = %3 AND device_name = '智能灯'').arg(brightness).arg(state).arg(userid);
    QSqlQuery query;
    if (!query.exec(queryStr))
    {
        qDebug() << '更新亮度失败: ' << query.lastError().text();
    }
}


代码解析

  1. SwitchForm 类:

    • 该类实现了一个简单的开关组件,通过鼠标点击事件来改变开关状态,并使用动画效果来模拟开关的滑动过程。

    • statusChanged 信号:当开关状态改变时,会发出该信号,以便其他组件获取开关状态。

  2. Lights 类:

    • 该类实现了一个智能灯设置界面,包括开关组件、亮度控制组件和完成按钮。

    • lightsWidget() 函数:初始化界面,设置标题、背景图片和固定大小。

    • switchButton_status() 函数:该函数是连接开关组件 statusChanged 信号的槽函数,当开关状态改变时,会更新亮度控制组件的可用状态。

    • loadLastStatus() 函数:该函数用于加载上次更改的状态,并更新UI界面上的状态。

    • saveLastStatus() 函数:该函数用于保存当前状态到数据库中。

    • getLastBrightness()getLastState() 函数:从数据库中获取上次的亮度值和状态值。

    • updateLastBrightness() 函数:更新数据库中亮度值和状态值。

使用方法

  1. 将代码复制到您的项目中。

  2. 在您的主窗口中创建 Lights 类的实例,并传入用户 ID。

  3. 调用 Lights 类的 show() 函数,显示界面。

说明

  • 代码中使用了 Qt 的信号与槽机制来实现组件之间的通信。

  • 代码中使用了 SQLite 数据库来保存上次更改的状态。

  • 代码中使用了动画效果来增强用户体验。

  • 代码中使用了 QDebug 类来打印调试信息。

改进建议

  • 可以使用其他类型的数据库来保存状态,例如 MySQL 或 PostgreSQL。

  • 可以添加更多功能,例如定时开关、场景模式等。

  • 可以优化代码结构和性能。

  • 可以使用 Qt 的样式表来美化界面。


原文地址: http://www.cveoy.top/t/topic/fATp 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录