ICode9

精准搜索请尝试: 精确搜索
首页 > 数据库> 文章详细

使用sql制作闹钟

2022-06-05 10:04:27  阅读:173  来源: 互联网

标签:info deviation int void 闹钟 sql model include 制作


效果

image

代码

mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QSqlDatabase>
#include <QSqlQuery>
#include <QMainWindow>
#include <QDialog>
#include <QHBoxLayout>
#include <QVBoxLayout>
#include <QPushButton>
#include <QListWidget>
#include <QLabel>
#include <QTime>
#include <QSqlTableModel>
#include "numberpicker.h"
#include "switchbutton.h"

class NumberPicker;
class SwitchButton;

/* ListWiget项结构体 */
struct ItemObjectInfo {
    /* 闹钟开关 */
    SwitchButton *switchButton;
    /* Widget容器 */
    QWidget *widget;
    /* 水平布局 */
    QHBoxLayout *hBoxLayout;
};


class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

private:

    /* 数据库连接类 */
    QSqlDatabase sqlDatabase;

    /* 数据库操作模型 */
    QSqlTableModel *model;

    /* 时针选择器 */
    NumberPicker *hourPicker;

    /* 分钟选择器 */
    NumberPicker *minutePicker;

    /* 弹出选择时间对话框 */
    QDialog *alarmDialog;

    /* 水平布局 */
    QHBoxLayout *hBoxLayout[3];

    /* 垂直布局 */
    QVBoxLayout *vBoxLayout[2];

    /* 显示闹钟列表 */
    QListWidget *listWidget;

    /* 主Widget */
    QWidget *mainWidget;

    /* 底部Wiget */
    QWidget *bottomWidget;

    /* 弹出对话框布局窗口选择时间容器 */
    QWidget *timeWidget;

    /* 弹出对话框布局窗口按钮容器 */
    QWidget *btWidget;

    /* 添加闹钟按钮 */
    QPushButton *addAlarm;

    /* 确认按钮 */
    QPushButton *yesButton;

    /* 取消按钮 */
    QPushButton *cancelButton;

    /* listWiget项信息存储 */
    QVector<ItemObjectInfo> itemObjectInfo;

private slots:
    /* 添加闹钟按钮被点击 */
    void addAlarmClicked();

    /* 列表被点击 */
    void listWidgetItemClicked(QListWidgetItem *);

    /* 确认按钮被点击 */
    void yesButtonClicked();

    /* 取消按钮被点击 */
    void cancelButtonClicked();

    /* 开关按钮点击 */
    void switchButtonClicked(bool);
};
#endif // MAINWINDOW_H

mainwindow.cpp

