当前位置: 首页 > ai >正文

Qt的学习(七)

1.显⽰类控件

1.1 Label

        QLabel 可以⽤来显⽰⽂本和图⽚

1.1.1 Qlabel显示文本 

#include "widget.h"
#include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);// 把第一个 label 设置成显示纯文本.ui->label->setTextFormat(Qt::PlainText);ui->label->setText("# 这是一段纯文本");// 把第二个 label 设置成显示富文本ui->label_2->setTextFormat(Qt::RichText);ui->label_2->setText("<b>这是一段富文本</b>");//<b></b>标签会加粗// 把第三个 label 设置成显示 markdownui->label_3->setTextFormat(Qt::MarkdownText);ui->label_3->setText("# 这是 markdown 文本");//#降温设置为一级标题
}Widget::~Widget()
{delete ui;
}

效果如下:

1.1.2 Qlabel显示图片

        当用户拖修改窗口大小的时候,就会触发resize事件(resizeEvent),像resize这样的事件,是连续变化的。把窗口尺寸从A拖到B这个过程中,会触发出一系列的resizeEvent
        此时就可以借助resizeEvent来完成上述的功能,可以让Widget窗口类,重写父类(QWidget)的resizeEvent虚函数(在鼠标拖动窗口尺寸的过程中这个函数就会被反复调用执行,每次触发一个resizeEvent事件都会调用一次对应的虚函数)。

        由于此处进行了函数重写,调用父类的虚函数就会实际调用到子类的对应的函数(多态)

#include "widget.h"
#include "ui_widget.h"
#include <QDebug>
#include <QResizeEvent>Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);// 先把 QLabel 设置成和窗口一样大, 并且把这个 QLabel 左上角设置到窗口的左上角这里.// 让整个 QLabel 铺满整个窗口QRect windowRect = this->geometry();ui->label->setGeometry(0, 0, windowRect.width(), windowRect.height());//上面的代码实在构造函数中进行的尺寸设置,这个设置相当于一次性的//一旦程序运行起来之后,Qlabel的尺寸就固定下来了//窗口的后续尺寸发生变化,但是qlabel不会随着窗口的尺寸发生变化QPixmap pixmap(":/huaji.png");ui->label->setPixmap(pixmap);// 启动自动拉伸. 此时图片就能够填充满整个窗口了.ui->label->setScaledContents(true);
}Widget::~Widget()
{delete ui;
}// 此处的形参 event 是非常有用的, 这里就包含了触发这个 resize 事件这一时刻, 窗口的尺寸的数值.
void Widget::resizeEvent(QResizeEvent *event)
{qDebug() << event->size();ui->label->setGeometry(0, 0, event->size().width(), event->size().height());
}

效果如下: 

  在实际编程中,指定回调函数其实有很多种写法
1)设置函数指针
 2)设置仿函数(函数对象)
 3)设置lambda
 4)通过重写父类虚函数(框架中拿着父类的指针调用这个函数.如果你创建了子类,重写了这个函数。此时在多态机制下,实际执行的就是子类的函数了)
 5)Qt的信号槽

1.2 LCD Number

        QLCDNumer 是⼀个专⻔⽤来显⽰数字的控件.类似于"⽼式计算器"的效果.

代码示例:倒计时
        使用QLCDNumber显示一个初始的数值,比如10每隔一秒钟,数字就-1,一直到0,就停止了

        此处关键要点是要实现“每秒钟-1”这个效果,即周期性的执行某个逻辑,使用定时器。
        C++标准库中,没有提供定时器的实现,Boost里面提供了对应的功能,Qt中也封装了对应的定时器(结合了信号槽机制的)
        QTimer->通过这个类创建出来的对象,就会产生一个timeout这样的信号.可以通过start方法来开启定时器,并且参数中设定触发timeout信号的周期
         结合connect,把这个timeout信号绑定到需要的槽函数中,就可以执行逻辑,修改LCDNumber中的数字。

