QT常用控件篇(3)(下)

一、多元素控件

1.介绍和要点

  • 前面两个是列表

  • 中间两个是表格

  • 后面两个是树形

要点:

  • View 仅负责"视图" (V):在 MVC (Model-View-Controller) 架构中,View 只承担数据的可视化呈现不包含数据本身 (Model),也不处理用户交互逻辑(Controller)

  • Widget 是更高层的封装Widget 不仅包含 View 的显示能力 ,还内嵌了 Model (数据管理) 和 Controller (交互逻辑、事件响应、业务流程),形成一个自包含的 UI 组件

1.1 List Widget(列表)

1.属性

2.方法

QListWidgetItem (相当于QListWidget的元素)

3.信号

4.代码

cpp 复制代码
//添加元素
ui->listWidget->addItem("C++");
ui->listWidget->addItem("Java");
ui->listWidget->addItem("Python");

void MainWindow::on_pushButton_clicked()
{
   QString str = ui->lineEdit->text();//获取文本
   ui->listWidget->addItem(str);
}

void MainWindow::on_pushButton_2_clicked()
{
   //获取当前被选中的元素
   int row = ui->listWidget->currentRow();
   //删除这一行
   ui->listWidget->takeItem(row);
}

//选中不同元素会触发(如果你选的不是第一个元素,那么之前选中默认为第一个元素,如果你选的是第一个元素,就不会有反应)
void MainWindow::on_listWidget_currentItemChanged(QListWidgetItem *current, QListWidgetItem *previous)
{
   if(current != NULL && previous != NULL)
   {
       qDebug()<<"当前选中:" <<current->text();
       qDebug()<<"之前选中:" <<previous->text();
   }
}

1.2 Table Widget(表格)

1.方法

重点:倒数两个的类型错了,应该是QTableWidgetItem类型

QTable Widget Item

方法:

信号:

2.代码

cpp 复制代码
//创建3行
ui->tableWidget->insertRow(0);
ui->tableWidget->insertRow(1);
ui->tableWidget->insertRow(2);
//创建3列
ui->tableWidget->insertColumn(0);
ui->tableWidget->insertColumn(1);
ui->tableWidget->insertColumn(2);

//给3行去行名
ui->tableWidget->setVerticalHeaderItem(0,new QTableWidgetItem("第一行"));
ui->tableWidget->setVerticalHeaderItem(1,new QTableWidgetItem("第二行"));
ui->tableWidget->setVerticalHeaderItem(2,new QTableWidgetItem("第三行"));

//给3列去列名
ui->tableWidget->setHorizontalHeaderItem(0,new QTableWidgetItem("学号"));
ui->tableWidget->setHorizontalHeaderItem(1,new QTableWidgetItem("姓名"));
ui->tableWidget->setHorizontalHeaderItem(2,new QTableWidgetItem("年龄"));

//设置初始数据
ui->tableWidget->setItem(0,0,new QTableWidgetItem("1001"));
ui->tableWidget->setItem(0,1,new QTableWidgetItem("张三"));
ui->tableWidget->setItem(0,2,new QTableWidgetItem("18"));

ui->tableWidget->setItem(1,0,new QTableWidgetItem("1002"));
ui->tableWidget->setItem(1,1,new QTableWidgetItem("李四"));
ui->tableWidget->setItem(1,2,new QTableWidgetItem("19"));


ui->tableWidget->setItem(2,0,new QTableWidgetItem("1003"));
ui->tableWidget->setItem(2,1,new QTableWidgetItem("王五"));
ui->tableWidget->setItem(2,2,new QTableWidgetItem("18"));

//新增一行
void MainWindow::on_pushButton_clicked()
{
   int row = ui->tableWidget->rowCount();//获取行数
   ui->tableWidget->insertRow(row);
}

//新增一列
void MainWindow::on_pushButton_2_clicked()
{
   int col = ui->tableWidget->columnCount();//获取列数
   ui->tableWidget->insertColumn(col);
}

//删除一行
void MainWindow::on_pushButton_3_clicked()
{
   int row = ui->tableWidget->currentRow();//获取行号
   ui->tableWidget->removeRow(row);
}

//删除一列
void MainWindow::on_pushButton_4_clicked()
{
   int col = ui->tableWidget->currentColumn();//获取行数
   ui->tableWidget->removeColumn(col);
}

1.3 Tree Widget(树形)

1.介绍和要点

介绍:

"Tree Widget"相关的功能主要用于以树形结构展示层次化数据,用户可展开或折叠节点,并通过选择节点来管理数据。它的

