基于 QT 实现 Task Timer,高效利用时间
一、开发环境
Ubuntu 20.04
QT6.0
二、新建 Qt Wigets Application
这里的基类选择 Wigets,


pro 配置文件添加 sql 模块,需要用到 sqlite,
QT += sql

三、添加数据库连接头文件

// connection.h
#ifndef CONNECTION_H
#define CONNECTION_H#include <QMessageBox>
#include <QSqlDatabase>
#include <QSqlQuery>
#include <QSqlError>
#include <QDebug>static bool createConnection()
{QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");db.setDatabaseName(":memory:");//db.setDatabaseName("ikun.db");bool res = db.open();if (res){qDebug() << "open ikun.db ok !";}else{qDebug() << "open ikun.db fail: " << db.lastError().text();}QSqlQuery query;if(!query.exec("create table task_history(id INTEGER PRIMARY KEY AUTOINCREMENT,task_name varchar(200) not null, cost_time varchar(20) not null, create_time varchar(25) not null)")){qDebug() << "create table task_history error: " << query.lastError().text();}return true;
}
#endif // CONNECTION_H
初始化连接到 sqlite 数据库,这里使用的内存数据库,没有持久化到磁盘,连接数据库之后创建了一个表 task_history ,主键为 id 自增,任务事项 task_name 以及消耗时间 cost_time,
四、布局设计
一个 QLineEdit 用于输入任务事项,一个 QLCDNumber 用于计时,一个 QPlainTextEdit 用于输出日志,两个 QPushButton 用于操作开始计时和终止计时,