#include "mainwindow.h"
#include <QDebug>
#include <QSqlError>

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
{
    /* 设置主窗体的显示位置与大小 */
    this->setGeometry(0, 0, 800, 480);

    /* 查看本机可用的数据库驱动 */
    QStringList drivers = QSqlDatabase::drivers();
    foreach(QString driver, drivers) {
        qDebug()<<driver;
    }

    /* 以QSQLITE驱动方式打开或者创建数据库 */
    sqlDatabase = QSqlDatabase::addDatabase("QSQLITE");
    sqlDatabase.setDatabaseName("alarm.db");
    /* 以open的方式打开alarm.db数据库,则会创建一个alarm.db */
    if (!sqlDatabase.open())
        qDebug()<<"连接数据库错误"<<sqlDatabase.lastError()<<endl;
    else
        qDebug()<<"连接数据库成功"<<endl;

    QSqlQuery query(sqlDatabase);
    /* 使用指令式创建表 */
    query.exec("create table alarm (id int primary key, time vchar(15), flag vchar(5))");
    /* 以指令的方式插入数据 */
    //query.exec("insert into alarm values(0, '06:00', 'false')");

    model = new QSqlTableModel(this, sqlDatabase);

    /* 模型设置表的名字,需要与数据库的表的名字相同 */
    model->setTable("alarm");

    /* 如果有修改则同步修改到数据库,
     * 注意这个规则需要与tabview这样的控件才生效,
     * 因为tabview可以直接编辑表里的内容 */
    model->setEditStrategy(QSqlTableModel::OnFieldChange);

    /* 成功则返回true,查看数据库里是否有alarm这个表格 */
    model->select();

    /* 如果数据表数据为空,则添加两个闹钟 */
    if (model->rowCount() == 0) {
        /* 插入一行 */
        model->insertRow(model->rowCount());
        /* 在该行插入数据 */
        model->setData(model->index(0, 0), 1);
        model->setData(model->index(0, 1), "06:00");
        model->setData(model->index(0, 2), "false");
        /* 插入数据后记得提交 */
        model->submit();

        /* 再插入一行 */
        model->insertRow(model->rowCount());
        model->setData(model->index(1, 0), 2);
        model->setData(model->index(1, 1), "18:00");
        model->setData(model->index(1, 2), "true");
        /* 提交 */
        model->submit();
    }

    hourPicker = new NumberPicker(this);
    hourPicker->setRange(0, 24);

    minutePicker = new NumberPicker(this);
    minutePicker->setRange(0, 60);

    /* 标签,用于显示时&分 */
    QLabel *label[3];
    label[0] = new QLabel();
    label[1] = new QLabel();
    label[2] = new QLabel();

    QFont font;
    font.setBold(true);
    font.setPixelSize(10);
    QPalette pal;
    pal.setBrush(QPalette::WindowText, QColor(0, 0, 0));

    label[0]->setFont(font);
    label[1]->setFont(font);
    label[2]->setFont(font);

    label[0]->setText(" ");
    label[1]->setText("时");
    label[2]->setText("分");

    /* 主布局初始化 */
    listWidget = new QListWidget();
    mainWidget = new QWidget();
    bottomWidget = new QWidget();
    alarmDialog = new QDialog(this);
    timeWidget = new QWidget();
    btWidget = new QWidget();
    addAlarm = new QPushButton();
    yesButton = new QPushButton();
    cancelButton = new QPushButton();
    vBoxLayout[0] = new QVBoxLayout();
    vBoxLayout[1] = new QVBoxLayout();
    hBoxLayout[0] = new QHBoxLayout();
    hBoxLayout[1] = new QHBoxLayout();
    hBoxLayout[2] = new QHBoxLayout();

    addAlarm->setMaximumSize(84, 84);
    addAlarm->setObjectName("addAlarm");
    addAlarm->setMinimumSize(84, 84);
    bottomWidget->setMinimumHeight(84);
    bottomWidget->setMaximumHeight(84);
    yesButton->setText("确认");
    cancelButton->setText("取消");
    yesButton->setMaximumSize(100, 50);
    yesButton->setMinimumSize(100, 50);
    cancelButton->setMinimumSize(100, 50);
    cancelButton->setMaximumSize(100, 50);
    btWidget->setMaximumHeight(70);
    btWidget->setMinimumHeight(70);
    alarmDialog->setMinimumSize(300, 300);
    alarmDialog->setMaximumSize(300, 300);
    alarmDialog->setModal(true);
    yesButton->setObjectName("yesButton");
    cancelButton->setObjectName("cancelButton");

    /* 主布局 */
    vBoxLayout[0]->addWidget(listWidget);
    vBoxLayout[0]->addWidget(bottomWidget);
    vBoxLayout[0]->setContentsMargins(0, 0, 0, 0);

    mainWidget->setLayout(vBoxLayout[0]);

    setCentralWidget(mainWidget);

    /* 底部按钮布局 */
    hBoxLayout[0]->addWidget(addAlarm);
    hBoxLayout[0]->setContentsMargins(0, 0, 0, 0);
    bottomWidget->setLayout(hBoxLayout[0]);

    /* 对话框布局 */
    vBoxLayout[1]->addWidget(timeWidget);
    vBoxLayout[1]->addWidget(btWidget);
    vBoxLayout[1]->setContentsMargins(0, 0, 0, 0);
    alarmDialog->setLayout(vBoxLayout[1]);

    hBoxLayout[1]->addWidget(label[0]);
    hBoxLayout[1]->addWidget(hourPicker);
    hBoxLayout[1]->addWidget(label[1]);
    hBoxLayout[1]->addWidget(minutePicker);
    hBoxLayout[1]->addWidget(label[2]);
    hBoxLayout[1]->setContentsMargins(0, 0, 0, 0);
    timeWidget->setLayout(hBoxLayout[1]);

    hBoxLayout[2]->addWidget(yesButton);
    hBoxLayout[2]->addWidget(cancelButton);

    btWidget->setLayout(hBoxLayout[2]);

    /* 打印出闹钟数据库里的信息 */
    for (int i = 0; i < model->rowCount(); i++) {
        for (int j = 0; j < 3; j++) {
            QModelIndex qindex = model->index(i, j);
            switch (j) {
            case 0:
                qDebug()<<"第"<<model->data(qindex).toInt()<<"行数据";
                break;
            case 1:
                listWidget->addItem(model->data(qindex).toString());
                qDebug()<<"闹钟时间为:"<<model->data(qindex).toString();
                break;
            case 2:
                qDebug()<<"闹钟状态为:"
                       <<model->data(qindex).toString()<<endl;
                if (model->data(qindex).toString() != "true")
                    listWidget->item(i)
                            ->setTextColor(QColor(22, 22, 22, 60));
                else
                    listWidget->item(i)
                            ->setTextColor(QColor(22, 22, 22, 225));
                break;
            default:
                break;
            }
        }
    }

    /* 在列表里添加闹钟开关 */
    for (int i = 0; i < model->rowCount(); i++) {
        ItemObjectInfo info;
        info.widget = new QWidget();
        info.switchButton = new SwitchButton();
        info.hBoxLayout = new QHBoxLayout();
        info.switchButton->setMaximumSize(55, 30);
        info.switchButton->setMinimumSize(55, 30);
        info.hBoxLayout->setContentsMargins(0, 0, 0, 0);
        info.hBoxLayout->setAlignment(Qt::AlignRight);
        info.hBoxLayout->addWidget(info.switchButton);
        info.widget->setLayout(info.hBoxLayout);
        listWidget->setItemWidget(listWidget->item(i),
                                  info.widget);
        itemObjectInfo.append(info);

        /* 连接信号槽 */
        connect(info.switchButton,
                SIGNAL(toggled(bool)),
                this,
                SLOT(switchButtonClicked(bool)));

        /* 获取数据库里的闹钟开关状态 */
        QModelIndex qindex = model->index(i, 2);
        if (model->data(qindex).toBool())
            /* 设置列表里的闹钟开关按钮状态 */
            info.switchButton->setToggle(true);
    }

    /* 按钮 */
    connect(addAlarm, SIGNAL(clicked()), this,
            SLOT(addAlarmClicked()));

    connect(yesButton, SIGNAL(clicked()), this,
            SLOT(yesButtonClicked()));

    connect(cancelButton, SIGNAL(clicked()), this,
            SLOT(cancelButtonClicked()));

    /* 列表 */
    connect(listWidget,
            SIGNAL(itemClicked(QListWidgetItem*)),
            this,
            SLOT(listWidgetItemClicked(QListWidgetItem*)));
}

