4.输入类控件
①Line Edit 单行输入框
属性 |
说明 |
text |
输入框中的文本 |
input |
输入内容格式约束 |
maxLength |
最大长度 |
frame |
是否添加边框 |
echoMode |
显示方式
|
cursorPosition |
光标所在位置 |
alignment |
文字对齐方式,设置水平和垂直方向的对齐 |
dragEnabled |
是否允许拖拽 |
readOnly |
是否是只读的(不允许修改) |
placeHolder |
当输入框内容为空的时候,显示什么样的提示信息 |
clearButtonEnabled |
是否会自动显示出“清除按钮” |
核心信号
属性 |
说明 |
|
当鼠标移动时发出此信号,old为先前的位置,new为新位置。 |
|
当按返回或者回车键时,或者行编辑失去焦点时,发出此信号。 |
|
当返回或回车键按下时发出此信号 如果设置了验证器,必须要验证通过,才能触发 |
|
当选中的文本改变时,发出此信号。 |
|
当QLineEdit中的文本改变时,发出此信号,text是新的文本 代码对文本的修改能够触发这个信号 |
|
当QLineEdit中的文本改变时,发出此信号,text是新的文本 代码对文本的修改不能触发这个信号 |
#include "widget.h"
#include "ui_widget.h"
#include<QDebug>
//#include<stdio.h>
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
// printf("hello");
//初始化第一个输入框,用来输入姓名
ui->lineEdit_name->setPlaceholderText("请输入姓名");
ui->lineEdit_name->setClearButtonEnabled(true);
//初始化第二个输入框,用来输入密码
ui->lineEdit_password->setPlaceholderText("请输入密码");
ui->lineEdit_password->setClearButtonEnabled(true);
//把显示模式设置成显示密码的模式
ui->lineEdit_password->setEchoMode(QLineEdit::Password);
//初始化第三个输入框
ui->lineEdit_phone->setPlaceholderText("请输入手机号");
ui->lineEdit_phone->setClearButtonEnabled(true);
//手机号有固定格式,此处的0代表数字
ui->lineEdit_phone->setInputMask("000-0000-0000");
}
Widget::~Widget()
{
delete ui;
}
void Widget::on_pushButton_submit_clicked()
{
QString gender = ui->radioButton_nan->isChecked()?"男" :"女";
qDebug()<<"姓名"<<ui->lineEdit_name->text()
<<"密码"<<ui->lineEdit_password->text()
<<"性别"<<gender
<<"电话"<<ui->lineEdit_phone->text();
}
正则表达式:
正则表达式是一种在计算机中常用的,使用特殊字符描述一个字符串的特征的机制.在进行字符串匹配时非常有用
正则表达式的语法还比较复杂,一般都是随用随查,不需要背下来
参考:
正则表达式在线工具:
①验证用户在单行输入框中输入的文本是否符合特定的正则表达式模式
(尝试输入字母是无法输入,且只能输入11位)
#include "widget.h"
#include "ui_widget.h"
#include<QRegExpValidator>
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
//给单行输入框设置验证器,基于正则表达式来完成验证目的
ui->pushButton->setEnabled(false);
QRegExp regExp("^1\\d{10}$");
ui->lineEdit->setValidator(new QRegExpValidator(regExp));
}
Widget::~Widget()
{
delete ui;
}
void Widget::on_lineEdit_textEdited(const QString &text)
{
QString content = text;
int pos = 0;
if (ui->lineEdit->validator()->validate(content,pos)){
//验证通过
ui->pushButton->setEnabled(true);
}else{
//验证不通过
ui->pushButton->setEnabled(false);
}
}
正则表达式 "^1\\d{10}$"
- ^:这个符号表示匹配字符串的开始位置。
- 1:这个数字表示匹配字符'1'。在这个正则表达式中,它指定了字符串必须以数字'1'开头。
- \\d:\d是一个正则表达式中的特殊字符,表示匹配任何一个阿拉伯数字(0-9)。由于在Qt中,反斜杠\是一个转义字符,所以在字符串中使用它需要进行转义,因此我们使用\\d来表示\d。
- {10}:这个花括号表示前面的表达式(这里是\d)需要重复10次。因此,\\d{10}表示匹配10个数字。
- $:这个符号表示匹配字符串的结束位置。
②验证两次输入的密码一致
#include "widget.h"
#include "ui_widget.h"
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
ui->label->setText("请输入密码,两次密码要填写一致!");
ui->lineEdit->setEchoMode(QLineEdit::Password);
ui->lineEdit_2->setEchoMode(QLineEdit::Password);
}
Widget::~Widget()
{
delete ui;
}
void Widget::on_lineEdit_textEdited(const QString &arg1)
{
(void) arg1;
const QString& s1 = ui->lineEdit->text();
const QString& s2 = ui->lineEdit_2->text();
if(s1.isEmpty() && s2.isEmpty())
{
ui->label->setText("密码为空!");
}
else if(s1 == s2){
ui->label->setText("两次输入的密码相同!");
}
else
{
ui->label->setText("两次输入的密码不相同!");
}
}
void Widget::on_lineEdit_2_textEdited(const QString &arg1)
{
(void) arg1;
const QString& s1 = ui->lineEdit->text();
const QString& s2 = ui->lineEdit_2->text();
if(s1.isEmpty() && s2.isEmpty())
{
ui->label->setText("密码为空!");
}
else if(s1 == s2){
ui->label->setText("两次输入的密码相同!");
}
else
{
ui->label->setText("两次输入的密码不相同!");
}
}
lineEdit和lineEdit_2的代码完全相同,在开发过程中建议封装成一个函数然后再调用该函数,这样只需写一遍,且能多次利用
在槽函数中,argl未被用到,这样的话编译器会出现警告,可以在函数内部添加(void) arg1;
绕过编译器检查
③切换显示密码
#include "widget.h"
#include "ui_widget.h"
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
//设置初始状态
ui->lineEdit->setEchoMode(QLineEdit::Password);
}
Widget::~Widget()
{
delete ui;
}
void Widget::on_checkBox_toggled(bool checked)
{
if(checked)
{
// true则是显示密码状态,就会把输入框的显示模式切换为normal
ui->lineEdit->setEchoMode(QLineEdit::Normal);
}
else
{
// false则是隐藏密码状态,就会把输入框的显示模式切换为Password
ui->lineEdit->setEchoMode(QLineEdit::Password);
}
}
②TextEdit 多行输入框&Markdown富文本编辑器
能在内容超出编辑框范围时自动提供滚动条
属性 |
说明 |
markdown |
输入框内持有的内容,支持markdown格式,能够自动的对markdown文本进行渲染成html |
html |
输入框内持有的内容,可以支持大部分html标签,包括img和table等 |
palceHolderText |
输入框为空时提示的内容 |
readOnly |
是否是只读的 |
undoRedoEnable |
是否开启undo/redo功能 按下ctrl+z触发undo 按下ctrl+y触发redo |
autoFormating |
开启自动格式化 |
tabstopWidth |
按下缩进占多少空间 |
overwriteMode |
是否开启覆盖写模式 |
acceptRichText |
是否接收富文本内容 |
verticalScrollBarPolicy |
垂直方向滚动条的出现策略
|
horizontalScrollBarPolicy |
水平方向滚动条的出现策略
值。
|
核心信号
信号 |
说明 |
textChanged() |
文本内容改变时触发 |
selectionChanged() |
选中范围改变时触发 |
cursorPositionChanged() |
光标移动时触发 |
undoAvailable(bool) |
可以进行undo操作时触发 |
redoAvailable(bool) |
可以进行redo操作时触发 |
copyAvailable(bool) |
文本被选中/取消选中时触发 |
①获取到多行输入框的内容
#include "widget.h"
#include "ui_widget.h"
#include<QDebug>
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
}
Widget::~Widget()
{
delete ui;
}
void Widget::on_textEdit_textChanged()
{
//获取到内部的文本
const QString& content = ui->textEdit->toPlainText();
qDebug() << content;
ui->label->setText(content);
}
②验证输入框的各种信号
#include "widget.h"
#include "ui_widget.h"
#include<QDebug>
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
}
Widget::~Widget()
{
delete ui;
}
void Widget::on_textEdit_textChanged()
{
qDebug() << "[textChanged] " << ui->textEdit->toPlainText();
}
void Widget::on_textEdit_selectionChanged()
{
//获取光标选中内容
const QTextCursor& cursor = ui->textEdit->textCursor();
qDebug() << "[selectionChanged] " << cursor.selectedText();
}
void Widget::on_textEdit_cursorPositionChanged()
{
//获取光标内容
const QTextCursor& cursor = ui->textEdit->textCursor();
qDebug() << "[cursorPositionChanged] " << cursor.position();
}
void Widget::on_textEdit_undoAvailable(bool b)
{
qDebug() << "[undoAvailable] " << b;
}
void Widget::on_textEdit_redoAvailable(bool b)
{
qDebug() << "[redoAvailable] " << b;
}
void Widget::on_textEdit_copyAvailable(bool b)
{
qDebug() << "[copyAvailable] " << b;
}
③ComboBox 下拉框
属性 |
说明 |
currentText |
当前选中的文本 |
currentIndex |
当前选中的条目下标 从0开始计算,如果当前没有条目被选中,值为-1 |
editable |
是否允许修改 设为true时, |
iconSize |
下标框图标(小三角)的大小 |
maxCount |
最多允许有多少个条目 |
核心方法
方法 |
说明 |
addltem(const QString) |
添加一个条目 |
currentIndex() |
获取当前条目的下标 从0开始计算,如果当前没有条目被选中,值为-1 |
currentText() |
获取当前条目的文本内容 |
核心信号
方法 |
说明 |
activated(int) activated(const QString &text) |
当用户选择了一个选项时发出 这个时候相当于用户点开下拉框,并且鼠标划过某个选项 此时还没有确认做出选择 |
currentIndexChanged(int) currentIndexChanged(const QString &text) |
当前选项改变时发出 此时用户已经明确了一个选项 用户操作或者通过程序操作都会触发这个信号 |
editTextChanged(const QString &text) |
当编辑框中的文本改变时发出 (editable为true时有效) |
①使用下拉框模拟麦当劳点餐
#include "widget.h"
#include "ui_widget.h"
#include<QDebug>
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
ui->comboBox->addItem("巨无霸");
ui->comboBox->addItem("麦辣鸡腿堡");
ui->comboBox_2->addItem("薯条");
ui->comboBox_2->addItem("麦辣鸡腿");
ui->comboBox_3->addItem("可乐");
ui->comboBox_3->addItem("雪碧");
}
Widget::~Widget()
{
delete ui;
}
void Widget::on_pushButton_clicked()
{
qDebug() << "汉堡选择" << ui->comboBox->currentText();
qDebug() << "小食选择" << ui->comboBox_2->currentText();
qDebug() << "饮料选择" << ui->comboBox_3->currentText();
}
②从文件中加载下拉框的选项
#include "widget.h"
#include "ui_widget.h"
#include <fstream>
//注意头文件!!!
#include<QDebug>
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
//std::ifstream file("./config.txt");
//相对路径,此时文件不是在D:\C C++\program\QT\ComboBox_2这个目录下
//而是在运行程序目录"D:\C C++\program\QT\build-ComboBox_2-Desktop_Qt_5_14_0_MinGW_64_bit-Debug\config.txt"下
std::ifstream file("D:/config.txt");
if (!file.is_open()) {
qDebug() << "Failed to open file";
return;
}
std::string line;
while(std::getline(file,line))
{
ui->comboBox->addItem(QString::fromStdString(line));
}
file.close();
}
Widget::~Widget()
{
delete ui;
}
Qt中也提供了QFile实现读写文件的功能.当然使用C++标准库的std:fstream也是完全可以的.
之所以存在两套,是因为Qt诞生较早(1991年左右),此时C+还没有完成"标准化"的工作,C++标准库这样的概念自然也没有诞生,
因此Qt就自己打造了一套库,实现了字符串,容器,文件操作,多线程,网络操作,定时器,正则表达式等内容.
(由于C++标准委员会的不作为,至今仍然有些Qt提供的功能,是标准库不具备的)
④SpinBox 微调框(带按钮的输入框)
SpinBox
和QDoubleSpinBox
用法基本相同
Spin英文原意为"旋转"此处引申成"微调".
事实上很多术语在翻译的时候,不一定非要按照原始的翻译来表示,更追求的是"信达雅"
举个例子,地铁上的"Priority Seat'"会翻译成"爱心专座”,而不是"优先座位".
属性 |
说明 |
value |
存储的数值 |
singleStep |
每次调整的“步长”,按下一次按钮数据变化多少 |
displayInterger |
数字的进制,例如 |
minimum |
最小值 |
maximum |
最大值 |
suffix |
后缀 |
prefix |
前缀 |
wrapping |
是否允许换行 |
frame |
是否带边框 |
alignment |
文字对齐方式 |
readOnly |
是否允许修改 |
buttonSymbol |
按钮上的图标
|
accelerated(加速的) |
按下按钮时是否为快速调整模式 |
correctionMode |
输入有误时如何修正,
|
keyboardTrack |
是否开启键盘跟踪, 设为true,每次在输入框输入一个数字,都会触发一次 设为false,只有在最终按下enter或者输入框失去焦点,才会触发 |
核心信号
属性 |
说明 |
textChanged(QString) |
微调框的文本发生改变时会触发 参数QString带有前缀和后缀 |
valueChanged(int) |
微调框的文本发生改变时会触发 参数int,表示当前的数值 |
①调整麦当劳购物车中的份数
#include "widget.h"
#include "ui_widget.h"
#include<QDebug>
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
ui->comboBox->addItem("巨无霸");
ui->comboBox->addItem("麦辣鸡腿堡");
ui->comboBox_2->addItem("薯条");
ui->comboBox_2->addItem("麦辣鸡翅");
ui->comboBox_3->addItem("可乐");
ui->comboBox_3->addItem("雪碧");
//初始化微调框
ui->spinBox->setValue(1);
ui->spinBox->setRange(1,5);
ui->spinBox_2->setValue(1);
ui->spinBox_2->setRange(1,5);
ui->spinBox_3->setValue(1);
ui->spinBox_3->setRange(1,5);
}
Widget::~Widget()
{
delete ui;
}
void Widget::on_pushButton_clicked()
{
qDebug() << "当前下单:"
<< ui->comboBox->currentText() << ":" << ui->spinBox->value()
<< ui->comboBox_2->currentText() << ":" << ui->spinBox_2->value()
<< ui->comboBox_3->currentText() << ":" << ui->spinBox_3->value();
}
⑤Data Edit & Time Edit 日期时间微调框
属性 |
说明 |
dataTime |
时间日期的值,形如 |
data |
单纯日期的值,形如 |
time |
单纯时间的值,形如 |
displayFormat |
时间日期格式,形如 y:表示年份 M:表示月份 d:表示日期 H:表示小时 m:表示分钟 s:表示秒 注意:这里的格式化符号的含义,不要记忆.不同语言/库的设定规则是存在差异的,一定是用的时候再去查 |
minimumDateTime |
最小时间日期 |
maximumDateTime |
最大时间日期 |
timeSpec |
|
关于本地时间(LocalTime)和协调世界时(UTC)
UTC时间是一个基于原子钟的标准时间.不受地球的自转周期影响.和格林威治时间(GMT)是非常接近的.科学家会通过精密的设备来测量并维护
咱们的计算机内部使用的时间就是基于UTC时间
本地时间则是基于不同的时区,对UTC时间做出了一些调整.比如咱们使用的北京时间,位于"东八区”,就需要在UTC时间基础上+8个小时的时差,
核心信号
信号 |
说明 |
dateChanged(QDate) |
日期改变时触发 |
timeChanged(QTime) |
事件改变时触发 |
dateTimeChanged(QDateTime) |
时间日期任意一个改变时触发 |
①实现日期计算器
#include "widget.h"
#include "ui_widget.h"
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
}
Widget::~Widget()
{
delete ui;
}
void Widget::on_pushButton_clicked()
{
//获取到两个时间框的时间和日期
QDateTime timeold = ui->dateTimeEdit_old->dateTime();
QDateTime timenew = ui->dateTimeEdit_new->dateTime();
//计算日期差值
int days = timeold.daysTo(timenew);
int hours = (timeold.secsTo(timenew)/3600) % 24;
//设置 label的内容
QString text = QString("在一起已经 ") + QString::number(days) + QString(" 天 零 ") + QString::number(hours) + QString(" 个小时!");
ui->label->setText(text);
}
⑥Dial 旋钮
属性 |
说明 |
value |
持有的数值 |
minimum |
最小值 |
maximum |
最大值 |
singleStep |
按下方向键的时候改变的步长 |
pageStep |
按下pageUp/pageDown的时候改变的步长 |
sliderPosition |
界面上旋钮显示的初始位置 |
tracking |
外观是否会跟踪数值变化 默认值为true,一般不需要修改 |
wrapping |
是否允许循环调整 即数值如果超过最大值,是否允许回到最小值 (调整过程中能否套圈) |
notchesVisible |
是否显示刻度线 |
notchTarget |
刻度线之间的相对位置 数字越大,刻度线越稀疏 |
核心信号
属性 |
说明 |
valueChanged(int) |
数值改变时触发 |
rangeChanged(int,int) |
范围变化时触发 |
①调整窗口透明度
#include "widget.h"
#include "ui_widget.h"
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
//设置可以循环旋转
ui->dial->setWrapping(true);
//设置刻度线可见
ui->dial->setNotchesVisible(true);
//设置最大值为
ui->dial->setMaximum(100);
//设置最小值为
ui->dial->setMinimum(0);
//设置初始值为
ui->dial->setValue(100);
}
Widget::~Widget()
{
delete ui;
}
void Widget::on_dial_valueChanged(int value)
{
ui->label->setText(QString("当前不透明度为: ") + QString::number(value));
this->setWindowOpacity((double)value / 100);
}
⑦Slider 滑动条
QSlider 和 QDial 都是继承自 QAbstractSlider
,因此用法上基本相同。
属性 |
说明 |
value |
持有的数值 |
minimum |
最小值 |
maximum |
最大值 |
singleStep |
按下方向键的时候改变的步长 |
pageStep |
按下pageUp/pageDown的时候改变的步长 |
sliderPosition |
界面上旋钮显示的初始位置 |
tracking |
外观是否会跟踪数值变化 默认值为true,一般不需要修改 |
orientation |
滑动条的方向是水平还是垂直 |
invertedAppearance |
是否要反转滑动条的位置 |
tickPosition |
刻度的位置 |
tickInterval |
刻度的密集程度 |
核心信号
属性 |
说明 |
valueChanged(int) |
数值改变时触发 |
rangeChanged(int,int) |
范围变化时触发 |
objectName分别为
水平:horizontalSlider
垂直:verticalSlider
①调整窗口大小
#include "widget.h"
#include "ui_widget.h"
#include<QDebug>
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
ui->horizontalSlider->setMinimum(500);
ui->horizontalSlider->setMaximum(2000);
ui->horizontalSlider->setSingleStep(100); //按下方向键的时候改变的步长
ui->horizontalSlider->setValue(800);
ui->verticalSlider->setMinimum(500);
ui->verticalSlider->setMaximum(1500);
ui->verticalSlider->setSingleStep(100); //按下方向键的时候改变的步长
ui->verticalSlider->setValue(600);
//翻转朝向,默认滑块从上往下增长
ui->verticalSlider->setInvertedAppearance(true);
}
Widget::~Widget()
{
delete ui;
}
void Widget::on_horizontalSlider_valueChanged(int value)
{
QRect rect = this->geometry();
this->setGeometry(rect.x(),rect.y(),value,rect.height());
qDebug()<<value;
}
void Widget::on_verticalSlider_valueChanged(int value)
{
QRect rect = this->geometry();
this->setGeometry(rect.x(),rect.y(),rect.width(),value);
qDebug()<<value;
}
②通过自定义快捷键调整滑动条位置
#include "widget.h"
#include "ui_widget.h"
#include<QShortcut> // 设置快捷键
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
ui->label->setText("");
ui->horizontalSlider->setMinimum(0);
ui->horizontalSlider->setMaximum(100);
ui->horizontalSlider->setSingleStep(10);
ui->horizontalSlider->setValue(0);
QShortcut* shortCut1 = new QShortcut(this);
shortCut1->setKey(QKeySequence("-"));
connect(shortCut1,&QShortcut::activated,this,&Widget::subValue);
QShortcut* shortCut2 = new QShortcut(this);
shortCut2->setKey(QKeySequence("="));
connect(shortCut2,&QShortcut::activated,this,&Widget::addValue);
}
Widget::~Widget()
{
delete ui;
}
void Widget::on_horizontalSlider_valueChanged(int value)
{
ui->label->setText(QString::number(value));
}
void Widget::subValue()
{
int value = ui->horizontalSlider->value();
ui->horizontalSlider->setValue(value-20);
}
void Widget::addValue()
{
int value = ui->horizontalSlider->value();
ui->horizontalSlider->setValue(value+20);
}