前言:
Hello Everyone!
我是橘颂TA
这里给带来新博客一篇,本博客全文精讲 Qt 的高阶功法,小白也能听懂,
当然也需要一定 C++ 的知识,全文有浅到难,步步解剖,给我们深入理解 Qt 在 GUI
强大的功能,理解 Qt 的魅力;我是橘颂TA,有兴趣可以给我点个关注。
主页更多精彩文章,不要错过哦!
目录
一、Combo Box 控件
▶️Combo Box 控件是一个下拉框,是 GUI 是非常常见的一个控件,我们来看一下它的核心属性。
属性 | 说明 |
currentText | 当前选中的⽂本 |
currentIndex | 当前选中的条⽬下标,从 0 开始计算,如果当前没有条⽬被选中,值为 -1 |
editable | 是否允许修改 设为 true 时,QComboBox 的⾏为就⾮常接近 QLineEdit, 也可以 设置 validator |
iconSize | 下拉框图标 (⼩三⻆) 的⼤⼩ |
maxCount | 最多允许有多少个条⽬ |
⏩️核心方法(使用方法):
方法 | 说明 |
addItem(const QString&) | 添加⼀个条⽬ |
currentIndex() | 获取当前条⽬的下标 从 0 开始计算,如果当前没有条⽬被选中,值为 -1 |
currentText() | 获取当前条⽬的⽂本内容 |
⏩️核心信号:
方法 | 说明 |
activated(int) activated(const QString & text) | 当⽤⼾选择了⼀个选项时发出。 这个时候相当于⽤⼾点开下拉框,并且⿏标划过某个选项, 此时还没有确认做出选择. |
currentIndexChanged(int) currentIndexChanged(int) | 当前选项改变时发出。 此时⽤⼾已经明确的选择了⼀个选项, ⽤⼾操作或者通过程序操作都会触发这个信号。 |
editTextChanged(const QString & text) | 当编辑框中的⽂本改变时发出 (editable 为 true 时有效) |
🚩代码练习1:实现一个点餐功能。
#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();
}
也可以使用图形画界面直接编辑实现上述效果:
🚩代码练习2:访问文件来或许选项。
⏩️①在桌面创建一个文本文件,并且输入食物。
⏩️②拖动控件
⏩️③编写代码
#include "widget.h"
#include "ui_widget.h"
#include<fstream>
#include<QDebug>
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
//读文件内容,获取每一行文件的内容作为一个 ComBox 选项
std::ifstream file("C:/Users/31430/Desktop/examin.txt");
if(!file.is_open())
{
qDebug() << "文件打开失败";
return;
}
//按行读取
std::string line;
while(std::getline(file,line))
{
//读取到的每一行设置到选项中
ui->comboBox->addItem(QString::fromStdString(line));
}
//addItem 的参数是QString而不是String,fromStdString可以把String转换成QString
file.close();
}
Widget::~Widget()
{
delete ui;
}
二、Spin Box 控件
▶️Spin Box 和 QDoubleSpinBox 表示微调框,它是一个带有按钮的输入框,可以通过浮点数和整数来修改数值大小,由于他们的用法基本相同,这里只介绍 SpinBox 。
⏩️QSpin Box 相关属性:
属性 | 说明 |
value | 存储的数值 |
singleStep | 每次调整的 "步⻓",按下⼀次按钮数据变化多少 |
displayInteger | 数字的进制。例如 displayInteger 设为 10,则是按照 10 进制表⽰。设为 2 则为 2 进制表⽰ |
minimum | 最⼩值 |
maximum | 最⼤值 |
suffix | 后缀 |
prefix | 前缀 |
wrapping | 是否允许换⾏ |
frame | 是否带边框 |
alignment | ⽂字对⻬⽅式 |
readOnly | 是否允许修改 |
buttonSymbol | 按钮上的图标: 🚩• UpDownArrows 上下箭头形式 🚩• PlusMinus 加减号形式 🚩• NoButtons 没有按钮 |
accelerated (加速的) | 按下按钮时是否为快速调整模式 |
correctionMode | 输⼊有误时如何修正: 🚩• QAbstractSpinBox::CorrectToPreviousValue : 如果⽤⼾输⼊了⼀个 ⽆效的值(例如,在只能显⽰正整数的SpinBox中输⼊了负数),那么 SpinBox会恢复为上⼀个有效值。例如,如果SpinBox的初始值是1,⽤⼾ 输⼊了-1(⽆效),然后SpinBox会恢复为1。 🚩• QAbstractSpinBox::CorrectToNearestValue : 如果⽤⼾输⼊了⼀个 ⽆效的值,SpinBox会恢复为最接近的有效值。例如,如果SpinBox的初始 值是1,⽤⼾输⼊了-1(⽆效),那么SpinBox会恢复为0。 |
keyboardTrack | 是否开启键盘跟踪。 🚩设为 true, 每次在输⼊框输⼊⼀个数字,都会触发⼀次 valueChanged() 和 textChanged() 信号。 🚩设为 false, 只有在最终按下 enter 或者输⼊框失去焦点, 才会触发 valueChanged() 和 textChanged() 信号. |
核心信号:
信号 | 说明 |
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->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);
//设置 QSpinBox 的初始值
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();
}
三、Date Edit && Time Edit
▶️下面都是和时间有关的控件:
⏩️Date Edit 是日期微调框:
⏩️Time Edit 是时间微调框:
⏩️QDateTimeEdit 是上面两个的结合体:
⏩️他们三个使用方法都差不多,这里只介绍 QDateTimeEdit 控件。
⏩️QDateTimeEdit 核心属性:
属性 | 说明 |
dateTime | 时间⽇期的值. 形如 2000/1/1 0:00:00 |
date | 单纯⽇期的值. 形如 2001/1/1 |
time | 单纯时间的值. 形如 0:00:00 |
displayFormat | 时间⽇期格式. 形如 yyyy/M/d H:mm 🚩• y 表⽰年份 🚩• M 表⽰⽉份 🚩• d 表⽰⽇期 🚩• H 表⽰⼩时 🚩• m 表⽰分钟 🚩• s 表⽰秒 ❌️注意:这⾥的格式化符号的含义,不要记忆。 不同语⾔/库的设定规则是存在差异的。 ⼀定是⽤的时候再去查. |
minimumDateTime | 最⼩时间⽇期 |
maximumDateTime | 最⼤时间⽇期 |
timeSpec | 🚩• Qt::LocalTime :显⽰本地时间。 🚩• Qt::UTC :显⽰协调世界时(UTC)。 🚩• Qt::OffsetFromUTC :显⽰相对于UTC的偏移量(时差). |
❌️注意:UTC 是标准时间,是科学家通过原子钟来计算的,现实生活中,存在一个时差问题,时差就是在标准时间的基础上计算机一个时间的差值,世界公认的标准时间是英国的格林威治天文台的标准时间,例如:我们英国现在是 0 点,而我们是 localTime(UTC)+ 8小时 = 8点(以北京东八区为准)。
⏩️QDateTimeEdit 核心信号:
信号 | 说明 |
dateChanged(QDate) | ⽇期改变时触发 |
timeChanged(QTime) | 时间改变时触发 |
dateTimeChanged(QDateTi me) | 时间⽇期任意⼀个改变时触发. |
⏩️代码练习:计算两个日期的时间间隔
#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_pushButton_clicked()
{
//先获取到两个输入框的时间
QDateTime timeOld = ui->dateTimeEdit->dateTime();
QDateTime timeNew = ui->dateTimeEdit_2->dateTime();
//计算差值
int days = timeOld.daysTo(timeNew);
qDebug()<<days;
int seconds = timeOld.secsTo(timeNew);//得到的是秒数
//把秒数换成小时
int hour = (seconds/3600) % 24;
//显示计算结果
ui->label->setText(QString("已经过去") + QString::number(days) + QString("天零")+ QString::number(hour) + QString("小时"));
}
❌️注意:QDateTime 提供了两个函数可以计算时间差值:1.daysTo 计算俩个时间日期的差值,2.secsTo 计算两个时间差值的秒数。
⏩️特例:
⏩️原因:Qt 官方文档规定不足一天也按一天算。
⏩️解决办法:
#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_pushButton_clicked()
{
//先获取到两个输入框的时间
QDateTime timeOld = ui->dateTimeEdit->dateTime();
QDateTime timeNew = ui->dateTimeEdit_2->dateTime();
//计算差值
// int days = timeOld.daysTo(timeNew);
// qDebug()<<days;
int seconds = timeOld.secsTo(timeNew);//得到的是秒数
//把秒数换成小时
int days = (seconds/3600) / 24;
int hour = (seconds/3600) % 24;
//显示计算结果
ui->label->setText(QString("已经过去") + QString::number(days) + QString("天零")+ QString::number(hour) + QString("小时"));
}
四、Dial 控件
▶️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"
#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);//透明的的值范围在 0 —— 1, 1是完全透明,0是完全不透明
}
❌️注意:其实也可以通过旋钮来控制音量,但是调整音量是window 系统的 api ,Qt 没有封装。此时需要通过 VS 写一个动态库把系统原生的 API 封装一下,再让 Qt 的程序来调用动态库。
五、Slider 控件
▶️QSlider 控件是一个滑动条。跟 Dial 差不多。
⏩️核心属性:
属性 | 说明 |
value | 持有的数值. |
minimum | 最⼩值 |
maximum | 最⼤值 |
singleStep | 按下⽅向键的时候改变的步⻓ |
pageStep | 按下 pageUp / pageDown 的时候改变的步⻓ |
sliderPosition | 滑动条显⽰的初始位置 |
tracking | 外观是否会跟踪数值变化. 默认值为 true. ⼀般不需要修改 |
orientation | 滑动条的⽅向是⽔平还是垂直 |
invertedAppearance | 是否要翻转滑动条的⽅向 |
tickPosition | 刻度的位置 |
tickInterval | 刻度的密集程度. |
⏩️核心信号:
信号 | 说明 |
valueChanged(int) | 数值改变时触发 |
rangeChanged(int, int) | 范围变化时触发 |
⏩️代码练习1:设置连个滑动条,一个垂直一个水平来控制窗口的大小。
#include "widget.h"
#include "ui_widget.h"
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
//初始化
ui->horizontalSlider->setMinimum(100);
ui->horizontalSlider->setMaximum(2000);
ui->horizontalSlider->setValue(800);
ui->horizontalSlider->setSingleStep(500);
ui->verticalSlider->setMinimum(100);
ui->verticalSlider->setMaximum(1500);
ui->verticalSlider->setValue(600);
ui->verticalSlider->setSingleStep(50);
}
Widget::~Widget()
{
delete ui;
}
void Widget::on_horizontalSlider_valueChanged(int value)
{
const QRect& rect = this->geometry();
this->setGeometry(rect.x(),rect.y(),value,rect.height());
}
void Widget::on_verticalSlider_valueChanged(int value)
{
const QRect& rect = this->geometry();
this->setGeometry(rect.x(),rect.y(),rect.width(),value);
}
⏩️代码练习2:通过来方向键来控制滑动条:
#include "widget.h"
#include "ui_widget.h"
#include<QShortcut>
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
//设置快捷键 - 减少 = 增加
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);
}
六、List Widget 控件
▶️Qt 中提供多元素的控件有六种:QListWiget、QListView、QTableWiget、QTableView、QTreeWidget、QTreeView,从他们的名字就不难看出,List 是列表,Table是表格,Tree是树状。
⏩️至于 xxxWidget 和 xxxView 的区别是什么?简单来说就是xxxView是更底层的实现,而 Widget 是基于View封装而来的;更具体来说 xxxView 是 MVC 结构的一种典型的实现,什么 MVC 呢?MVC 是软件开发中非常典型的软件结构的组织形式,其中 M 是 model: 数据,V 是 view:视图界面,C 是 controller:控制器,实现数据和视图之间的业务流程。不过 Qt 中的 view 只负责实现了视图,不负责数据如何存储表示也不负责数据和视图之间的交互,因此,如果使用 xxxView 就需要程序员自己实现 model 和 controller 的部分,比较麻烦。总之,xxxWidget 基于 xxxView 的同时把 model 和 controller 也帮我们实现好了,拿过来就能用,并且提供了功能很方便的 api 。
⏩️我们先来说说 List Widdget 它是一个能够显示纵向的列表,我们看看它的核心属性。
⏩️核心属性:
属性 | 说明 |
currentRow | 当前被选中的是第⼏⾏ |
count | ⼀共有多少⾏ |
sortingEnabled | 是否允许排序 |
isWrapping | 是否允许换⾏ |
itemAlignment | 元素的对⻬⽅式 |
selectRectVisible | 被选中的元素矩形是否可⻅ |
spacing | 元素之间的间隔 |
⏩️核心方法:
方法 | 说明 |
addItem(const QString& label) addItem(QListWidgetItem *item) | 列表中添加元素 |
currentItem() | 返回 QListWidgetItem* 表⽰当前选中的元素 |
setCurrentItem(QListWidgetItem* item) | 设置选中哪个元素 |
setCurrentRow(int row) | 设置选中第⼏⾏的元素 |
insertItem(const QString& label, int row) insertItem(QListWidgetItem *item, int row) | 在指定的位置插⼊元素 |
item(int row) | 返回 QListWidgetItem* 表⽰第 row ⾏的元素 |
takeItem(int row) | 删除指定⾏的元素, 返回 QListWidgetItem* 表⽰是哪个元素被删 除了 |
⏩️核心信号:
信号 | 说明 |
currentItemChanged(QListWidgetItem* current, QListWidgetItem* old) | 选中不同元素时会触发. 参数是当前选中的元素和之前选中的元素 |
currentRowChanged(int) | 选中不同元素时会触发. 参数是当前选中元素的⾏数 |
itemClicked(QListWidgetItem* item) | 点击某个元素时触发 |
itemDoubleClicked(QListWidgetItem* item) | 双击某个元素时触发 |
itemEntered(QListWidgetItem* item) | ⿏标进⼊元素时触发 |
❌️注意:在上面表格中,QListWidgetItem 这个类是 QListWiget 的一个元素,本质是就是文本加上图标构成。他的核心方法如下:
⏩️核心方法:
方法 | 说明 |
setFont | 设置字体 |
setIcon | 设置图标 |
setHidden | 设置隐藏 |
setSizeHint | 设置尺⼨ |
setSelected | 设置是否选中 |
setText | 设置⽂本 |
setTextAlignment | 设置⽂本对⻬⽅式 |
⏩️代码练习:
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include<QListWidgetItem>
QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE
class Widget : public QWidget
{
Q_OBJECT
public:
Widget(QWidget *parent = nullptr);
~Widget();
private slots:
void on_pushButton_add_clicked();
void on_pushButton_delete_clicked();
void on_listWidget_currentItemChanged(QListWidgetItem *current, QListWidgetItem *previous);
private:
Ui::Widget *ui;
};
#endif // WIDGET_H
#include "widget.h"
#include "ui_widget.h"
#include<QDebug>
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
//初始化
ui->listWidget->addItem("C++");
ui->listWidget->addItem("JAVA");
ui->listWidget->addItem("Python");
//另外一种方法初始化
// ui->listWidget->addItem(new QListWidgetItem("C++"));
// ui->listWidget->addItem(new QListWidgetItem("JAVA"));
// ui->listWidget->addItem(new QListWidgetItem("Python"));
//第三种方法:图形化界面右键添加项目
}
Widget::~Widget()
{
delete ui;
}
void Widget::on_pushButton_add_clicked()
{
//获取到输入框中的内容
const QString& text = ui->lineEdit->text();
//添加到 QListWidget
ui->listWidget->addItem(text);
}
void Widget::on_pushButton_delete_clicked()
{
//获取到被选中的元素
int row = ui -> listWidget -> currentRow();
if(row < 0)
{
return;
}
//按照行号来删除
ui->listWidget->takeItem(row);
}
void Widget::on_listWidget_currentItemChanged(QListWidgetItem *current, QListWidgetItem *previous)
{
//通过这个函数来感知变化
if(current != nullptr)
{
qDebug()<<"当前行选中的元素:"<<current->text();
}
if(previous != nullptr)
{
qDebug()<<"上次被选中的元素:"<< previous->text();
}
}
七、总结
🔆🔆🔆本文全篇结束,看到这里的博友恭喜你,今天的你比昨天更进一步,能坚持看到这里的博友肯定是非常自律的优秀程序员。全文精讲 Qt 的各种控件的介绍和使用,给我们带来对 Qt 的不一样认识,嗯?怎么说呢?感觉可以和CSS较量一下哈,OKOK,多余的话不多说,干饭去了。
哦!对了,各位优秀的程序员觉得我博客给你带来帮助或者让你学到了知识,记得给博主一个关注哦~❤️❤️❤️
各位博友,下篇博客见🍁🍁🍁
转载自CSDN-专业IT技术社区
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/2403_84958571/article/details/151964198