MainWindow::~MainWindow()
{
    /* 关闭数据库 */
    sqlDatabase.close();
}

void MainWindow::addAlarmClicked()
{
    /* 选择时间对话框里显示当前系统时间 */
    hourPicker->setValue(QTime::currentTime().hour());
    minutePicker->setValue(QTime::currentTime().minute());

    /* 取消按钮显示文本为"取消" */
    cancelButton->setText("取消");

    /* 如果是点击添加闹钟的按钮,则设置闹钟列表的索引index为-1 */
    listWidget->setCurrentRow(-1);

    /* 显示对话框 */
    alarmDialog->show();
}

void MainWindow::listWidgetItemClicked(QListWidgetItem *item)
{
    /* 从被点击项里获取闹钟数据 */
    QStringList list =
            listWidget->item(listWidget->row(item))->text().split(":");

    /* 选择时间对话框里显示被选择项的时间 */
    hourPicker->setValue(list.at(0).toInt());
    minutePicker->setValue(list.at(1).toInt());

    /* 取消按钮显示文本为"删除" */
    cancelButton->setText("删除");

    /* 显示闹钟选择对话框 */
    alarmDialog->show();

    /* 作用使其失去选择 */
    listWidget->clearSelection();
}

void MainWindow::yesButtonClicked()
{
    /* 获取数值选择值的数据,转为字符串 */
    QString hour;
    QString minute;

    if (hourPicker->readValue() < 10)
        hour = "0" + QString::number(hourPicker->readValue()) + ":";
    else
        hour = QString::number(hourPicker->readValue()) + ":";

    if (minutePicker->readValue() < 10)
        minute = "0" + QString::number(minutePicker->readValue());
    else
        minute = QString::number(minutePicker->readValue());

    /* 如果不是选中闹钟列表的数据 */
    if (listWidget->currentRow() == -1) {
        /* 插入一行数据,闹钟时间为选择的闹钟时间 */
        int row = model->rowCount();

        /* 插入数据到数据库 */
        model->insertRow(row);
        model->setData(model->index(row, 0), row + 1);
        model->setData(model->index(row, 1), hour + minute);
        model->setData(model->index(row, 2), "true");
        model->submit();

        /* 添加闹钟到列表 */
        listWidget->addItem(hour + minute);

        /* 添加到容器 */
        ItemObjectInfo info;
        info.widget = new QWidget();
        info.switchButton = new SwitchButton();
        info.hBoxLayout = new QHBoxLayout();
        info.switchButton->setMaximumSize(55, 30);
        info.switchButton->setMinimumSize(55, 30);
        info.hBoxLayout->setContentsMargins(0, 0, 0, 0);
        info.hBoxLayout->setAlignment(Qt::AlignRight);
        info.hBoxLayout->addWidget(info.switchButton);
        info.widget->setLayout(info.hBoxLayout);
        info.switchButton->setToggle(true);

        /* 连接信号槽 */
        connect(info.switchButton, SIGNAL(toggled(bool)), this,
                SLOT(switchButtonClicked(bool)));

        listWidget->setItemWidget(
                    listWidget->item(listWidget->count() - 1),
                    info.widget);
        itemObjectInfo.append(info);
    } else {
        /* 修改数据(更新闹钟数据) */
        int row =  listWidget->currentRow();
        model->setData(model->index(row, 0), row + 1);
        model->setData(model->index(row, 1), hour + minute);
        model->setData(model->index(row, 2), "true");
        model->submit();

        /* 设置当前项的闹钟文本 */
        listWidget->currentItem()->setText(hour + minute);
    }

    /* 再确保提交 */
    if (model->isDirty())
        model->submitAll();

    /* 关闭对话框 */
    alarmDialog->close();
}

