前言

现在比较闲,我就把手上的项目写了两个版本:一版QtWidgets c++实现的;另一版 qml 加少量c++实现的(当然还没写完)。可能我用QtWidgets用习惯了,感觉qml少很多控件,然后很多东西需要自己写:我发现qml没有时间日期编辑器/选择器,所以我模仿了QDateTimeEdit,根据思路的不同写了两个版本。

代码和说明

QDateTimeEdit可以通过两种方式修改:一则是直接编辑修改;二呢,是通过按钮上下调。

为了直接修改,时间数据不会错,所以我加了验证器(validator)属性,这部分是通过c++ 继承QValidator实现的

//DateTimeValidator.h
#ifndef DATETIMEVALIDATOR_H
#define DATETIMEVALIDATOR_H#include <QValidator>
#include<QDateTime>class DateTimeValidator : public QValidator
{Q_OBJECT
public:DateTimeValidator();State validate(QString& input, int& pos) const;
};#endif // DATETIMEVALIDATOR_H
//DateTimeValidator.cpp
#include "DateTimeValidator.h"DateTimeValidator::DateTimeValidator()
{}QValidator::State DateTimeValidator::validate(QString &input, int &pos) const
{QDateTime dt = QDateTime::fromString(input, "yyyy-MM-dd HH:mm");if (dt.isNull()) // If null, the input cannot be parsed{return QValidator::Invalid;}return QValidator::Acceptable;
}

然后在main.cpp中注册此属性

qmlRegisterType<DateTimeValidator>("my.components", 1, 0, "DateTimeValidator");

纯字符串操作版本

qml没有关于日期时间的类,挨边的只有一个日历,但是不是我想要的。所以若想改变它的值——字符串,好像可以通过直接修改对应的字符实现,所以就有了这个版本:通过光标的位置,得知需要修改的部分(年/月/日/时/分),然后加减后,再拼成字符串写入就行了。注意:月、日、时和分他们的值可能是一位(即小于10),前面要加'0';还有大小月,闰年的区分。

这个版本和JS Date版本稍微有点不同:这个版本达到极限值后,就不响应了,比如若秒达到59后将不再响应加操作,一直停留在59(当然若你想59后面从0开始也可以,一句话的事儿)。而JS版本若达到极限值后再操作(加/减),将影响到上一位。

这个属于最初版本可能看着很繁琐,可以精简,而且存在着小bug,但是我懒,就先这样吧

