Qt的学习

发布于:2025-06-25 ⋅ 阅读:(20) ⋅ 点赞:(0)

1.多元素控件

        Qt 中提供的多元素控件有:

        • QListWidget

        • Q ListView

        • Q TableWidget

        • Q TableView

        • Q TreeWidget

        • Q TreeView

        xxView是更底层的实现;XWidget是基于xxView封装而来的。

        此处xxView只是负责实现了视图,不负责数据如何存储表示,更不负责数据和视图之间的交互。

        因此如果使用xxView就需要程序员自己实现model和controller的部分。操作比较繁琐。xxWidget基于xxView同时把model和controller都帮我们实现好了,拿过来过来就可以使用.xxWidget提供了功能很方便的api,让我们直接就用。

1.1 1 List Widget

        使⽤ QListWidget 能够显⽰⼀个纵向的列表.

代码如下:

#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");

    // 在 QListWidgetItem 中, 可以设置字体属性, 设置图标, 设置文字大小, 设置是否被选中等状态~~
//    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_insert_clicked()
{
    // 1. 先获取到输入框中的内容.
    const QString& text = ui->lineEdit->text();
    // 2. 添加到 QListWidget 中
    ui->listWidget->addItem(text);
}

void Widget::on_pushButton_delete_clicked()
{
    // 1. 先获取到被选中的元素是哪个.
    int row = ui->listWidget->currentRow();
    if (row < 0) {
        return;
    }
    // 2. 按照行号来删除元素
    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();
    }
}

执行结果如下:

1.2 Table Widget

        使⽤ QTableWidget 表⽰⼀个表格控件.⼀个表格中包含若⼲⾏,每⼀⾏⼜包含若⼲列. 表格中的每个单元格,是⼀个 QTableWidgetItem 对象 

1.3 Tree Widget

        使⽤ QTreeWidget 表⽰⼀个树形控件.⾥⾯的每个元素,都是⼀个 QTreeWidgetItem ,每个 QTreeWidgetItem 可以包含多个⽂本和图标,每个⽂本/图标为⼀个列.

        可以给 QTreeWidget 设置顶层节点(顶层节点可以有多个),然后再给顶层节点添加⼦节点,从⽽构成 树形结构.

#include "widget.h"
#include "ui_widget.h"

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);

    // 设置根节点的名字
    ui->treeWidget->setHeaderLabel("动物");

    // 新增顶层节点
    QTreeWidgetItem* item1 = new QTreeWidgetItem();
    // 每个节点都可以设置多个列. 此处为了简单就只设置一列了.
    item1->setText(0, "猫");
    // 添加到顶层节点中.
    ui->treeWidget->addTopLevelItem(item1);

    // 新增顶层节点
    QTreeWidgetItem* item2 = new QTreeWidgetItem();
    // 每个节点都可以设置多个列. 此处为了简单就只设置一列了.
    item2->setText(0, "狗");
    // 添加到顶层节点中.
    ui->treeWidget->addTopLevelItem(item2);

    // 新增顶层节点
    QTreeWidgetItem* item3 = new QTreeWidgetItem();
    // 每个节点都可以设置多个列. 此处为了简单就只设置一列了.
    item3->setText(0, "鸟");
    // 添加到顶层节点中.
    ui->treeWidget->addTopLevelItem(item3);

    // 添加一些子节点
    QTreeWidgetItem* item4 = new QTreeWidgetItem();
    item4->setText(0, "中华田园猫");
    item1->addChild(item4);

    QTreeWidgetItem* item5 = new QTreeWidgetItem();
    item5->setText(0, "布偶猫");
    item1->addChild(item5);

    QTreeWidgetItem* item6 = new QTreeWidgetItem();
    item6->setText(0, "暹罗猫");
    item1->addChild(item6);
}

Widget::~Widget()
{
    delete ui;
}


void Widget::on_pushButton_insertTopLevelItem_clicked()
{
    // 获取到输入框中的内容
    const QString& text = ui->lineEdit->text();
    // 构造一个 QTreeWidgetItem
    QTreeWidgetItem* item = new QTreeWidgetItem();
    item->setText(0, text);
    // 添加到顶层节点中
    ui->treeWidget->addTopLevelItem(item);
}

void Widget::on_pushButton_insertItem_clicked()
{
    // 获取到当前选中的节点
    QTreeWidgetItem* currentItem = ui->treeWidget->currentItem();
    if (currentItem == nullptr) {
        return;
    }
    // 获取到输入框的内容
    const QString& text = ui->lineEdit->text();
    // 构造一个 QTreeWidgetItem
    QTreeWidgetItem* item = new QTreeWidgetItem();
    item->setText(0, text);
    // 插入到选中节点的子节点中
    currentItem->addChild(item);
}