void MainWindow::cancelButtonClicked()
{
    if (cancelButton->text() == "删除") {
        /* 删除数据库整一行数据 */
        model->removeRow(listWidget->currentRow());
        model->submit();
        /* 执行上面语句 */
        model->select();
        itemObjectInfo.remove(listWidget->currentRow());
        listWidget->takeItem(listWidget->currentRow());
    }

    /* 再确保提交 */
    if (model->isDirty())
        model->submitAll();

    /* 关闭对话框 */
    alarmDialog->close();
}


/* 当点击闹钟开关时,将闹钟开关状态同步更新到数据库里 */
void MainWindow::switchButtonClicked(bool checked)
{
    listWidget->clearSelection();

    SwitchButton *button = (SwitchButton *)sender();
    for (int i = 0; i < itemObjectInfo.count(); i++) {
        if (button == itemObjectInfo.at(i).switchButton) {
            if (checked) {
                model->setData(model->index(i, 2), "true");
                listWidget->item(i)
                        ->setTextColor(QColor(22, 22, 22, 225));
            } else {
                model->setData(model->index(i, 2), "false");
                listWidget->item(i)
                        ->setTextColor(QColor(22, 22, 22, 60));
            }

            model->submit();
            break;
        }
    }
}

numberpicker.h

#ifndef NUMBERPICKER_H
#define NUMBERPICKER_H

#include <QMainWindow>
#include <QPropertyAnimation>

class NumberPicker : public QWidget
{
    Q_OBJECT

    Q_PROPERTY(int deviation READ readDeviation WRITE setDeviation )
public:
    NumberPicker(QWidget *parent = nullptr);
    ~NumberPicker();

    /* 设置最大值与最小值的范围 */
    void setRange(int min, int max);

    /* 读取当前值 */
    int readValue();

protected:
    void mousePressEvent(QMouseEvent *);

    void mouseMoveEvent(QMouseEvent *);

    void mouseReleaseEvent(QMouseEvent *);

    void wheelEvent(QWheelEvent *);