#include "widget.h"
#include "ui_widget.h"
#include <QTimer>
#include <QDebug>Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);// 设置初始值ui->lcdNumber->display(10);// 创建一个 QTimer 实例timer = new QTimer(this);// 把 QTimer 的 timeout 信号和咱们自己的槽函数进行连接connect(timer, &QTimer::timeout, this, &Widget::handle);// 启动定时器, 参数是触发 timeout 的周期. 单位是 mstimer->start(1000);
}Widget::~Widget()
{delete ui;
}void Widget::handle()
{// 先拿到 LCDNumber 中的数字int value = ui->lcdNumber->intValue();if (value <= 0) {// 数字减到 0 了, 停止定时器.timer->stop();return;}ui->lcdNumber->display(value - 1);
}

 效果如下所示:

1.3 ProgressBar

使⽤ QProgressBar 表⽰⼀个进度条

核心属性:

实例:创建一个进度条,让进度条随时间的增长而增长;

#include "widget.h"
#include "ui_widget.h"#include <QTimer>Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);timer = new QTimer(this);connect(timer, &QTimer::timeout, this, &Widget::handle);// 别忘了启动定时器. 启动操作要在 connect 之后.timer->start(100);
}Widget::~Widget()
{delete ui;
}void Widget::handle()
{// 获取到进度条的当前数值.int value = ui->progressBar->value();if (value >= 100) {// 进度条满了, 就可以停止定时器了.timer->stop();return;}ui->progressBar->setValue(value + 1);
}

        虽然在widget.h中用到了QTimer,但是却没在.h文件中包含QTimer 头文件,为啥这个代码编译不会出错?为啥此处的QTimer就不会提示“找不到定义”?

        上述问题其实是通过Qt内部提供的一个特殊技巧来实现的。在Qt中,有一个专门的头文件(#include <Qwidget>)。这个头文件中包含了Qt中所有类的“前置声明”,这个头文件,一般不会直接接触到,但是包含其他的Qt的头文件,都会间接的包含到这个头文件。

        Qt为啥要使用上述的技巧,上述技巧能解决什么问题?
         主要解决的是编译速度的问题,C/C++的代码,编译速度在其他语言横向对比中,是非常慢的。C++编译速度慢,和#include头文件有直接关系的。

        由于include关系错综复杂。 因此尽可能减少include头文件的个数,就可以有效的减少编译时间,Qt中就使用class前置声明的方式,来尽量减少头文件的包含。通过前置声明的方式,Qt中的头文件,每个头文件包含的其他头文件数量都能得到一定的降低。

1.4 Calendar Widget

        QCalendarWidget 表⽰⼀个"⽇历"

#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_calendarWidget_selectionChanged()
{QDate date = ui->calendarWidget->selectedDate();qDebug() << date;ui->label->setText(date.toString());
}

效果如下:

2.输⼊类控件

2.1 Line Edit

        QLineEdit ⽤来表⽰单⾏输⼊框.可以输⼊⼀段⽂本,但是不能换⾏.

示例:

代码如下:

#include "widget.h"
#include "ui_widget.h"
#include <QDebug>Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);// 初始化第一个输入框, 用来输入姓名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_male->isChecked() ? "男" : "女";qDebug() << "姓名: " << ui->lineEdit_name->text()<< "密码: " << ui->lineEdit_password->text()<< "性别: " << gender<< "电话: " << ui->lineEdit_phone->text();
}

效果如下:

        正则表达式,本质上就是一个带有特殊字符的字符串.特殊字符用来表示另一个字符串的特征
此时就可以借助正则表达式来描述出一些具有一定特点的字符串。

参考: 正则表达式⽂档https://learn.microsoft.com/zh-cn/previous-versions/visualstudio/visual-studio-2008/ae5bf541(v=vs.90)?redirectedfrom=MSDN

正则表达式在线⼯具:https://regextester.buyaocha.com/

 通过正则表达式对手机号进行验证:

代码如下:

2.1.1 验证手机号