void Widget::on_pushButton_deleteItem_clicked()
{
    // 获取到选中的元素
    QTreeWidgetItem* currentItem = ui->treeWidget->currentItem();
    if (currentItem == nullptr) {
        return;
    }
    // 删除选中的元素, 需要先获取到父元素, 通过父元素进行删除
    QTreeWidgetItem* parent = currentItem->parent();
    if (parent == nullptr) {
        // 顶层元素
        int index = ui->treeWidget->indexOfTopLevelItem(currentItem);
        ui->treeWidget->takeTopLevelItem(index);
    } else {
        // 普通元素
        parent->removeChild(currentItem);
    }
}

运行结果如下:

        上述这几个控件相关的操作,数据都是在内存中保存的.无论在界面上做任何操作,重新运行程序,之前的数据就都没了。
        如果要想让数据能够重启也不丢失,就需要编写更多的代码吧内存存储的数据获取到,写入到文件中,并且在下次运行的时候从文件加载数据。

2. 容器类控件

        多元素控件,包含的内容,是一个一个的自定义好的“item”对象
        容器类控件,包含的内容是前面已经学过的各种控件了.QPushButton,QLineEditQLabel等.QGroupBox分组框,QTableWidget标签页

 2.1 GroupBox

        当一个界面比较复杂的时候,包含了很多控件的时候。分组框就可以把具有关联关系的控件,组织到一起。就只是为了让界面看起来更好看一点。

使用页面编辑效果如下:

2.2 TabWidget

        使⽤ QTabWidget 实现⼀个带有标签⻚的控件,可以往⾥⾯添加⼀些widget.进⼀步的就可以通过标 签⻚来切换.

图形化界面操作初始化如下:

#include "widget.h"
#include "ui_widget.h"
#include <QLabel>
#include <QDebug>

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);

    // 先在每个标签页中, 添加一个 Label
    QLabel* label1 = new QLabel(ui->tab);
    label1->setText("标签页1");
    label1->resize(100, 50);

    QLabel* label2 = new QLabel(ui->tab_2);
    label2->setText("标签页2");
    label2->resize(100, 50);
}

Widget::~Widget()
{
    delete ui;
}


void Widget::on_pushButton_clicked()
{
    // 使用 addTab 方法来创建新的标签页.
    // 参数1 要指定一个 QWidget.
    // 参数2 指定这个标签页的 text (标题), 此处标题就叫做 Tab + 数字
    int count = ui->tabWidget->count();  // 获取到标签页的数量
    QWidget* w = new QWidget();
    ui->tabWidget->addTab(w, QString("Tab ") + QString::number(count + 1));
    // 添加一个 QLabel 显示内容
    QLabel* label = new QLabel(w);
    label->setText(QString("标签页 ") + QString::number(count + 1));
    label->resize(100, 50);
    // 设置新标签页被选中
    ui->tabWidget->setCurrentIndex(count);
}

void Widget::on_pushButton_2_clicked()
{
    // 获取到当前选中的标签页的下标
    int index = ui->tabWidget->currentIndex();
    // 删除标签页
    ui->tabWidget->removeTab(index);
}

void Widget::on_tabWidget_currentChanged(int index)
{
    qDebug() << "当前选中的标签页是: " << index;
}

效果执行:

3. 布局管理器 

3.1 垂直布局

        使⽤ QVBoxLayout 表⽰垂直的布局管理器.V是vertical 的缩写。

        Layout 只是⽤于界⾯布局,并没有提供信号.

#include "widget.h"
#include "ui_widget.h"
#include <QPushButton>
#include <QVBoxLayout>

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);

    // 创建三个按钮, 使用垂直布局管理器管理起来.
    QPushButton* button1 = new QPushButton("按钮1");
    QPushButton* button2 = new QPushButton("按钮2");
    QPushButton* button3 = new QPushButton("按钮3");

    // 创建布局管理器
    QVBoxLayout* layout = new QVBoxLayout();
    layout->addWidget(button1);
    layout->addWidget(button2);
    layout->addWidget(button3);

    // 把布局管理器添加到窗口中.
    this->setLayout(layout);
}

Widget::~Widget()
{
    delete ui;
}

执行效果如下:

一般来说,每个widget中只能设置一个布局管理器。