    void paintEvent(QPaintEvent *);

public:
    /* 描绘数字 */
    void paintNum(QPainter &painter, int num, int deviation);

    /* 使选中的数字回到屏幕中间 */
    void homing();

    /* 鼠标移动偏移量,默认为0 */
    int readDeviation();

    /* 设置偏移量 */
    void setDeviation(int n);

    /* 设置字体大小 */
    void setNumSize(int);

    /* 设置间隔大小 */
    void setInterval(int);

    /* 设置分格数量,一般设置为3、5、7... */
    void setDevide(int);

    /* 设置数字颜色,设置rgb的数值 */
    void setNumberColor(QRgb rgb);

    /* 设置当前值 */
    void setValue(int value);

signals:

    void currentValueChanged(int value);

    void deviationChange(int deviation);

private:
    /* 最小值 */
    int minRange;

    /* 最大值 */
    int maxRange;

    /* 当前选中的值 */
    int currentValue;

    /* 鼠标是否按下 */
    bool isDragging;

    /* 偏移量,记录鼠标按下后移动的垂直距离 */
    int deviation;

    /* 鼠标按下的垂直位置 */
    int mouseSrcPos;

    /* 数字大小 */
    int numSize;

    /* 动画 */
    QPropertyAnimation *homingAni;

    /* 间隔大小 */
    int interval;

    /* 分格数量 */
    int devide;

    /* 数字颜色 */
    QColor numberColor;
};
#endif // NUMBERPICKER_H

numberpicker.cpp

#include <QMouseEvent>
#include <QDebug>
#include "numberpicker.h"
#include <QPainter>

NumberPicker::NumberPicker(QWidget *parent) :
    /* 最小值默认为0 */
    minRange(0),

    /* 最大值默认60 */
    maxRange(60),

    /* 当前值默认0 */
    currentValue(0),

    /* 按下标志位为假 */
    isDragging(false),

    /* 默认偏移量为0 */
    deviation(0),

    /* 数值越大 */
    numSize(15),

    /* 间隔为1 */
    interval(1),

    /* 默认分成3格 */
    devide(3),

    /* 默认颜色黑色 */
    numberColor(0, 0, 0)
{
    setParent(parent);
    setMinimumSize(50, 150);
    homingAni = new QPropertyAnimation(this, "deviation");
    homingAni->setDuration(300);
    homingAni->setEasingCurve(QEasingCurve::OutQuad);
}

NumberPicker::~NumberPicker()
{

}

void NumberPicker::setRange(int min, int max)
{
    minRange = min;
    maxRange = max;
    if (currentValue < min) {
        currentValue = min;
    }
    if (currentValue > max) {
        currentValue = max;
    }
    repaint();
}

int NumberPicker::readValue()
{
    return currentValue;
}

void NumberPicker::mousePressEvent(QMouseEvent *e)
{
    homingAni->stop();
    isDragging = true;
    mouseSrcPos = e->pos().y();
    QWidget::mousePressEvent(e);
}

void NumberPicker::mouseMoveEvent(QMouseEvent *e)
{
    if (isDragging){
        deviation = e->pos().y() - mouseSrcPos;

        /* 若移动速度过快,则进行限制 */
        if (deviation > (height() - 1) / devide) {
            deviation = (height() - 1) / devide;
        } else if (deviation < -(height() - 1) / devide) {
            deviation = -( height() - 1) / devide;
        }

        emit deviationChange(deviation / ((height() - 1) / devide));
        repaint();
    }
}

void NumberPicker::mouseReleaseEvent(QMouseEvent *)
{
    if (isDragging) {
        isDragging = false;
        homing();
    }
}

void NumberPicker::wheelEvent(QWheelEvent *e)
{
    if (e->delta() > 0) {
        deviation = (this->height() - 1) / devide;
    } else {
        deviation = -(this->height() - 1) / devide;
    }

    homing();
    repaint();
}

