关注

【C/C++】不止基础!QT 控件的隐藏技巧与实战案例,一篇文章全收录

前言:

        Hello  Everyone!

我是橘颂TA

这里给带来新博客一篇,本博客全文精讲 Qt 的高阶功法,小白也能听懂,

当然也需要一定 C++ 的知识,全文有浅到难,步步解剖,给我们深入理解 Qt 在 GUI 

强大的功能,理解 Qt 的魅力;我是橘颂TA,有兴趣可以给我点个关注。

主页更多精彩文章,不要错过哦!


目录

一、Combo Box 控件

二、Spin Box 控件

三、Date Edit && Time Edit

四、Dial 控件

五、Slider 控件

六、List Widget 控件

七、总结


一、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

评论

赞0

评论列表

微信小程序
QQ小程序

关于作者

点赞数:0
关注数:0
粉丝:0
文章:0
关注标签:0
加入于:--