#include "widget.h"
#include "ui_widget.h"
#include <QRegExpValidator>Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);// 就需要给单行输入框设置验证器. 基于正则表达式来完成验证的~~QRegExp regExp("^1\\d{10}$");
//    ^1表示以1开头
//    \d:表示数字,为了在字符串中使用需要写作\\d
//    {10}表示前面的内容重复出现10次//$表示结尾ui->lineEdit->setValidator(new QRegExpValidator(regExp));
//    setValidator设置验证器,当前只是注册一个验证器//只有输入框中的内容发生改变了,验证操作就应该被执行
}Widget::~Widget()
{delete ui;
}void Widget::on_lineEdit_textEdited(const QString &text)
{//将常引用转为qstring类的对象QString content = text;int pos = 0;//pos是哪个位置验证出来不相同,就返回该位置if (ui->lineEdit->validator()->validate(content, pos) == QValidator::Acceptable) {// 验证通过ui->pushButton->setEnabled(true);} else {// 验证不通过ui->pushButton->setEnabled(false);}
}

效果如下:

2.1.2 两次验证密码是否输入相同

#include "widget.h"
#include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);// 初始化, 把这两个输入框的 echoMode 设置一下.ui->lineEdit->setEchoMode(QLineEdit::Password);ui->lineEdit_2->setEchoMode(QLineEdit::Password);ui->label->setText("密码为空");
}Widget::~Widget()
{delete ui;
}void Widget::on_lineEdit_textEdited(const QString &arg1)
{(void) arg1;//绕过编译器的检查,对于代码的执行逻辑没有任何影响,//只是为了消除警告this->compare();
}void Widget::on_lineEdit_2_textEdited(const QString &arg1)
{(void) arg1;this->compare();
}void Widget::compare()
{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("两次输入的密码不一致");}
}

效果执行如下:

2.1.3 输入框中密码的切换显示密码和原始文本

#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 则是 "显示密码" 状态, 就把输入框的显示模式, 设为 Normalui->lineEdit->setEchoMode(QLineEdit::Normal);} else {// false 则是 "隐藏密码" 状态, 就把输入框的显示模式, 设为 Passwordui->lineEdit->setEchoMode(QLineEdit::Password);}
}

执行效果如下:

2.2 TextEdit

        QTextEdit 表⽰多⾏输⼊框.也是⼀个富⽂本&markdown编辑器. 并且能在内容超出编辑框范围时⾃动提供滚动条.

2.3 ComboBox

        QComboBox 表⽰下拉框

核心属性:

核⼼⽅法

核⼼信号

实例:模拟麦当劳点餐

#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->addItem("培根蔬萃双层牛堡");ui->comboBox_2->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() << ", "<< ui->comboBox_2->currentText() << ", "<< ui->comboBox_3->currentText();
}

 效果如下:

实例:从文本文件中获取内容放于多选下拉框

#include "widget.h"
#include "ui_widget.h"
#include <QDebug>#include <fstream>Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);// 需要读取文件内容, 把文件中的每一行读取出来, 作为一个 ComboBox 的选项std::ifstream file("E:/config.txt");if (!file.is_open()) {qDebug() << "文件打开失败";return;}// 按行来读取文本内容.// getline 函数完成.std::string line;while (std::getline(file, line)) {// 取到的每一行内容, 设置到下拉框中.ui->comboBox->addItem(QString::fromStdString(line));}file.close();
}Widget::~Widget()
{delete ui;
}

效果如下:

2.4 SpinBox

        使⽤ Q SpinBox 或者 QDoubleSpinBox 表⽰"微调框",它是带有按钮的输⼊框.可以⽤来输⼊整 数/浮点数.通过点击按钮来修改数值⼤⼩。

        实例:通过下拉框来选择每个食物的种类,再通过微调框来选择数量

#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->addItem("培根蔬粹双层牛堡");ui->comboBox_2->addItem("中薯条");ui->comboBox_2->addItem("麦乐鸡块");ui->comboBox_2->addItem("麦辣鸡翅");ui->comboBox_3->addItem("雪碧");ui->comboBox_3->addItem("可乐");// 针对 QSpinBox 的范围进行设置ui->spinBox->setRange(1, 5);ui->spinBox_2->setRange(1, 5);ui->spinBox_3->setRange(1, 5);ui->spinBox->setValue(1);ui->spinBox_2->setValue(1);ui->spinBox_3->setValue(1);
}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();
}