void NumberPicker::paintEvent(QPaintEvent *)
{
    QPainter painter(this);
    painter.setRenderHint(QPainter::Antialiasing, true);
    int Height = height() - 1;

    if (deviation >= Height / devide && currentValue > minRange ) {
        mouseSrcPos += Height / devide;
        deviation -= Height / devide;
        currentValue -= interval;
        /* 负数处理 */
        if (currentValue < 0)
            currentValue = maxRange + currentValue;
    }

    if (deviation <= -Height / devide && currentValue < maxRange ) {
        mouseSrcPos -= Height / devide;
        deviation += Height / devide;
        currentValue += interval;
    }

    if (qAbs(int(currentValue)) >= int(maxRange))
        currentValue = minRange;

    paintNum(painter, qAbs(int(currentValue + maxRange) % maxRange),
             deviation);

    paintNum(painter,
             qAbs((currentValue - interval + maxRange) % maxRange),
             deviation - Height / devide);

    paintNum(painter,
             qAbs((currentValue + interval + maxRange) % maxRange),
             deviation + Height / devide);

    for (int i = 2; i <= devide / 2; ++i) {
        if (qAbs(currentValue - interval * i) >= minRange) {
            paintNum(painter,
                     qAbs((currentValue - interval * i + maxRange)
                          % maxRange),
                     deviation - Height / devide * i);
        }

        if (qAbs(currentValue + interval * i) <= maxRange) {
            paintNum(painter,
                     qAbs((currentValue + interval * i + maxRange)
                          % maxRange),
                     deviation + Height / devide * i);
        }
    }
}

void NumberPicker::paintNum(QPainter &painter, int num, int deviation)
{
    int Width = width() - 1;
    int Height = height() - 1;

    /* 偏移量越大,数字越小 */
    //int size = (Height - qAbs(deviation)) / numSize;
    int size = (Height - qAbs(deviation)) * numSize / 80;
    int transparency = 255 - 255 * qAbs(deviation) / Height;
    int height = Height / devide;
    int y = Height / 2 + deviation - height / 2;

    QFont font;
    font.setPixelSize(size);
    painter.setFont(font);
    painter.setPen(QColor(numberColor.red(),
                          numberColor.green(),
                          numberColor.blue(),
                          transparency));

    if ( y >= 0 && y + height < Height) {
        //painter.drawRect(0, y, Width, height);
        if (num < 10)
            painter.drawText(QRectF(0, y, Width, height),
                             Qt::AlignCenter,
                             "0" + QString::number(num, 'f', 0));
        else
            painter.drawText(QRectF(0, y, Width, height),
                             Qt::AlignCenter,
                             QString::number(num, 'f', 0));
    }
}

void NumberPicker::homing()
{
    if (deviation > height() / 10) {
        homingAni->setStartValue((height() - 1 ) / 8 - deviation);
        homingAni->setEndValue(0);
        currentValue -= interval;
    } else if (deviation > -height() / 10) {
        homingAni->setStartValue(deviation);
        homingAni->setEndValue(0);
    } else if (deviation < -height() / 10) {
        homingAni->setStartValue(-(height() - 1) / 8 - deviation);
        homingAni->setEndValue(0);
        currentValue += interval;
    }

    emit currentValueChanged(currentValue);
    homingAni->start();
}

int NumberPicker::readDeviation()
{
    return deviation;
}

void NumberPicker::setDeviation(int n)
{
    deviation = n;
    repaint();
}

void NumberPicker::setNumSize(int size)
{
    numSize = size;
    repaint();
}

void NumberPicker::setInterval(int n)
{
    interval = n;
    repaint();
}

void NumberPicker::setDevide(int n)
{
    devide = n;
    repaint();
}

void NumberPicker::setNumberColor(QRgb rgb)
{
    numberColor.setRgb(rgb);
    repaint();
}

void NumberPicker::setValue(int value)
{
    if (value < minRange || value > maxRange) {
        qDebug()<<"数值设置必须在"<<minRange
               <<"和"<<maxRange<<"之间"<<endl;
        return;
    }
    currentValue = value;
    repaint();
}

switchbutton.h

#ifndef SWITCHBUTTON_H
#define SWITCHBUTTON_H

#include <QWidget>
#include <QTimer>

class SwitchButton : public QWidget
{
    Q_OBJECT

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

    /* 返回开关状态 - 打开:true 关闭:false */
    bool isToggled() const;

    /* 设置开关状态 */
    void setToggle(bool checked);

    /* 设置背景颜色 */
    void setBackgroundColor(QColor color);

    /* 设置选中颜色 */
    void setCheckedColor(QColor color);

