QML 中的时间输入字段
Time input field in QML
我需要在 QML 中实现一个 TimeEdit
(HH:MM:SS) 字段,类似于 QT C++ 中的 QTimeEdit
。在 QML 中,我没有找到 TimeEdit,我已经使用 TextField
实现了类似于 TimeEdit 的控件,如果我添加 inputMask,那么 正则表达式 根本没有经过验证,有什么办法可以实现这一目标吗?以下是代码。
import QtQuick 2.7
import QtQuick.Window 2.2
import QtQuick.Controls 2.2
Window {
visible: true
width: 640
height: 480
title: qsTr("Time Edit")
TextField{
id:textEditTD
text : ""
inputMethodHints: Qt.ImhDigitsOnly
inputMask: "dd:dd:dd; "
validator: RegExpValidator { regExp: /^([0-1]?[0-9]|2[0-3]):([0-5][0-9]):[0-5][0-9]$ / }
width:100
height:50
background:Rectangle{
color:"transparent"
border.color: "red"
border.width:2
radius:(width * 0.05)
}
}
}
我使用以下组合 "round-down" QValidator
-派生的时间输入自定义验证器(添加秒数很简单):
#pragma once
#include <QTime>
#include <QValidator>
// almost equiv to RegExpValidator { regExp: /(([01][0-9])|(2[0-3])):([0-5][0-9])/ }
class TimeValidator
: public QValidator
{
Q_OBJECT
public :
explicit TimeValidator(QObject * const parent = Q_NULLPTR)
: QValidator{parent}
{ ; }
virtual
State validate(QString & input, int & pos) const Q_DECL_OVERRIDE
{
Q_UNUSED(pos);
const auto parts = input.splitRef(':');
if (parts.length() != 2) {
input = QStringLiteral("00:00");
} else {
const int hours = qBound(0, parts.first().toInt(), 23);
const int minutes = qBound(0, parts.last().toInt(), 59);
const QTime time{hours, minutes};
Q_ASSERT(time.isValid());
input = time.toString("hh:mm");
}
return Acceptable;
}
};
template< typename T >
int qmlRegisterClass(int versionMajor = 1, int versionMinor = 0)
{
const auto className = T::staticMetaObject.className();
return ::qmlRegisterType< T >(className, versionMajor, versionMinor, className);
}
// ...
qmlRegisterClass< TimeValidator >();
和TextFiled
与inputMask
:
import TimeValidator 1.0
TextField {
id: timePicker
verticalAlignment: TextInput.AlignVCenter
horizontalAlignment: TextInput.AlignHCenter
text: "00:00"
inputMask: "00:00;_"
validator: TimeValidator {}
inputMethodHints: Qt.ImhDigitsOnly
// placeholderText: "00:00" // for implicitWidth
// Layout.minimumWidth: implicitWidth
// Layout.fillWidth: true
}
我找到了两种实现方法:
1) 我对 Orient 答案进行了更改以满足我的要求,以下是按下 backspace
时有效的更改:
virtual
State validate(QString & input, int & pos) const Q_DECL_OVERRIDE
{
const QStringList parts = input.split(":");
if (parts.length() != 3) {
input = QStringLiteral("00:00:00");
}
else
{
int hours = 0;
int minutes = 0;
int seconds = 0;
//hours
if(parts[0].toInt() > 23){
hours = 23;
pos +=1; //Increment the position
}
else{
QString str = parts[0];
if(str.contains(" ")){
str.replace(" ","0");
}
hours = str.toInt();
}
// Minutes
if(parts[1].toInt() > 59){
minutes = 59;
pos +=1; //Increment the position
}
else{
QString str = parts[1];
if(str.contains(" ")){
str.replace(" ","0");
}
minutes = str.toInt();
}
//Seconds
if(parts[2].toInt() > 59){
seconds = 59;
pos +=1; //Increment the position
}
else{
QString str = parts[2];
if(str.contains(" ")){
str.replace(" ","0");
}
seconds = str.toInt();
}
const QTime time{hours, minutes,seconds};
Q_ASSERT(time.isValid());
input = time.toString("hh:mm:ss");
}
return Acceptable;
}
2) 只需更改 inputMask
和 RegExp
,这非常简单:
inputMask: "99:99:99"
validator: RegExpValidator { regExp: /^([0-1\s]?[0-9\s]|2[0-3\s]):([0-5\s][0-9\s]):([0-5\s][0-9\s])$ / }
我需要在 QML 中实现一个 TimeEdit
(HH:MM:SS) 字段,类似于 QT C++ 中的 QTimeEdit
。在 QML 中,我没有找到 TimeEdit,我已经使用 TextField
实现了类似于 TimeEdit 的控件,如果我添加 inputMask,那么 正则表达式 根本没有经过验证,有什么办法可以实现这一目标吗?以下是代码。
import QtQuick 2.7
import QtQuick.Window 2.2
import QtQuick.Controls 2.2
Window {
visible: true
width: 640
height: 480
title: qsTr("Time Edit")
TextField{
id:textEditTD
text : ""
inputMethodHints: Qt.ImhDigitsOnly
inputMask: "dd:dd:dd; "
validator: RegExpValidator { regExp: /^([0-1]?[0-9]|2[0-3]):([0-5][0-9]):[0-5][0-9]$ / }
width:100
height:50
background:Rectangle{
color:"transparent"
border.color: "red"
border.width:2
radius:(width * 0.05)
}
}
}
我使用以下组合 "round-down" QValidator
-派生的时间输入自定义验证器(添加秒数很简单):
#pragma once
#include <QTime>
#include <QValidator>
// almost equiv to RegExpValidator { regExp: /(([01][0-9])|(2[0-3])):([0-5][0-9])/ }
class TimeValidator
: public QValidator
{
Q_OBJECT
public :
explicit TimeValidator(QObject * const parent = Q_NULLPTR)
: QValidator{parent}
{ ; }
virtual
State validate(QString & input, int & pos) const Q_DECL_OVERRIDE
{
Q_UNUSED(pos);
const auto parts = input.splitRef(':');
if (parts.length() != 2) {
input = QStringLiteral("00:00");
} else {
const int hours = qBound(0, parts.first().toInt(), 23);
const int minutes = qBound(0, parts.last().toInt(), 59);
const QTime time{hours, minutes};
Q_ASSERT(time.isValid());
input = time.toString("hh:mm");
}
return Acceptable;
}
};
template< typename T >
int qmlRegisterClass(int versionMajor = 1, int versionMinor = 0)
{
const auto className = T::staticMetaObject.className();
return ::qmlRegisterType< T >(className, versionMajor, versionMinor, className);
}
// ...
qmlRegisterClass< TimeValidator >();
和TextFiled
与inputMask
:
import TimeValidator 1.0
TextField {
id: timePicker
verticalAlignment: TextInput.AlignVCenter
horizontalAlignment: TextInput.AlignHCenter
text: "00:00"
inputMask: "00:00;_"
validator: TimeValidator {}
inputMethodHints: Qt.ImhDigitsOnly
// placeholderText: "00:00" // for implicitWidth
// Layout.minimumWidth: implicitWidth
// Layout.fillWidth: true
}
我找到了两种实现方法:
1) 我对 Orient 答案进行了更改以满足我的要求,以下是按下 backspace
时有效的更改:
virtual
State validate(QString & input, int & pos) const Q_DECL_OVERRIDE
{
const QStringList parts = input.split(":");
if (parts.length() != 3) {
input = QStringLiteral("00:00:00");
}
else
{
int hours = 0;
int minutes = 0;
int seconds = 0;
//hours
if(parts[0].toInt() > 23){
hours = 23;
pos +=1; //Increment the position
}
else{
QString str = parts[0];
if(str.contains(" ")){
str.replace(" ","0");
}
hours = str.toInt();
}
// Minutes
if(parts[1].toInt() > 59){
minutes = 59;
pos +=1; //Increment the position
}
else{
QString str = parts[1];
if(str.contains(" ")){
str.replace(" ","0");
}
minutes = str.toInt();
}
//Seconds
if(parts[2].toInt() > 59){
seconds = 59;
pos +=1; //Increment the position
}
else{
QString str = parts[2];
if(str.contains(" ")){
str.replace(" ","0");
}
seconds = str.toInt();
}
const QTime time{hours, minutes,seconds};
Q_ASSERT(time.isValid());
input = time.toString("hh:mm:ss");
}
return Acceptable;
}
2) 只需更改 inputMask
和 RegExp
,这非常简单:
inputMask: "99:99:99"
validator: RegExpValidator { regExp: /^([0-1\s]?[0-9\s]|2[0-3\s]):([0-5\s][0-9\s]):([0-5\s][0-9\s])$ / }