import QtQuick 2.0
import QtQuick.Controls 1.2
import my.components 1.0
TextField {id:dateEdit;text : "2020-07-30 00:00"inputMask: "9999-99-99 99:99"validator: DateTimeValidator {}Rectangle{id:upArrow;x:dateEdit.width-13; y:2;width: 9;height: (dateEdit.height-8)/2;color: "#00000000";Image{anchors.centerIn: parent;width: 9;height: 5;source: "qrc:/img/dateUp.png";}MouseArea{anchors.fill: parent;onPressed: upArrow.color="#cfcfcf";onReleased: upArrow.color="#00000000";onClicked:{var pos=dateEdit.cursorPosition;var txt=dateEdit.text;if(pos<4){//年份var year=txt.substr(0,4);year=parseInt(year);var other=txt.substr(4);txt=(year+1).toString().concat(other);}else if(pos>=4&&pos<=6){//月份var month=txt.substr(5,2)month=parseInt(month);if(month===12){return;}month=month+1;if(month<10)month=0+month.toString();elsemonth=month.toString();other=txt.substr(0,5);var other2=txt.substr(7);txt=other+month+other2;}else if(pos>=7&&pos<=9){//天数var day=txt.substr(8,2);month=parseInt(txt.substr(5,2));if(month===1||month===3||month===5||month===7||month===8||month===10||month===12){if(day==="31")return}else if(month===2){year=parseInt(txt.substr(0,4));if (year%100!=0&&year%4==0||year%400==0){//闰年if(day==="29")return;}else{//平年if(day==="28")return}} else{if(day==="30")return;}day=parseInt(day)+1;if(day<10)day=0+day.toString();elseday=day.toString();other=txt.substr(0,8);other2=txt.substr(10);txt=other+day+other2;}else if(pos>=10&&pos<=12){var hour=txt.substr(11,2);if(hour==="23")return;hour=parseInt(hour)+1;if(hour<10)hour=0+hour.toString();elsehour=hour.toString();other=txt.substr(0,11);other2=txt.substr(13);txt=other+hour+other2;}else{var min=txt.substr(14,2);if(min==="59")return;min=parseInt(min)+1;if(min<10)min=0+min.toString();elsemin=min.toString();other=txt.substr(0,14);txt=other+min;}dateEdit.text=txt;dateEdit.cursorPosition=pos;}}}Rectangle{id:downArrow;anchors.left: upArrow.left;anchors.top: upArrow.bottom;anchors.topMargin: 4;width: upArrow.width;height: upArrow.height;Image{anchors.centerIn: parent;width: 9;height: 5;source: "qrc:/img/dateDown.png";}MouseArea{anchors.fill: parent;onPressed: downArrow.color="#cfcfcf";onReleased: downArrow.color="#00000000";onClicked:{var pos=dateEdit.cursorPosition;var txt=dateEdit.text;if(pos<4){//年份var year=txt.substr(0,4);year=parseInt(year);var other=txt.substr(4);txt=(year-1).toString().concat(other);}else if(pos>=4&&pos<=6){//月份var month=txt.substr(5,2)month=parseInt(month);if(month===1){return;}month=month-1;if(month<10)month=0+month.toString();elsemonth=month.toString();other=txt.substr(0,5);var other2=txt.substr(7);txt=other+month+other2;}else if(pos>=7&&pos<=9){//天数var day=txt.substr(8,2);month=parseInt(txt.substr(5,2));if(day==="01")return;day=parseInt(day)-1;if(day<10)day=0+day.toString();elseday=day.toString();other=txt.substr(0,8);other2=txt.substr(10);txt=other+day+other2;}else if(pos>=10&&pos<=12){var hour=txt.substr(11,2);if(hour==="00")return;hour=parseInt(hour)-1;if(hour<10)hour=0+hour.toString();elsehour=hour.toString();other=txt.substr(0,11);other2=txt.substr(13);txt=other+hour+other2;}else{var min=txt.substr(14,2);if(min==="00")return;min=parseInt(min)-1;if(min<10)min=0+min.toString();elsemin=min.toString();other=txt.substr(0,14);txt=other+min;}dateEdit.text=txt;dateEdit.cursorPosition=pos;}}}}

JS Date版本

这个版本逻辑主要是靠JS Date实现的,说实话我不太会,所以我是对着教程敲的(附赠网络地址)。这个参考了一些网上的对Date的操作(Date转字符串,字符串转Date),整体逻辑比上一个清晰很多,看着也舒服优雅一些。

import QtQuick 2.0
import QtQuick.Controls 1.2
import my.components 1.0
TextField {id:dateEdit;text : "2020-07-30 00:00"inputMask: "9999-99-99 99:99"validator: DateTimeValidator {}Rectangle{id:upArrow;x:dateEdit.width-13; y:2;width: 9;height: (dateEdit.height-8)/2;Image{anchors.centerIn: parent;width: 9;height: 5;source: "qrc:/img/dateUp.png";}MouseArea{anchors.fill: parent;onPressed: upArrow.color="#cfcfcf";onReleased: upArrow.color="#00000000";onClicked:{operateDateTime(1);}}}Rectangle{id:downArrow;anchors.left: upArrow.left;anchors.top: upArrow.bottom;anchors.topMargin: 4;width: upArrow.width;height: upArrow.height;Image{anchors.centerIn: parent;width: 9;height: 5;source: "qrc:/img/dateDown.png";}MouseArea{anchors.fill: parent;onPressed: downArrow.color="#cfcfcf";onReleased: downArrow.color="#00000000";onClicked:{operateDateTime(-1);}}}function operateDateTime(operate){var pos=dateEdit.cursorPosition;var txt=dateEdit.text;txt=txt+":00";var date=convertDateFromString(txt);var str=date.toString();if(pos<4){//年份date.setFullYear(date.getFullYear()+operate);}else if(pos>=4&&pos<=6){//月份date.setMonth(date.getMonth()+operate);}else if(pos>=7&&pos<=9){//天数date.setDate(date.getDate()+operate);}else if(pos>=10&&pos<=12){//小时date.setHours(date.getHours()+operate);}else{//分钟date.setMinutes(date.getMinutes()+operate);}str=date.toString();txt=dateFormat(date,"yyyy-MM-dd hh:mm");dateEdit.text=txt;dateEdit.cursorPosition=pos;}function checkNull(value) {return (!value || value == null || typeof(value) == "undefined" || value == "");}// 填充0function fillZero(value) {return value.toString().length < 2 ? ('0' + value) : value}//字符串转Datefunction  convertDateFromString(dateString) {if (dateString) {var arr1 = dateString.split(" ");var sdate = arr1[0].split('-');var stime=arr1[1].split(':');var date = new Date(sdate[0], sdate[1]-1, sdate[2],stime[0],stime[1],stime[2]);return date;}}//Date通过格式str转为字符串function dateFormat(d, str) {var formatStr = checkNull(str) ? 'yyyy-MM-dd HH:mm:ss' : str;if (checkNull(d)) { // 如果日期为空,自动获取当前日期d = new Date();} else if (d.constructor != Date) { // 如果参数不是一个日期对象,就认为是一个标准Long值日期d = new Date(d);}return formatStr .replace("yyyy", d.getFullYear()).replace("MM", fillZero(d.getMonth() + 1)).replace("dd", fillZero(d.getDate())).replace("hh", fillZero(d.getHours())).replace("mm", fillZero(d.getMinutes())).replace("ss",fillZero(d.getSeconds())).replace("sss", d.getMilliseconds());}
}

效果图

结束语

日期时间编辑器本来觉得挺简单的东西,结果折腾挺久,感觉想学好qml道阻且长啊!

日期时间编辑器(模拟QDateTimeEdit的自定义控件)——QML相关推荐

  1. python日历gui_python GUI库图形界面开发之PyQt5日期时间控件QDateTimeEdit详细使用方法与实例...

    PyQt5日期时间控件QDateTimeEdit介绍 QDateTimeEdit是一个允许用户编辑日期时间的控件,可以使用键盘上的上下键头按钮来增加或减少日期的时间值,QDateTimeEdit通过s ...

  2. PyQt5之QDateTimeEdit编辑日期时间

    PyQt5之QDateTimeEdit QDateTimeEdit是一个允许用户编辑日期时间的控件,可以使用键盘来增加或减少日期时间值.QDateTimeEdit通过setDisplayFormat( ...

  3. java 时间处理_JAVA处理日期时间常用方法

    Calendar 类是一个抽象类,它为特定瞬间与一组诸如 YEAR.MONTH.DAY_OF_MONTH.HOUR 等 日历字段之间的转换提供了一些方法,并为操作日历字段(例如获得下星期的日期)提供了 ...

  4. mysql添加字符串日期时间_mysql学习笔记--- 字符串函数、日期时间函数

    一.常见字符串函数:1.CHAR_LENGTH  获取长度(字符为单位) 2.FORMAT  格式化 3.INSERT  替换的方式插入 4.INSTR  获取位置 5.LEFT/RIGHT  取左. ...

  5. JavaScrpit+Html实现日期时间启动、停止操作(应用场景:计时器、秒表)

    JavaScrpit+Html实现日期时间启动.停止操作(应用场景:计时器.秒表) 文章目录 JavaScrpit+Html实现日期时间启动.停止操作(应用场景:计时器.秒表) 前言 一.什么是Jav ...

  6. 彻底弄透Java处理GMT/UTC日期时间

    平时工作中遇到时间如何处理?用Date还是JDK 8之后的日期时间API?如何解决跨时区转换等等头大问题.A哥向来管生管养,管杀管埋,因此本文就带你领略一下,Java是如何实现GMT和UTC的? 众所 ...

  7. WPF自定义日期时间控件

    WPF自定义日期时间控件 一.需求分析 二.功能实现 一.需求分析 在工作中遇到的项目中,大部分软件是处于全屏运行状态,这时候就需要在软件的界面上加上日期时间那些,方便用户查看当前时间. 二.功能实现 ...

  8. 一文告诉你Java日期时间API到底有多烂

    前言 你好,我是A哥(YourBatman). 好看的代码,千篇一律!难看的代码,卧槽卧槽~其实没有什么代码是"史上最烂"的,要有也只有"史上更烂". 日期是商 ...

  9. mysql 库比对_库比蒂诺日期时间选择器

    mysql 库比对 Easily pick a Date or a Time in your Flutter app 在Flutter应用中轻松选择日期或时间 I wrote a routine to ...

  10. Day640.Java 8的日期时间类问题 -Java业务开发常见错误

    Java 8的日期时间类问题 Hi,阿昌来也! 今天记录分享的是Java 8的日期时间类问题 在 Java 8 之前,我们处理日期时间需求时,使用 Date.Calender 和 SimpleDate ...

最新文章

  1. 突发!美国最大输油管道遭网络攻击关闭!美媒:为其基础设施的脆弱堪忧
  2. Java 基础 之 常量
  3. 记录一下有关ChArUco标定板
  4. property Alternative forms propretie
  5. 公有云私有云的区别_一分钟秒懂公有云、私有云、混合云的区别?
  6. inline ,inline-block ,block
  7. DM8168 开发环境搭建
  8. 人类大脑每日24小时工作节奏表
  9. 无监督学习 k-means_无监督学习-第1部分
  10. 第一人称视角获得运动方向和视角的夹角
  11. thinkphp一句话疑难解决笔记
  12. phpcmsV9内容页hits点击量 - 调用总结
  13. 征稿 | 计算机视觉与数据挖掘-EI会议 ICCVDM2020
  14. 计算机视觉图像去噪原理,AI笔记: 计算机视觉之图像滤波去噪: 原理、方法和效果比较...
  15. 搭建STM32开发环境——STM32CubeMX并配合Keil5重写跑马灯程序
  16. C语言指针面试题详解
  17. 输入整形 matlab仿真
  18. Windows 7远程桌面 重启 关机 任务管理器 命令
  19. 计算机网络中如何看别人的共享文件夹,教大家如何使用网络共享文件夹和手机如何使用电脑端查看网络共享-共享文件夹...
  20. VirtualBox中虚拟机的克隆方法

热门文章

  1. win的名词_英语语法系列:名词性从句
  2. thought works培训总结
  3. 压缩照片大小——PPT实现
  4. 使用python来搭建一个简易的文件下载环境以及用droopy来实现一个文件上传环境
  5. 搜狗批量推送软件-搜狗批量推送工具【2022最新】
  6. 区块链开发团队,公链开发才是主战场
  7. 航空公司客户价值特征构建与分析k-means
  8. [Android稳定性] Android Fd Leak问题分析方法
  9. 51单片机学习笔记(郭天祥版)(5)——作业讲解、独立键盘、矩阵键盘
  10. 郭天祥51单片机笔记(一)