    /* 设置不可用颜色 */
    void setDisbaledColor(QColor color);

protected:
    /* 绘制开关 */
    void paintEvent(QPaintEvent *event) Q_DECL_OVERRIDE;

    /* 鼠标按下事件 */
    void mousePressEvent(QMouseEvent *event) Q_DECL_OVERRIDE;

    /* 鼠标释放事件 - 切换开关状态、发射toggled()信号 */
    void mouseReleaseEvent(QMouseEvent *event) Q_DECL_OVERRIDE;

    /* 大小改变事件 */
    void resizeEvent(QResizeEvent *event) Q_DECL_OVERRIDE;

    /* 缺省大小 */
    QSize sizeHint() const Q_DECL_OVERRIDE;
    QSize minimumSizeHint() const Q_DECL_OVERRIDE;

signals:
    /* 状态改变时,发射信号 */
    void toggled(bool checked);

private slots:
    /* 状态切换时,用于产生滑动效果 */
    void onTimeout();

private:
    /* 是否选中 */
    bool m_bChecked;

    /* 背景颜色 */
    QColor m_background;

    /* 选中颜色 */
    QColor m_checkedColor;

    /* 不可用颜色 */
    QColor m_disabledColor;

    /* 拇指颜色 */
    QColor m_thumbColor;

    /* 圆角 */
    qreal m_radius;

    /* x点坐标 */
    qreal m_nX;

    /* y点坐标 */
    qreal m_nY;

    /* 高度 */
    qint16 m_nHeight;

    /* 外边距 */
    qint16 m_nMargin;

    /* 定时器 */
    QTimer m_timer;
};
#endif // SWITCHBUTTON_H

switchbutton.cpp

#include "switchbutton.h"

#include <QPainter>
#include <QMouseEvent>

SwitchButton::SwitchButton(QWidget *parent)
    : QWidget(parent),
      m_bChecked(false),
      m_background(Qt::gray),
      m_checkedColor(34, 131, 246),
      m_disabledColor(190, 190, 190),
      m_thumbColor(Qt::gray),
      m_radius(12.5),
      m_nHeight(16),
      m_nMargin(3)
{
    /* 鼠标滑过光标形状 - 手型 */
    setCursor(Qt::PointingHandCursor);

    /* 连接信号槽 */
    connect(&m_timer, SIGNAL(timeout()),
            this, SLOT(onTimeout()));
}

/* 绘制开关 */
void SwitchButton::paintEvent(QPaintEvent *event)
{
    Q_UNUSED(event)

    QPainter painter(this);
    painter.setPen(Qt::NoPen);
    painter.setRenderHint(QPainter::Antialiasing);

    QPainterPath path;
    QColor background;
    QColor thumbColor;
    qreal dOpacity;
    /* 可用状态 */
    if (isEnabled()) {
        /* 打开状态 */
        if (m_bChecked) {
            background = m_checkedColor;
            thumbColor = m_checkedColor;
            dOpacity = 0.600;
            /* 关闭状态 */
        } else {
            background = m_background;
            thumbColor = m_thumbColor;
            dOpacity = 0.800;
        }
        /* 不可用状态 */
    } else {
        background = m_background;
        dOpacity = 0.260;
        thumbColor = m_disabledColor;
    }
    /* 绘制大椭圆 */
    painter.setBrush(background);
    painter.setOpacity(dOpacity);
    path.addRoundedRect(QRectF(m_nMargin,
                               m_nMargin, width() - 2 * m_nMargin,
                               height() - 2 * m_nMargin),
                        m_radius, m_radius);
    painter.drawPath(path.simplified());

    /* 绘制小椭圆 */
    painter.setBrush(thumbColor);
    painter.setOpacity(1.0);
    painter.drawEllipse(QRectF(m_nX - (m_nHeight / 2),
                               m_nY - (m_nHeight / 2),
                               height(),
                               height()));
}

/* 鼠标按下事件 */
void SwitchButton::mousePressEvent(QMouseEvent *event)
{
    if (isEnabled()) {
        if (event->buttons() & Qt::LeftButton) {
            event->accept();
        } else {
            event->ignore();
        }
    }
}