实例:在一个widget中设置多个布局管理器

每个widget中只能设置一个布局管理器
        如果在代码中创建layout,其实是只创建了一个layout
        如果在QtDesigner中创建的layout,先创建了一个Widget,然后再在这个新的Widget中添加了一个layout.

3.2 ⽔平布局

        使⽤ QHBoxLayout 表⽰垂直的布局管理器.H是 horizontal 的缩写 。

布局管理器之间也能进行嵌套。

#include "widget.h"
#include "ui_widget.h"
#include <QPushButton>
#include <QHBoxLayout>
#include <QVBoxLayout>

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);

    // 创建垂直的布局管理器
    QVBoxLayout* vlayout = new QVBoxLayout();
    this->setLayout(vlayout);

    // 添加两个按钮进去
    QPushButton* button1 = new QPushButton("按钮1");
    QPushButton* button2 = new QPushButton("按钮2");
    vlayout->addWidget(button1);
    vlayout->addWidget(button2);

    // 创建水平的布局管理器
    QHBoxLayout* hlayout = new QHBoxLayout();

    // 添加两个按钮进去
    QPushButton* button3 = new QPushButton("按钮3");
    QPushButton* button4 = new QPushButton("按钮4");
    hlayout->addWidget(button3);
    hlayout->addWidget(button4);

    // 把水平布局管理器添加到垂直布局管理器内部
    vlayout->addLayout(hlayout);
}

Widget::~Widget()
{
    delete ui;
}

效果如下:

3.3 ⽹格布局

        Qt 中还提供了 QGridLayout ⽤来实现⽹格布局的效果.可以达到M*N的这种⽹格的效果

        刚创建的布局管理器,这里的控件尺寸都是均等的。当需要创建出尺寸不同的控件的时候,就可以通过拉伸系数来设置,拉伸系数就相当于设置控件之间尺寸的“比例“。

    // 设置水平拉伸系数.
    layout->setColumnStretch(0, 0);
    layout->setColumnStretch(1, 1);
    layout->setColumnStretch(2, 2);

        由于按钮垂直方向默认没有拉伸开(水平方向默认是拉伸的)因此垂直方向不会受到拉伸系数的影响了,要想让垂直方向的拉伸系数生效,就需要让按钮先能够拉伸展开。

3.4 表单布局 

          除了上述的布局管理器之外,Qt还提供了QFormLayout,属于是QGridLayout的特殊情况,专门用于实现两列表单的布局。这种表单布局多用于让用户填写信息的场景,左侧列为提示,右侧列为输入框

#include "widget.h"
#include "ui_widget.h"
#include <QFormLayout>
#include <QLabel>
#include <QLineEdit>
#include <QPushButton>

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);

    // 设置成 3 行 2 列.
    QFormLayout* layout = new QFormLayout();
    this->setLayout(layout);

    // 创建 3 个 label 作为第一列
    QLabel* label1 = new QLabel("姓名");
    QLabel* label2 = new QLabel("年龄");
    QLabel* label3 = new QLabel("电话");

    // 创建 3 个 输入框 作为第二列
    QLineEdit* edit1 = new QLineEdit();
    QLineEdit* edit2 = new QLineEdit();
    QLineEdit* edit3 = new QLineEdit();

    // 把上述控件添加到表单布局中
    layout->addRow(label1, edit1);
    layout->addRow(label2, edit2);
    layout->addRow(label3, edit3);

    // 创建一个 "提交按钮"
    QPushButton* button = new QPushButton("提交");
    layout->addRow(nullptr, button);
}

Widget::~Widget()
{
    delete ui;
}

3.5 Spacer

        使⽤布局管理器的时候,可能需要在控件之间,添加⼀段空⽩.就可以使⽤ QSpacerItem 来表⽰.

 QHBoxLayout* layout = new QHBoxLayout();
    this->setLayout(layout);

    QPushButton* button1 = new QPushButton("按钮1");
    QPushButton* button2 = new QPushButton("按钮2");

    // 创建 spacer 使两个按钮之间存在空白.
    QSpacerItem* spacer = new QSpacerItem(200, 20);

    // 当前是要把空白添加到两个按钮之间. 此处 add 的顺序就是把 addSpacerItem 放到中间了.
    layout->addWidget(button1);
    layout->addWidget(button2);
    layout->addSpacerItem(spacer);

 ps:对于qt的部分控件的学习就到这里了,谢谢观看!!!


网站公告

今日签到

点亮在社区的每一天
去签到