使用sql制作闹钟
效果
代码
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%)
}
主要是给自己看的,所以肯定会出现很多错误哈哈哈哈哈