/* 鼠标释放事件 - 切换开关状态、发射toggled()信号 */
void SwitchButton::mouseReleaseEvent(QMouseEvent *event)
{
    if (isEnabled()) {
        if ((event->type() == QMouseEvent::MouseButtonRelease)
                && (event->button() == Qt::LeftButton)) {
            event->accept();
            m_bChecked = !m_bChecked;
            emit toggled(m_bChecked);
            m_timer.start(10);
        } else {
            event->ignore();
        }
    }
}

/* 大小改变事件 */
void SwitchButton::resizeEvent(QResizeEvent *event)
{
    m_nX = m_nHeight / 2;
    m_nY = m_nHeight / 2;
    QWidget::resizeEvent(event);
}

/* 默认大小 */
QSize SwitchButton::sizeHint() const
{
    return minimumSizeHint();
}

/* 最小大小 */
QSize SwitchButton::minimumSizeHint() const
{
    return QSize(2 * (m_nHeight + m_nMargin),
                 m_nHeight + 2 * m_nMargin);
}

/* 切换状态 - 滑动 */
void SwitchButton::onTimeout()
{
    if (m_bChecked) {
        m_nX += 1;
        if (m_nX >= width() - m_nHeight - m_nHeight / 2 ) {
            m_timer.stop();
            m_nX -= 1;
        }
    } else {
        m_nX -= 1;
        if (m_nX <= m_nHeight / 2) {
            m_timer.stop();
            m_nX += 1;
        }
    }
    update();
}

/* 返回开关状态 - 打开:true 关闭:false */
bool SwitchButton::isToggled() const
{
    return m_bChecked;
}

/* 设置开关状态 */
void SwitchButton::setToggle(bool checked)
{
    m_bChecked = checked;
    m_timer.start(10);
}

/* 设置背景颜色 */
void SwitchButton::setBackgroundColor(QColor color)
{
    m_background = color;
}

/* 设置选中颜色 */
void SwitchButton::setCheckedColor(QColor color)
{
    m_checkedColor = color;
}

/* 设置不可用颜色 */
void SwitchButton::setDisbaledColor(QColor color)
{
    m_disabledColor = color;
}

main.cpp

#include "mainwindow.h"

#include <QApplication>
#include <QFile>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    /* 指定文件 */
    QFile file(":/style.qss");

    /* 判断文件是否存在 */
    if (file.exists() ) {
        /* 以只读的方式打开 */
        file.open(QFile::ReadOnly);
        /* 以字符串的方式保存读出的结果 */
        QString styleSheet = QLatin1String(file.readAll());
        /* 设置全局样式 */
        qApp->setStyleSheet(styleSheet);
        /* 关闭文件 */
        file.close();
    }

    MainWindow w;
    w.show();
    return a.exec();
}

style.qss

QListWidget {
font-size: 30px;
outline:none;
}

QListWidget::item:active {
background: transparent;
}

QListWidget::item {
height:80;
}

QListWidget::item:selected:hover {
background:#22222222;
}

QListWidget::item:selected {
background:transparent;
color:#ee222222;
}

QPushButton#addAlarm {
border-image:url(:/icons/addalarm1.png);
background:transparent;
outline: none;
}

QPushButton#addAlarm:hover {
border-image:url(:/icons/addalarm2.png);
}

QPushButton#yesButton {
border: 1px solid #22222222;
border-radius: 25px;
background:#22222222;
outline:none;
}

QPushButton#yesButton:pressed {
background:#44222222;
color:white;
}

QPushButton#cancelButton {
border: 1px solid #22222222;
border-radius: 25px;
background:#22222222;
outline:none;
}

QPushButton#cancelButton:pressed {
background:#44222222;
color:white;
}

QScrollBar:vertical {
width:30px;
background:rgba(255, 255, 255, 100%)
}

QScrollBar::handle:vertical {
width:30px;
background:rgba(200, 200, 200, 20%);
border-radius:15px;
}

QScrollBar::add-line:vertical {
width:0px; height:0px;
}
QScrollBar::sub-line:vertical {
width:0px;
height:0px;
}
QScrollBar::handle:vertical:hover {
width:30px;
background:rgba(200, 200, 200, 80%);
border-radius:15px;
}
QScrollBar::add-page:vertical,QScrollBar::sub-page:vertical {
background:rgba(255, 255, 255, 100%)
}

标签:info,deviation,int,void,闹钟,sql,model,include,制作
来源: https://www.cnblogs.com/yoshinb/p/16343409.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有