除了组件的布局调整,还需要在主窗体新增一个槽函数 on_Widget_customContextMenuRequested ,在添加右键菜单功能时需要用到,
五、修改 widget.h
#ifndef WIDGET_H
#define WIDGET_H#include <QWidget>
#include <QDateTime>
#include <QTimer>
#include <QTime>
#include <QSqlQuery>
#include <QSqlError>
#include <QDebug>QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACEclass Widget : public QWidget
{Q_OBJECTpublic:Widget(QWidget *parent = nullptr);~Widget();
protected:void mousePressEvent(QMouseEvent *event);void mouseMoveEvent(QMouseEvent *event);void paintEvent(QPaintEvent *);
protected:QPoint pos;QTimer * timer;QTime * timeRecord;bool isStart;
private slots:void update_time();void on_start_btn_clicked();void get_todo_summary();void on_end_btn_clicked();void on_Widget_customContextMenuRequested(const QPoint &pos);private:Ui::Widget *ui;
};
#endif // WIDGET_H
头文件中主要定义了计时器的成员属性与成员方法、鼠标事件、绘画事件以及对应的槽方法,
六、修改 widget.cpp
#include "widget.h"
#include "ui_widget.h"
#include <qpainter.h>
#include <QMouseEvent>
#include <QPaintEvent>
#include <QMessageBox>
#include <QMenu>
#include <QSqlQueryModel>
#include <QTableView>
#include <QDateTime>
#include <QScreen>Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);this->setWindowFlag(Qt::FramelessWindowHint);this->setAttribute(Qt::WA_TranslucentBackground);this->setWindowFlags(windowFlags() | Qt::WindowStaysOnTopHint);// initthis->isStart = false;this->timer = new QTimer;this->timeRecord = new QTime(0, 0, 0);// connect timer and SLOT functionconnect(this->timer,SIGNAL(timeout()),this,SLOT(update_time()));// menuthis->setContextMenuPolicy(Qt::CustomContextMenu);
}Widget::~Widget()
{delete ui;
}void Widget::mousePressEvent(QMouseEvent* ev)
{if(ev->button()==Qt::LeftButton){pos=ev->pos();}
}void Widget::mouseMoveEvent(QMouseEvent*ev)
{if(ev->buttons()==Qt::LeftButton){int x,y;x=ev->pos().x()-pos.x();y=ev->pos().y()-pos.y();this->move(this->x()+x,this->y()+y);}
}void Widget::paintEvent(QPaintEvent *)
{QPainter painter(this);QPixmap pixmap;pixmap.load(QString("../MyPet/image/pikakun.png"));painter.drawPixmap(0, 0, 128, 128, pixmap);
}void Widget::on_start_btn_clicked()
{if(this->ui->todo_line->text().trimmed().length() == 0 ){QMessageBox::warning(this, tr("warning"), tr("please input todo first!"), QMessageBox::Yes);this->ui->todo_line->setFocus();return;}this->ui->todo_line->setEnabled(false);this->ui->last_log->setPlainText(QString("Mission " + this->ui->todo_line->text().trimmed() + " is timing..."));if(!this->isStart){this->timer->start(128);this->ui->start_btn->setText(QString("Pause"));}else{this->timer->stop();this->ui->start_btn->setText(QString("Continue"));}this->isStart = !this->isStart;
}void Widget::update_time()
{// timer add 1 secs, and then display*this->timeRecord = this->timeRecord->addMSecs(128);this->ui->timer->display(this->timeRecord->toString(QString("hh:mm:ss.zzz")));
}void Widget::on_end_btn_clicked()
{// stop timerthis->timer->stop();// show logthis->ui->last_log->setPlainText(QString(this->ui->todo_line->text() +" Cost Time " +this->timeRecord->toString(QString("hh:mm:ss.zzz"))));// save dbQSqlDatabase::database().transaction();QSqlQuery query;query.prepare(QString("insert into task_history(task_name, cost_time, create_time ) ""values(:task_name, :cost_time,:create_time)"));query.bindValue(":task_name", this->ui->todo_line->text());query.bindValue(":cost_time", this->timeRecord->toString(QString("hh:mm:ss.zzz")));QDateTime dt =QDateTime::currentDateTime();// format yyyy//MM/dd hh:mm:s.zzzQString create_time = dt.toString("yyyy-MM-dd hh:mm:ss.zzz");query.bindValue(":create_time", create_time);if(!query.exec()){qDebug() << "insert into task_history error: " << query.lastError().text();}QSqlDatabase::database().commit();// reset displaythis->timeRecord->setHMS(0,0,0);this->ui->timer->display(this->timeRecord->toString(QString("hh:mm:ss.zzz")));this->isStart = false;this->ui->start_btn->setText(QString("Start"));// reset todo_linethis->ui->todo_line->clear();this->ui->todo_line->setEnabled(true);this->ui->todo_line->setFocus();
}void Widget::get_todo_summary()
{QSqlQueryModel *model = new QSqlQueryModel(this);model->setQuery("select * from task_history");model->setHeaderData(0, Qt::Horizontal, tr("ID"));model->setHeaderData(1, Qt::Horizontal, tr("Task"));model->setHeaderData(2, Qt::Horizontal, tr("Time"));model->setHeaderData(3, Qt::Horizontal, tr("LogTime"));QTableView *view = new QTableView;view->setWindowTitle(QString("summary"));view->setModel(model);// must after setModelview->setColumnWidth(1,250);view->setColumnWidth(3,150);QSize *min_size = new QSize;min_size->setWidth(620);min_size->setHeight(400);view->setMinimumSize(*min_size);QScreen *screen = QApplication::primaryScreen();QSize screenSize = screen->size();view->move(( screenSize.width() - min_size->width() ) / 2 , ( screenSize.height() - view->height() ) / 2 );view->show();// free memdelete min_size;
}void Widget::on_Widget_customContextMenuRequested(const QPoint &pos)
{QMenu *menu = new QMenu(this);QAction *summary = new QAction( QIcon(QString("../MyPet/image/pikakun.png")),tr("summary"), this);menu->addAction(summary);connect(summary, SIGNAL(triggered()), this, SLOT(get_todo_summary()));menu->exec(cursor().pos());
}
七、修改 main.cpp
初始化数据库连接,并将窗口移动至屏幕的中间位置,
#include "widget.h"
#include "connection.h"
#include <QApplication>
#include <QLocale>
#include <QTranslator>
#include <QScreen>int main(int argc, char *argv[])
{QApplication a(argc, argv);if (!createConnection()){return 1;}QTranslator translator;const QStringList uiLanguages = QLocale::system().uiLanguages();for (const QString &locale : uiLanguages) {const QString baseName = "MyPet_" + QLocale(locale).name();if (translator.load(":/i18n/" + baseName)) {a.installTranslator(&translator);break;}}Widget w;QScreen *screen = QApplication::primaryScreen();QSize screenSize = screen->size();w.move(( screenSize.width() - w.width() ) / 2 , ( screenSize.height() - w.height() ) / 2 );w.show();return a.exec();
}
八、效果演示