要点:

Tree Widget 这个树形结构是没有根节点 的,所谓的顶层节点 其实就是第一层节点

2.方法

3.信号

TreeWidgetItem

属性:

方法:

4.代码

cpp 复制代码
//设置根目录的名字(虽然这个树形不存在根目录,但是可以给它取名)
ui->treeWidget->setHeaderLabel("动物");
QTreeWidgetItem* item1 = new QTreeWidgetItem();
item1->setText(0,"猫");//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);

//添加到顶层
void MainWindow::on_pushButton_clicked()
{
   //获取输入框内容
   const QString& text = ui->lineEdit->text();
   if(text.isEmpty())
   {
       return;
   }
   QTreeWidgetItem* item = new QTreeWidgetItem();
   item->setText(0,text);
   ui->treeWidget->addTopLevelItem(item);
}
//添加到指定节点下面
void MainWindow::on_pushButton_2_clicked()
{
   //获取输入框内容
   const QString& text = ui->lineEdit->text();
   if(text.isEmpty())
   {
       return;
   }
   //获取当前选中的节点
   QTreeWidgetItem* item = ui->treeWidget->currentItem();
   if(item == NULL)
   {
       return;
   }
   //构造新的item
   QTreeWidgetItem* newItem = new QTreeWidgetItem();
   newItem->setText(0,text);
   item->addChild(newItem);//添加到当前选中节点
}

void MainWindow::on_pushButton_3_clicked()
{
   //获取当前选中的节点
   QTreeWidgetItem* item = ui->treeWidget->currentItem();
   if(item == NULL)
   {
       return;
   }
   //获取当前选中节点的父节点
   QTreeWidgetItem* parent = item->parent();
   if(parent == NULL)
   {
       //顶层节点
       int index = ui->treeWidget->indexOfTopLevelItem(item);
       ui->treeWidget->takeTopLevelItem(index);
   }
   else
   {
       //非顶层节点
       parent->removeChild(item);
   }
}

二、容器类

2.1 Group Box

1.介绍和要点

介绍:
"Group Box"相关的功能主要用于
将一组相关的控件进行逻辑和视觉上的分组,提供带标题的框架容器。

容器类和多元素控件的区别

  • 多元素控件 :它包含的内容,是一个个自定义好的 Item 对象

  • 容器类控件 :包含的是各种控件 ,被容器类包含的控件,其父元素就不再是 this(窗口) ,而是容器

2.属性

重点: 如果checked为false(没有选中),那么容器里的控件无法使用

2.2 Tab Widget

1.介绍

介绍:
"Tab Widget"相关的功能主要用于
提供一个多页面的切换容器,每个页面(标签页)可承载不同的界面内容,用户通过点击标签标题在不同页面间切换。

要点:

  • 每一个标签页都是一个QWidget

    cpp 复制代码
    ui->Tab1;//就可以访问到这个标签了

2.属性

3.信号

4.方法

addTab

cpp 复制代码
int addTab(QWidget *page, const QString &label)

// 功能:向 QTabWidget 中添加一个新标签页,并返回该页的索引
// 参数说明:
//   • page  :要添加为新标签页的 QWidget 指针
//   • label :标签页上方显示的文本标题

removeTab

cpp 复制代码
void QTabWidget::removeTab(int index);
// 功能:从 QTabWidget 中移除指定索引的标签页

// 参数说明:
//   • index :要移除的标签页的索引(从 0 开始)

5.代码

cpp 复制代码
void MainWindow::on_pushButton_clicked()
{
    //使用addTab方法创建新的标签页
    int count = ui->tabWidget->count();//获取标签页数量
    QWidget* w = new QWidget();

    ui->tabWidget->addTab(w,QString("Tab") + QString::number(count + 1));

    //设置新标签被选中
    ui->tabWidget->setCurrentIndex(count);
}

void MainWindow::on_pushButton_2_clicked()
{
    //使用removeTab删除标签
    int index = ui->tabWidget->currentIndex();//获取选中的标签下表

    ui->tabWidget->removeTab(index);
}

三、布局管理器

3.1 VBoxLayout(垂直布局)

1.属性

2.方法

addWidget

cpp 复制代码
void QLayout::addWidget(QWidget *widget);
// 功能:将一个 QWidget 添加到布局(QLayout)中,由布局自动管理其几何位置和大小

setLayout

cpp 复制代码
void QWidget::setLayout(QLayout *layout);
// 功能:将一个布局(QLayout)应用到当前 QWidget 上,使布局管理该 widget 的子控件排列

