输入框是必不可少的交互组件,qml提供多种输入框如: TextInput、TextField、TextEdit 和 TextArea,这篇文章重点讲Textinput。
Textinput
Textinput 用于编辑一行文本,类似于 QLineEdit,除了显示光标和文本外,默认并没有边框等装饰性效果,所以重点讲相关设置效果,不讲美化。
1、自适应输入框尺寸
contentWidth
和 contentHeight
属性来根据输入内容的宽高设置背景矩形的大小
2、输入掩码
可以使用输入掩码 inputMask
来限制输入的内容,输入掩码就是使用一些特殊的字符来限制输入的格式和内容,举个简单的例子,你想让用户输入类似于 "2014-01-30" 这种格式的日期, 可以将 inputMask 设置为 "0000-00-00"。可用的掩码字符如下表所示。
字符(必须输入) | 字符(可留空) | 含义 |
---|---|---|
A | a | 只能输入A-Z,a-z |
N | n | 只能输入A-Z,a-z,0-9 |
X | x | 可以输入任意字符 |
9 | 0 | 只能输入0-9 |
D | d | 只能输入1-9 |
# | 只能输入加号(+),减号(-),0-9 | |
H | h | 只能输入十六进制字符,A-F,a-f,0-9 |
B | b | 只能输入二进制字符,0或1 |
字符 | 含义 |
---|---|
> | 后面的字母字符自动转换为大写 |
< | 后面的字母字符自动转换为小写 |
! | 停止字母字符的大小写转换 |
[ ] | 括号中的内容会直接显示出来 |
\ | 将该表中的特殊字符正常显示用作分隔符 |
上代码:
Rectangle {
width: 100
height: 24
color: "lightgrey"
border.color: "grey"
TextInput {
anchors.fill: parent
anchors.margins: 2
font.pointSize: 10
focus: true
inputMask: "9999" //限制输入 数字
validator: IntValidator{ bottom: 11; top: 31; } // 限制输入数字的范围
onEditingFinished :{
console.log("get data is :",text)
}
}
}
3、验证器
除了使用掩码,还可以使用整数验证器 IntValidator
、DoubleValidator(非整数验证器)
和RegExpValidator(正则表达式验证器)
。下面的代码可以限制在 TextInput 中只能输入 11 到 31 之间的整数:
validator: IntValidator{ bottom: 11; top: 31; }
下面代码使用正则表达式:/[0-9A-F]+/
表示只允许输入数字和大写字母 A 到 F。
官网建议使用: RegularExpressionValidator 代替 RegExpValidator,代码人士请多多注意,QT6差不多把它弃用了
validator: RegularExpressionValidator {
regExp: /[0-9A-F]+/ // 设置正则表达式
}
4、回显方式
TextInput项目的 echoMode
属性指定了文本的显示方式,可用的方式有:
- TextInput.Normal:直接显示文本(默认方式);
- TextInput.Password:使用密码掩码字符(根据不同平台显示效果不同)来代替真实的字符;
- TextInput.NoEcho:不显示输入的内容;
- TextInput.PasswordEchoOnEdit:使用密码掩码字符,但在输入时显示真实字符。
TextField
TextField:类似于 TextInput,但具有更丰富的功能。可以设置其外观、验证器、错误状态等
上代码:
TextField {
width: 200
height: 40
placeholderText: "请输入文本"
validator: IntValidator { bottom: 0; top: 100 } // 设置验证器
errorHighlight: true // 显示错误状态
}
附上最近写的代码,很乱,下面可以不看
Single文件
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
Item {
RowLayout {
anchors.fill: parent
Layout.margins: 30
MyCombox {
}
ColumnLayout {
Layout.margins: 10
Repeater {
model: ['aaaa', 'bbbb', 'ccccc']
anchors.fill: parent
RadioButton {
text: modelData
}
}
}
RowLayout {
spacing: 10
// anchors.centerIn: parent
Text {
text: qsTr("请输入")
font.pointSize: 15
verticalAlignment: Text.AlignVCenter
}
Rectangle {
width: 100
height: 24
color: "lightgrey"
border.color: "grey"
TextInput {
anchors.fill: parent
anchors.margins: 2
font.pointSize: 10
focus: true
inputMask: "9999" //限制输入 数字
validator: IntValidator{ bottom: 11; top: 31; } // 限制输入数字的范围
onEditingFinished :{
console.log("get data is :",text)
}
}
}
}
}
}
MyCombox文件
import QtQuick
import QtQuick.Controls
import MyApp 1.0
// 创建一个包含多个字符串的 JavaScript 数组,并将其暴露给 QML
ComboBox {
editable: true
textRole: "text"
displayText: currentText + " >>> " + currentIndex
// model: [
// { value: Qt.NoModifier, text: qsTr("No modifier") },
// { value: Qt.ShiftModifier, text: qsTr("Shift") },
// { value: Qt.ControlModifier, text: qsTr("Control") }
// ]
//------------------显示Model方式1-----------------------------------------
// model: ListModel {
// id: model
// ListElement { text: "Banana" }
// ListElement { text: "Apple" }
// ListElement { text: "Coconut" }
// }
// ------------------显示Model方式2---------------------------
// 导入模块
DataModel {
id: dataModel
}
model:ListModel {
id: listModel
}
// 将 QStringList 数据写入 ListModel 中
Component.onCompleted: {
for (var i = 0; i < dataModel.stringList.length; ++i) {
listModel.append({ "text": qsTr(dataModel.stringList[i])})
}
currentIndex = indexOfValue(dataModel.selectString) // 找到数据对应的值
}
// 存在可能重复选中的情况
onAccepted: {
if (find(editText) === -1) {
// model.append({text: editText})
} else {
// 选中一个数据后,下发到后端
dataModel.selectString = currentValue
}
console.log(" editText data is ", editText);
}
onCurrentIndexChanged: {
// 选中一个数据后,下发到后端
// currentValue 是上一个选中数据的data
dataModel.selectString = dataModel.stringList[currentIndex]
console.log(currentValue + " index is:" + currentIndex, " data is:", currentValue)
}
}
main中两种注入方式
// 一般情况
qmlRegisterType<DataModel>("MyApp", 1, 0, "DataModel");
// // 单例
// qmlRegisterSingletonType("MySingleApi", 1, 0, "MyApi", [](QQmlEngine *engine, QJSEngine *scriptEngine) -> QJSValue {
// Q_UNUSED(engine)
// static int seedValue = 5;
// QJSValue example = scriptEngine->newObject();
// example.setProperty("someProperty", seedValue++);
// return example;
// });
// 1: 注册号,23,主次版本号,调用名,单例的返回函数
qmlRegisterSingletonType<MySingleton>("MySingleApi", 1, 0, "MySingleApi", instance);
.h文件
#ifndef DATA_BASE_H
#define DATA_BASE_H
#include "data_base.h"
#include <QObject>
#include <QStringList>
#include <QQmlEngine>
class DataModel : public QObject
{
Q_OBJECT
Q_PROPERTY(QStringList stringList READ stringList WRITE setStringList NOTIFY stringListChanged)
Q_PROPERTY(QString selectString READ SelectString WRITE SetSelectString NOTIFY SelectStringChange)
public:
explicit DataModel(QObject *parent = nullptr);
QStringList stringList() const ;
void setStringList(const QStringList &list);
QString SelectString() const;
void SetSelectString(const QString string);
signals:
void stringListChanged();
void SelectStringChange();
private:
QStringList stringList_;
QList< QStringList > list_;
QString selectString_;
};
class MySingleton : public QObject
{
Q_OBJECT
Q_PROPERTY(int someProperty READ someProperty WRITE setSomeProperty NOTIFY somePropertyChanged)
public:
explicit MySingleton(QObject* parent = nullptr);
MySingleton* instance(); // 获取单例实例
// 添加其他成员函数和属性...
Q_INVOKABLE int doSomething() {
setSomeProperty(5);
return m_someProperty;
}
int someProperty() const { return m_someProperty; }
void setSomeProperty(int val) {
m_someProperty = val;
emit somePropertyChanged(val);
}
signals:
void somePropertyChanged(int newValue);
private:
static MySingleton *m_instance; // 单例实例
int m_someProperty {28}; // 数据
};
#endif // DATA_BASE_H
cpp文件
#include "data_base.h"
#include <QDebug>
DataModel::DataModel(QObject *parent): QObject(parent)
{
stringList_ << "Item data1" << "Item data2" << "Item data99999";
selectString_ = stringList_[1];
}
QStringList DataModel::stringList() const
{
return stringList_;
}
void DataModel::setStringList(const QStringList &list)
{
if (stringList_ == list) {
return;
}
stringList_ = list;
emit stringListChanged();
}
QString DataModel::SelectString() const
{
return selectString_;
}
void DataModel::SetSelectString(const QString string)
{
qDebug() << " cpp : change data str is: " << string;
selectString_ = string;
qDebug() << " cpp : selectString_ is : " << selectString_;
emit SelectStringChange();
}
// ------------------------------------------------------------------------------------------
// ------------------------------------------------------------------------------------------
// ------------------------------------------------------------------------------------------
MySingleton* MySingleton::m_instance = nullptr;
MySingleton *MySingleton::instance()
{
// SingletonTypeExample *example = new SingletonTypeExample();
// return example;
static MySingleton *ins = new MySingleton;
return ins;
}
MySingleton::MySingleton(QObject* parent) : QObject(parent)
{
// 初始化单例
}