1、输入需要计时的事项后,点击“Start”按钮开始计时
2、开始计时后,“Start”按钮会变成“Pause”按钮,点击该按钮会暂停计时
3、暂停后,“Pause”按钮会变成“Continue”按钮,点击该按钮会继续计时
4、点击“End”按钮后,停止计时,并记录事项耗时到 sqlite 数据库中
5、右键有“Summary”菜单,点击后可以看到事项汇总
特别注意,如果需要将数据从内存中持久化到硬盘,则修改 connection.h,
# 保存在内存,注释这行
// db.setDatabaseName(":memory:");# 保存在 ikun.db,添加这行
db.setDatabaseName("ikun.db");相关文章:
基于 QT 实现 Task Timer,高效利用时间
一、开发环境 Ubuntu 20.04 QT6.0 二、新建 Qt Wigets Application 这里的基类选择 Wigets, pro 配置文件添加 sql 模块,需要用到 sqlite, QT sql 三、添加数据库连接头文件 // connection.h #ifndef CONNECTION_H #define CONNECTION_…...
图像处理与计算机视觉--第五章-图像分割-霍夫变换
文章目录 1.霍夫变换(Hough Transform)原理介绍2.霍夫变换(Hough Transform)算法流程3.霍夫变换(Hough Transform)算法代码4.霍夫变换(Hough Transform)算法效果 1.霍夫变换(Hough Transform)原理介绍 Hough Transform是一种常用的计算机视觉图形检验方法,霍夫变换一…...
linux下文件操作命令
title: linux下文件操作命令 createTime: 2020-10-29 18:05:52 updateTime: 2020-10-29 18:05:52 categories: linux tags: Linux下文件操作命令 tar命令 使用tar命令一般打包分为两种*.tar ,*.tar.gz 相信大家也使用过tar -zcvf test.tar test/tar -zcvf test.tar.gz test/…...
Golang语法、技巧和窍门
Golang简介 命令式语言静态类型语法标记类似于C(但括号较少且没有分号),结构类似Oberon-2编译为本机代码(没有JVM)没有类,但有带有方法的结构接口没有实现继承。不过有type嵌入。函数是一等公民函数可以返…...
Grander因果检验(格兰杰)原理+操作+解释
笔记来源: 1.【传送门】 2.【传送门】 前沿原理介绍 Grander因果检验是一种分析时间序列数据因果关系的方法。 基本思想在于,在控制Y的滞后项 (过去值) 的情况下,如果X的滞后项仍然有助于解释Y的当期值的变动,则认为 X对 Y产生…...
Python-Flask:编写自动化连接demo脚本:v1.0.0
主函数: # _*_ Coding : UTF-8 _*_ # Time : 13:14 # Author : YYZ # File : Flask # Project : Python_Project_爬虫 import jsonfrom flask import Flask,request,jsonify import sshapi Flask(__name__)# methods: 指定请求方式 接口解析参数host host_info[…...
kafka客户端应用参数详解
一、基本客户端收发消息 Kafka提供了非常简单的客户端API。只需要引入一个Maven依赖即可: <dependency><groupId>org.apache.kafka</groupId><artifactId>kafka_2.13</artifactId><version>3.4.0</version></depend…...
Apache Doris 行列转换可以这样玩
行列转换在做报表分析时还是经常会遇到的,今天就说一下如何实现行列转换吧。 行列转换就是如下图所示两种展示形式的互相转换 1. 行转列 我们来看一个简单的例子,我们要把下面这个表的数据,转换成图二的样式 image-20230914151818953.png …...
【Qt图形视图框架】自定义QGraphicsItem和QGraphicsView,实现鼠标(移动、缩放)及键盘事件、右键事件
自定义QGraphicsItem和QGraphicsView 说明示例myitem.hmyitem.cppmyview.hmyview.cpp调用main.cpp 效果 说明 在使用Qt的图形视图框架实现功能时,一般会在其基础上进行自定义功能实现。 如:滚轮对场景的缩放,鼠标拖动场景中的项,…...
C语言结构体指针学习
结构体变量存放内存中,也有起始地址,定义一个变量来存放这个地址,那这个变量就是结构体指针; typedef struct mydata{int a1;int a2;int a3; }mydata;void CJgtzzView::OnDraw(CDC* pDC) {CJgtzzDoc* pDoc GetDocument();ASSERT…...
华为云云耀云服务器L实例评测|部署在线轻量级备忘录 memos
华为云云耀云服务器L实例评测|部署在线轻量级备忘录 memos 一、云耀云服务器L实例介绍1.1 云服务器介绍1.2 产品优势1.3 应用场景1.4 支持镜像 二、云耀云服务器L实例配置2.1 重置密码2.2 服务器连接2.3 安全组配置 三、部署 memos3.1 memos介绍3.2 Docker 环境搭建…...
详解Avast Driver Updater:电脑驱动更新工具的利器还是多余的软件?
亲爱的读者朋友们,你是不是经常为电脑的驱动问题而烦恼?如果是的话,你可能会对这款软件——Avast Driver Updater 电脑驱动更新工具感兴趣。但在你决定尝试之前,不妨先和我一起深入探讨一下它的优点、缺点以及它适用的使用场景。 …...
大数据Flink(九十五):DML:Window TopN
文章目录 DML:Window TopN DML:Window TopN Window TopN 定义(支持 Streaming):Window TopN 是一种特殊的 TopN,它的返回结果是每一个窗口内的 N 个最小值或者最大值。 应用场景...
使用OKHttpClient访问网络
使用OKHttpClient前要引入依赖: 在build.gradle(Moduel :app)中添加 implementation com.squareup.okhttp3:okhttp:3.14.1 implementation com.squareup.okhttp3:logging-interceptor:3.14.1 implementation com.squareup.okio:okio:1.6.0 1. GET(同步…...
maui 开发AMD CPU踩的坑。
刚换的 amd R7735HS 笔记本,8核16线程,32GB内存。性能得实强悍 。 当需要发布iOS版本时发现,我没有macos ,那就安装个vmware 吧。看了一下Apple 要求以后的发布的APP需要以xcode14.3或以后版本开发的版本,但xcode14.3…...
宝塔反代openai官方API接口详细教程,502 Bad Gateway问题解决
一、前言 宝塔反代openai官方API接口详细教程,实现国内使用ChatGPT502 Bad Gateway问题解决, 此方法最简单快捷,没有复杂步骤,不容易出错,即最简单,零代码、零部署的方法。 二、实现前提 一台海外VPS服务…...
【leetocde】128. 最长连续序列
给定一个未排序的整数数组 nums ,找出数字连续的最长序列(不要求序列元素在原数组中连续)的长度。 请你设计并实现时间复杂度为 O(n) 的算法解决此问题。 示例 1: 输入:nums [100,4,200,1,3,2] 输出:4 …...
【Vue3】动态 class 类
如果你想在 Vue.js 中动态设置元素的 class 类名,你可以使用以下两种主要方式: 绑定一个动态的 class 对象:你可以使用 v-bind 或简写的 : 来绑定一个包含类名的对象,其中类名的键是类名字符串,值是一个布尔值或计算属…...
【Redis】redis基本数据类型详解(String、List、Hash、Set、ZSet)
目录 RedisString(字符串)List(列表)Hash(字典)Set(集合)ZSet(有序集合) Redis Redis有5种基本的数据结构,分别为:string(字符串)、list(列表)、set(集合)、hash(哈希&a…...
ubuntu源码安装aria2
github:GitHub - aria2/aria2: aria2 is a lightweight multi-protocol & multi-source, cross platform download utility operated in command-line. It supports HTTP/HTTPS, FTP, SFTP, BitTorrent and Metalink. 发行说明:GitHub - aria2/aria2 at releas…...
日语AI面试高效通关秘籍:专业解读与青柚面试智能助攻
在如今就业市场竞争日益激烈的背景下,越来越多的求职者将目光投向了日本及中日双语岗位。但是,一场日语面试往往让许多人感到步履维艰。你是否也曾因为面试官抛出的“刁钻问题”而心生畏惧?面对生疏的日语交流环境,即便提前恶补了…...
RocketMQ延迟消息机制
两种延迟消息 RocketMQ中提供了两种延迟消息机制 指定固定的延迟级别 通过在Message中设定一个MessageDelayLevel参数,对应18个预设的延迟级别指定时间点的延迟级别 通过在Message中设定一个DeliverTimeMS指定一个Long类型表示的具体时间点。到了时间点后…...
基于Flask实现的医疗保险欺诈识别监测模型
基于Flask实现的医疗保险欺诈识别监测模型 项目截图 项目简介 社会医疗保险是国家通过立法形式强制实施,由雇主和个人按一定比例缴纳保险费,建立社会医疗保险基金,支付雇员医疗费用的一种医疗保险制度, 它是促进社会文明和进步的…...
质量体系的重要
质量体系是为确保产品、服务或过程质量满足规定要求,由相互关联的要素构成的有机整体。其核心内容可归纳为以下五个方面: 🏛️ 一、组织架构与职责 质量体系明确组织内各部门、岗位的职责与权限,形成层级清晰的管理网络…...
Axios请求超时重发机制
Axios 超时重新请求实现方案 在 Axios 中实现超时重新请求可以通过以下几种方式: 1. 使用拦截器实现自动重试 import axios from axios;// 创建axios实例 const instance axios.create();// 设置超时时间 instance.defaults.timeout 5000;// 最大重试次数 cons…...
Unit 1 深度强化学习简介
Deep RL Course ——Unit 1 Introduction 从理论和实践层面深入学习深度强化学习。学会使用知名的深度强化学习库,例如 Stable Baselines3、RL Baselines3 Zoo、Sample Factory 和 CleanRL。在独特的环境中训练智能体,比如 SnowballFight、Huggy the Do…...
全志A40i android7.1 调试信息打印串口由uart0改为uart3
一,概述 1. 目的 将调试信息打印串口由uart0改为uart3。 2. 版本信息 Uboot版本:2014.07; Kernel版本:Linux-3.10; 二,Uboot 1. sys_config.fex改动 使能uart3(TX:PH00 RX:PH01),并让boo…...
中医有效性探讨
文章目录 西医是如何发展到以生物化学为药理基础的现代医学?传统医学奠基期(远古 - 17 世纪)近代医学转型期(17 世纪 - 19 世纪末)现代医学成熟期(20世纪至今) 中医的源远流长和一脉相承远古至…...
CVE-2020-17519源码分析与漏洞复现(Flink 任意文件读取)
漏洞概览 漏洞名称:Apache Flink REST API 任意文件读取漏洞CVE编号:CVE-2020-17519CVSS评分:7.5影响版本:Apache Flink 1.11.0、1.11.1、1.11.2修复版本:≥ 1.11.3 或 ≥ 1.12.0漏洞类型:路径遍历&#x…...
SQL慢可能是触发了ring buffer
简介 最近在进行 postgresql 性能排查的时候,发现 PG 在某一个时间并行执行的 SQL 变得特别慢。最后通过监控监观察到并行发起得时间 buffers_alloc 就急速上升,且低水位伴随在整个慢 SQL,一直是 buferIO 的等待事件,此时也没有其他会话的争抢。SQL 虽然不是高效 SQL ,但…...