3**.代码**

cpp 复制代码
//创建三个按钮,使用垂直布局管理起来
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);

4.要点

  • 如果对象没有绑定父对象,然后被添加到布局管理器中,当该布局被设置给某个窗口或容器控件 时,该窗口或容器控件会自动成为这些控件的父对象

  • 一个 widget 只能设置一个顶层布局管理器

3.2 HBoxLayout(水平布局)

1.属性

2.代码

cpp 复制代码
QPushButton* button1 = new QPushButton("按钮1");
QPushButton* button2 = new QPushButton("按钮2");
QPushButton* button3 = new QPushButton("按钮3");

QHBoxLayout* layout = new QHBoxLayout();//创建水平布局

layout->addWidget(button1);
layout->addWidget(button2);
layout->addWidget(button3);

this->setLayout(layout);

3.布局间嵌套

cpp 复制代码
QPushButton* button1 = new QPushButton("按钮1");
QPushButton* button2 = new QPushButton("按钮2");

QPushButton* button3 = new QPushButton("按钮3");
QPushButton* button4 = new QPushButton("按钮4");

//两个水平布局
QHBoxLayout* layout1 = new QHBoxLayout();
QHBoxLayout* layout2 = new QHBoxLayout();

//一个垂直布局
QVBoxLayout* layout3 = new QVBoxLayout();

layout1->addWidget(button1);
layout1->addWidget(button2);

layout2->addWidget(button3);
layout2->addWidget(button4);

//垂直布局把水平布局嵌套了
layout3->addLayout(layout1);
layout3->addLayout(layout2);

this->setLayout(layout3);

重点:布局嵌套并不违背"一个 QWidget 只能有一个顶层布局管理器"的规则,因为嵌套的子布局属于父布局的内容,而非直接设置在 QWidget 上

3.3 GridLayout(网格布局)

1.属性

重点 :在布局管理器中,若要使控件尺寸不均等,需通过设置拉伸比例来控制各控件或子布局所占空间的相对大小。

2.代码

cpp 复制代码
//创建4个按钮,采用2*2的方式进行布局
QPushButton* button1 = new QPushButton("按钮1");
QPushButton* button2 = new QPushButton("按钮2");

QPushButton* button3 = new QPushButton("按钮3");
QPushButton* button4 = new QPushButton("按钮4");

//创建网络布局管理器,将这些控件添加进去
QGridLayout* layout = new QGridLayout();
layout->addWidget(button1,0,0);//(阵营1,的第一个)
layout->addWidget(button2,0,1);//(阵营1,的第二个)
layout->addWidget(button3,2,0);//(阵营2,的第一个)
layout->addWidget(button4,2,1);//(阵营2,的第二个)

this->setLayout(layout);

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

3.要点

  • xy 并不表示网格中的行号和列号,而是用于标识所属类别或阵营 (例如用 1 表示白棋、2 表示黑球等);而"第几行""第几列"通常由声明顺序 决定,而非 xy 的数值本身。

  • 设置拉伸系数时,参数分别对应具体的行号和列号(基于声明顺序的索引),而非之前提到的阵营标识值。

  • 在布局管理器中,按钮垂直方向默认不会自动拉伸填充(保持最小高度),因此即使设置了行拉伸系数,按钮本身也不会随行高增加而变高;而水平方向则可以。

cpp 复制代码
	//把水平/垂直拉伸都打开
	button1->setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Expanding);

3.4 FormLayout(表单布局)

1.介绍

介绍:
"Form Layout"相关的功能主要用于
以表单形式组织"标签-控件"成对出现的布局,常用于设置界面或数据录入界面。

2.方法

addRow

cpp 复制代码
void QFormLayout::addRow(QWidget *label, QWidget *field);

//参数一:标签控件用来表示后面是干嘛的(可以为nullptr,代表不要标签)
//参数二:交互控件用来输出数据的

3.代码

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

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

//创建表单
QFormLayout* layout = new QFormLayout();
this->setLayout(layout);

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

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

3.5 Spacer(空白)

1.属性

2.代码

cpp 复制代码
QPushButton* button1 = new QPushButton("按钮1");
QPushButton* button2 = new QPushButton("按钮2");

//创建空白
QSpacerItem* spacer = new QSpacerItem(200,300);//传入空白的大小

//创建水平布局
QHBoxLayout* layout = new QHBoxLayout();
layout->addWidget(button1);
layout->addSpacerItem(spacer);//插入空白
layout->addWidget(button2);

this->setLayout(layout);