效果如下:

2.5 DateEdit &TimeEdit

        使⽤ QDateEdit 作为⽇期的微调框;

        使⽤ QTimeEdit 作为时间的微调框;

        使⽤QDateTimeEdit 作为时间⽇期的微调框;

displayFormat格式的大小写为:小-大-小-大-小-小;一个字母表示一个数字。y-M-d H-m-s(这只是在qt中这样表示时间,不同的编程语言对于时间单位的大小写不一定,所以用的时候查)

2.6Dial

        使⽤ Q Dial 表⽰⼀个旋钮.。有 些程序,通过⿏标拖动旋钮旋转,即可完成⼀些相关的设置

实例:编写代码,通过旋钮来控制窗口的透明度(opicaty是0-1d的小数表示)

#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_dial_valueChanged(int value)
{qDebug() << value;this->setWindowOpacity((double)value / 100);
}

效果如下:

2.7 Slider

        使⽤ Q Slider 表⽰⼀个滑动条;

        自定义快捷键,通过快捷键来操作滑动条,滑动条本身就可以通过方向键和pageup,pagedown来操作。

#include "widget.h"
#include "ui_widget.h"
#include <QShortcut>//该类来定义头文件Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);// 使用快捷键, 需要用到 QShortCut 类// 需要两个快捷键, - 进行减少, = 进行增加 (= 和 + 是一个按钮)QShortcut* shortCut1 = new QShortcut(this);shortCut1->setKey(QKeySequence("-"));QShortcut* shortCut2 = new QShortcut(this);shortCut2->setKey(QKeySequence("="));// 使用信号槽, 感知到快捷键被按下.connect(shortCut1, &QShortcut::activated, this, &Widget::subValue);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();if (value <= ui->horizontalSlider->minimum()) {return;}ui->horizontalSlider->setValue(value - 5);
}void Widget::addValue()
{// 获取到当前值int value = ui->horizontalSlider->value();if (value >= ui->horizontalSlider->maximum()) {return;}ui->horizontalSlider->setValue(value + 5);
}

ps:对于显示空间和输入空间的学习如上,谢谢观看!!!

http://www.xdnf.cn/news/14540.html

相关文章:

  • Kubernetes多容器Pod实战
  • 操作系统进程与线程核心知识全览
  • 一个小BUG引发的对Mybatis-Plus的模糊查询的思考
  • C 语言结构体:从基础到内存对齐深度解析
  • word-spacing 属性
  • 那些年,曾经辉煌过的数据库
  • AtCoder AT_abc411_c [ABC411C] Black Intervals
  • python基础知识,以及7个练习案例
  • ubuntu24.4 + ros2 jazzy 安装gazebo
  • C++11 std::thread 多线程编程详解
  • OpenAI与微软的未来合作之路:充满挑战的AI竞赛与共赢
  • 从事登高架设作业需要注意哪些安全事项?
  • C#学习日记
  • tkinter 的 place() 布局管理器学习指南
  • AI 产品的“嵌点”(Embedded Touchpoints)
  • gitea本地部署代码托管后仓库的新建与使用(配置好ssh密钥后仍然无法正常克隆仓库是什么原因)
  • 机加工工时定额计算标准
  • 【云创智城】YunCharge充电桩系统-深度剖析OCPP 1.6协议及Java技术实现:构建高效充电桩通信系统
  • Python 中布尔值的使用:掌握逻辑判断的核心
  • C++ 学习笔记精要(二)
  • 计算机——硬盘驱动器
  • 236. 二叉树的最近公共祖先 (js)
  • macOS - 根据序列号查看机型、保障信息
  • 【AI驱动网络】
  • 响应式数据可视化大屏解决方案,重构工业交互体验
  • Java开发小知识-获取配置文件的值(转为Java对象)
  • AIGC工具平台-VideoRetalking音频对口型数字人
  • 前端如何禁止用户复制?
  • vue3 el-select @change (val) 多参数传值操作
  • HCIP-数据通信基础