QT(2.0)

1.常用控件的介绍

1.1 TextEdit

QTextEdit表示多行输入框,也是一个富文本&markdown编辑器,并且能在内容超出编辑框范围时自动提供滚动条。

核心属性

属性

说明

markdown

输入框内持有的内容,支持markdown格式,能够自动的对markdown文本渲染成html

html

输入框持有的内容,可以支持大部分html标签,包括img和table等

placeHolderText

输入框为空时提醒的内容

readOnly

是否是只读的

undoRedoEnable

是否开启undo/redo功能
按下ctrl+z触发undo
按下ctrl+y触发redo

autoFormating

开启自动格式化

tabstopWidth

按下缩进多少控件

overwriteMode

是否开启覆盖写模式

AcceptRichText

是否接受富文本内容

VerticalScrollBarPolicy

垂直方向滚动条的出现策略
Qt::ScrollBarAsNeeded:根据内容自动决定是否需要滚动条。这是默认值
 Qt::ScrollBarAlwaysOff:总是关闭滚动条                                                    
Qt::ScrollBarAlwaysOn:总是显示滚动条                                                   

HorizontalScrollBarPolicy

水平方向滚动条的出现策略
Qt::ScrollBarAsNeeded:根据内容自动决定是否需要滚动条。这是默认值
Qt::ScrollBarAlwaysOff:总是关闭滚动条。
Qt::ScrollBarAlwaysOn:总是显示滚动条。

核心信号

TextChanged()

文本内容改变时触发

selectionChanged()

选中范围改变时触发

cursorPositionChanged()

光标移动时触发

undoAvailable(bool)

可以进行undo操作时触发

redoAvailable(bool)

可以进行redo操作时触发

copyAvaiable(bool)

文本被选中/取消选中时触发

代码示例:创建一个label和QTextEdit获取用户输入的文本,显示值label中

通过Qt designer创建两个控件出来,然后通过点击QTextEdit转到槽TextChanged(),进行编写代码

void Widget::on_textEdit_textChanged()
{//获取用户输入到textEdit中的文本const QString& text = ui->textEdit->toPlainText();//将获取到的文本设置到label中ui->label->setText(text);
}

运行结果:

还可以看看其他信号的触发情况

void Widget::on_textEdit_copyAvailable(bool b)
{qDebug() << "文本是否被选中:" << b;
}void Widget::on_textEdit_cursorPositionChanged()
{qDebug() << "光标移动";
}void Widget::on_textEdit_undoAvailable(bool b)
{qDebug() << "触发undo";
}void Widget::on_textEdit_currentCharFormatChanged(const QTextCharFormat &format)
{QFont font = format.font(); // 获取当前字符格式的字体信息QColor textColor = format.foreground().color(); // 获取当前字符格式的前景色qDebug() << "Font family: " << font.family();qDebug() << "Font size: " << font.pointSize();qDebug() << "Text color: " << textColor;// 在这里可以根据需要更新界面上的其他部分或者执行其他操作
}

1.2 ComboBox

QcomboBox表示下拉框

核心属性

属性

说明

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)

currentIndecChanged(const QString& text)

当前选项改变时发出。

此时用户已经明确的选择了一个选项
用户操作或者通过程序操作都会触发这个信号

editTextChanged(const QString& text)

当编辑框中的文本改变时发出

(editable为true时有效)

代码示例:创建三个下拉框(comboBox)和一个按钮(pushButton),实现用户选中“食物”,点击“确认”按钮后,打印出用户选择的食物

//添加下拉框选项
ui->comboBox->addItem("陕西凉皮");
ui->comboBox->addItem("擀面皮");
ui->comboBox->addItem("凉面");ui->comboBox_2->addItem("素鸡夹馍");
ui->comboBox_2->addItem("锅盔");ui->comboBox_3->addItem("雪碧");
ui->comboBox_3->addItem("可乐");
void Widget::on_pushButton_clicked()
{const QString& Text1 = ui->comboBox->currentText();const QString& Text2 = ui->comboBox_2->currentText();const QString& Text3 = ui->comboBox_3->currentText();qDebug() << Text1 << Text2 << Text3;
}

运行结果:

在很多情况下,我们都需要从文件中加载资源到程序中,我们来模拟实现从本地文件中获取数据,填入到下拉框中

我们在再电脑本地创建一个文件,然后在QT中加在这个文件

    //打开文件std::ifstream file("D:/QT/Text.txt");std::string line;//获取文件中的数据while (std::getline(file, line)) {ui->comboBox->addItem(QString::fromStdString(line));}

运行结果:

1.3 SpinBox

使用QSpinBox或者QDoubleSpinBox表示“微调框”,它是带有按钮的输入框, 可以用来输入整数/浮点数,通过点击按钮来修改数值大小

QSpinBox核心属性

属性

说明

Value

存储的数值

singleStep

每次调整的“步长”,按下一次按钮变化多少

displayInteger

数字的进制,例如displayInteger设为10,则是按照10进制表示,设为2则为2进制表示

minimum

最小值

maximum

最大值

suffix

后缀

prefix

后缀

wrapping

是否允许换行

frame

是否带边框

alignment

文字对齐方式

readOnly

是否允许修改

buttonSymbol

按钮上的图标

UpDownArrows 上下箭头形式

PlusMinus 加减号形式

NoButtons 没有按钮

Accelerated(加速的)

按下按钮时是否为快速调整模式

correctionMode

输入有误时如何修改.

QAbsteactSpinBox::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,表示当前的数值

代码示例:实现购物车结算

    ui->comboBox->addItem("陕西凉皮");ui->comboBox->addItem("擀面皮");ui->comboBox->addItem("凉面");ui->comboBox_2->addItem("素鸡夹馍");ui->comboBox_2->addItem("锅盔");ui->comboBox_3->addItem("雪碧");ui->comboBox_3->addItem("可乐");//设置初始值为1,每次增加份数/1份,最多可以买5份ui->spinBox->setValue(1);ui->spinBox->setRange(1, 5);ui->spinBox_2->setValue(1);ui->spinBox_2->setRange(1, 5);ui->spinBox_3->setValue(1);ui->spinBox_3->setRange(1, 5);ui->spinBox->setCorrectionMode(QAbstractSpinBox::CorrectToNearestValue);
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();
}

1.4 DateEdit & TimeFdit

使用QDateEdit作为日期的微调框

使用QTimeEdit 作为时间的微调框

使用QDateTimeEdit作为时间日期的微调框

由于这些控件十分相似,我们这里只介绍最全的QDateTimeEdit这个控件

QDateTime核心属性

属性

说明

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 表示秒

注意:格式化符号,无需记忆,不同语言/库中均存在差异

minmumDateTime

最小时间日期

maximumDateTime

最大日期时间

timeSpec

Qt::localTime: 显示本地时间

Qt::UTC: 显示协调世界时(UTC)

Qt::OffsetFromUTC:显示相对UTC的偏移量(时差)

关于本地时间(LocalTime)和协调世界时(UTC)

UTC时间是一个基于原子钟的标准时间,不受地球的自转周期影响,和格林威治时间(GMT)是非常接近的,科学家会通过精密的设备来测量并维护

咱们得计算机内部使用的时间就是基于UTC时间。

本地时间是基于不同时区,对UTC时间做出了一些调整,比如咱们使用的北京时间,位于“东八区”,就需要再UTC时间基础上+8小时的时差

核心信号

信号

说明

dateChanged(QDate)

日期改变时触发

timeChanged(QTime)

时间改变时触发

dateTimeChanged(QDateTime)

时间日期任意一个改变时触发

代码示例:实现日期计算器

void Widget::on_pushButton_clicked()
{//获取两个时间的日期QDateTime timeOld = ui->dateTimeEdit_old->dateTime();QDateTime timeNew = ui->dateTimeEdit_new->dateTime();//计算时间差int days = timeOld.daysTo(timeNew);int hours = (timeOld.secsTo(timeNew) / 3600) % 24;//设置label中的值QString timeDifference = QString("它们之间相差:") + QString::number(days) +QString("天") + QString::number(hours) + QString("小时");ui->label->setText(timeDifference);

运行结果:

1.5 Dial

使用QDial表示一个旋钮,在一些程序中,通过鼠标拖动旋转,即可完成一些相关的设置

核心属性

属性

说明

value

持有的数值

minimun

最小值

maximum

最大值

singleStep

按下方向键的时候改变的步长

pageStep

按下pageUp / pageDown的时候改变的步长

sliderPosition

界面上旋钮显示的初始位置

tracking

外观是否会跟踪数值变化

默认值为true,一般不需要修改

wrapping

是否允许循环调整。

即数值如果超过最大值,是否允许回到最小值。

(调整过程能否“套圈”)

notchesVisible

是否显示刻度线

notchTarget

刻度线之间的相对位置。

数字越大,刻度线越稀疏

核心信号

属性

说明

valueChanged(int)

数值改变时触发

rangeChanged(int, int)

范围变化时触发

代码示例:通过Dial实现调节窗口的透明度

    //设置可以循环旋转ui->dial->setWrapping(true);//设置刻度线可见ui->dial->setNotchesVisible(true);//设置最大值和最小值ui->dial->setMaximum(100);ui->dial->setMinimum(0);//设置初始值ui->dial->setValue(100);
void Widget::on_dial_valueChanged(int value)
{ui->label->setText(QString("当前透明度:") + QString::number(value));this->setWindowOpacity((double)value / 100);
}

运行结果:

1.6 Slider

使用QSlider表示一个滑动条

与QDial用法相似,均继承自QAbstactSlider

核心属性

属性

说明

value

持有的数值

minimum

最小值

maximum

最大值

singleStep

按下方向键的时候改变的步长

pageStep

按下pageUp / pageDown 的时候改变的步长

sliderPosition

滑动条显示的初始位置

tracking

外观是否会跟踪数值变化

默认值为true,一般不需要修改

orientation

滑动条的方向是水平还是垂直

invertedAppearance

是否要翻动滑动条的方向

tickPosition

刻度的位置

tickInterval

刻度的密集程度

核心信号

属性

说明

valueChanged(int)

数值改变时触发

rangeChanged(int, int)

范围变化时触发

代码示例:调整窗口大小

    ui->horizontalSlider->setMaximum(800);ui->horizontalSlider->setMinimum(200);ui->horizontalSlider->setSingleStep(100);ui->horizontalSlider->setValue(800);ui->verticalSlider->setMaximum(1024);ui->verticalSlider->setMinimum(224);ui->verticalSlider->setSingleStep(100);ui->verticalSlider->setValue(1024);//改变朝向,默认自上而下ui->verticalSlider->setInvertedAppearance(true);
void Widget::on_horizontalSlider_valueChanged(int value)
{QRect rect = this->geometry();this->setGeometry(rect.x(), rect.y(), value, rect.height());qDebug() << value;
}void Widget::on_verticalSlider_valueChanged(int value)
{QRect rect = this->geometry();this->setGeometry(rect.x(), rect.y(), rect.width(), value);qDebug() << value;
}

运行结果:

1.7 多元素控件

QListWidget, QListView, QTableWidget, QTableView, QTreeWidget, QTreeView

xxWidget 和 xxView 之间的区别

以QTabelWidget 和 QTableView 为例

QTableView 是基于MVC设计的控件, QTableView自身不持有数据, 使用QTableView的时候需要用户创建一个Model对象(比如 QStanfardModel),并且把Model和QTableView关联起来,后续修改Model中的数据就会影响QTableView的显示; 修改QTableView的显示;修改QTableView的显示也会影响到Model中的数据(属于双向绑定)

QTableWidget 则是QTableView的子类,对Model 进行了封装,不需要用户手动创建Model 对像,直接就可以往QTableWidget 中添加数据了

1.7.1 List Widget

使用 QListWidget 能够显示一个纵向的列表,形如:

其中每项都可以被选择

核心属性

属性

说明

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 . 这个类表⽰ QListWidget 中的⼀个元素.
核⼼⽅法如下, 本质上就是⼀个 "⽂本+图标" 构成的.

方法

说明

setFont

设置字体

setIcon

设置图标

setHidden

设置隐藏

setSizeHint

设置尺寸

setSelected

设置是否被选中

setText

设置文本

setTextAlignment

设置文本对齐方式

代码示例:实现QListWidget的新增和获取

    ui->lineEdit->setPlaceholderText("请输入你想增加的文本");ui->listWidget->addItem("c++");ui->listWidget->addItem("java");ui->listWidget->addItem("python");
void Widget::on_pushButton_clicked()
{// 获取用户输入的文本const QString& text = ui->lineEdit->text();if(text.isEmpty()){return;}ui->listWidget->addItem(text);}void Widget::on_pushButton_2_clicked()
{//获取被选中的行号int row = ui->listWidget->currentRow();ui->listWidget->takeItem(row);
}void Widget::on_listWidget_currentItemChanged(QListWidgetItem *current, QListWidgetItem *previous)
{//此信号之前和当前所选中的文本指针不能为空if(current != nullptr && previous != nullptr){qDebug() << "当前" << current->text() << "之前" << previous->text();}
}
1.7.2 Table Widget

使用QTableWidget表示一个表格控件, 一个表格中包含若干行,每一行又包含若干列, 表格中的每个单元格,是一个QTableWidgetItem对象

QTableWidget核心方法

方法

说明

item(int row, int column)

根据行数列数获取指定的QTableWidgetItem*

setItem(int row, int column, QTableWidget*)

根据行数列数设置表格中的元素

currentItem()

返回被选中的元素QTableWidgetItem*

currentRow()

返回被选中元素时第几行

currentColumn()

返回被选中元素时第几列

Row(QTableWidgetItem*)

获取指定item是第几行

Column(QTableWidgetItem*)

获取指定item是第几列

rowCount()

获取行数

columnCount()

获取列数

insertRow(int row)

在第row行处插入新行

insertColumn(int column)

在第column列插入新列

setHorizeontalHeaderItem(int column, QTableWidget*)

设置指定列的表头

setVerticalHeaderItem(int row,  QTableWidget*

设置指定的表头

removeRow(int row)

删除第row行

removeColumn(int column)

删除第column列

QTableWidgetItem 核心信号

信号

说明

cellClicked(int row, int column)

点击单元格时触发

cellDoubleClicked(int row, int column)

双击单元格是触发

cellEntered(int row, int column)

鼠标进入单元格时触发

currentCellChanged(int row, int column, int previousRow, int previousColumn)

选中不同单元格时触发

QTableWidgetItem核心方法

方法

说明

Row()

获取当前是第几行

Column()

获取当前是第几列

setText(const QString&)

设置文本

setTextAlignment(int)

设置文本对齐

setIcon(const QIcon&)

设置图标

setSelected(bool)

设置被选中

setSizeHints(const Qsize&)

设置尺寸

setFont(const QFont&)

设置字体

代码示例:使用Table WIdget实现表格

    ui->lineEdit->setPlaceholderText("请输入新增的列名");//新增三行ui->tableWidget->insertRow(0);ui->tableWidget->insertRow(1);ui->tableWidget->insertRow(2);//新增三列ui->tableWidget->insertColumn(0);ui->tableWidget->insertColumn(1);ui->tableWidget->insertColumn(2);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("张三"));ui->tableWidget->setItem(0, 1, new QTableWidgetItem("19"));ui->tableWidget->setItem(0, 2, new QTableWidgetItem("西安"));ui->tableWidget->setItem(1, 0, new QTableWidgetItem("李四"));ui->tableWidget->setItem(1, 1, new QTableWidgetItem("20"));ui->tableWidget->setItem(1, 2, new QTableWidgetItem("杭州"));ui->tableWidget->setItem(2, 0, new QTableWidgetItem("王五"));ui->tableWidget->setItem(2, 1, new QTableWidgetItem("21"));ui->tableWidget->setItem(2, 2, new QTableWidgetItem("北京"));
void Widget::on_pushButton_clicked()
{//获取当前行号int row = ui->tableWidget->rowCount();//插入新的行ui->tableWidget->insertRow(row);
}void Widget::on_pushButton_2_clicked()
{const QString& text = ui->lineEdit->text();//有文本则新增一行if(text.isEmpty()){return;}else {//获取当前的列号int column = ui->tableWidget->columnCount();ui->tableWidget->insertColumn(column);ui->tableWidget->setHorizontalHeaderItem(column, new QTableWidgetItem(text));}}void Widget::on_pushButton_3_clicked()
{int row = ui->tableWidget->currentRow();ui->tableWidget->removeRow(row);
}void Widget::on_pushButton_4_clicked()
{int column = ui->tableWidget->currentColumn();ui->tableWidget->removeColumn(column);
}

运行结果:

1.7.3 Tree Widget

使用QTreeWidget 表示一个树形控件,里面的每个元素,都是一个QTreeWidgetItem,每个QTreeWidgetItem可以包含多个文本和图标,每个文本/图标为一个列。

可以给QTreeWIdget设置顶层节点(顶层节点可以有多个),然后再给顶层节点添加子节点,从而构成树形结构

QTreeWidget核心方法

方法

说明

clear

清空所有子节点

addTopLevelItem(QTreeWidgetItem* item)

新增顶层节点

topLevelItem(int index)

获取指定下标的顶层节点

topLevelItemCount()

获取顶层节点个数

indexOfTopLevelItem(QTreeWidgetItem* item)

查询指定节点是顶层节点中的下标

tackTopLevelItem(int index)

删除指定的顶层节点,返回QTreeWidgetItem* 表示被删除的元素

currentItem()

获取到当前选中的节点,返回QTreeWidgetItem*

setCurrentItem(QTreeWidgetItem* item)

选中指定节点

setExpanded(bool)

展开/关闭节点

setHeaderLabel(const QString& text)

设置TreeWidget的header名称

QTreeWidget 核心信号

信号

说明

currentItemChanged(QTreeWidgetItem* current, QTreeWidgetItem* old)

切换选中元素时触发

itemClicked(QTreeWidgetItem* item, int col)

点击元素时触发

itemEntered(QTreeWidgetItem* item , int col)

鼠标进入时触发

itemExpanded(QTreeWidgetItem* item)

元素被展开时触发

itemCollapsend(QTreeWidgetItem* item)

元素被折叠时触发

QTreeWidgetItem核心方法

方法

说明

addChild(QTreeWidgetItem* child)

新增子节点

childCount()

子节点的个数

Chile(int index)

获取指定下标的子节点,返回QTreeWidgetItem*

tackChild(int index)

删除对应下标的子节点

removeChile(QTreeWidgetItem* child)

删除对应的子节点

parent()

获取该元素的父节点

代码示例:使用TreeWidget,完成插入(顶层和非顶层)和删除

    ui->treeWidget->setHeaderLabel("动物");QTreeWidgetItem* item1 = new QTreeWidgetItem();item1->setText(0, "cat");ui->treeWidget->addTopLevelItem(item1);QTreeWidgetItem* item2 = new QTreeWidgetItem();item2->setText(0, "doy");ui->treeWidget->addTopLevelItem(item2);QTreeWidgetItem* item3 = new QTreeWidgetItem();item3->setText(0, "sheep");ui->treeWidget->addTopLevelItem(item3);
void Widget::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 Widget::on_pushButton_2_clicked()
{//获取输入框文本const QString& text = ui->lineEdit->text();if(text.isEmpty()){return;}//找到父亲节点QTreeWidgetItem* currentItem = ui->treeWidget->currentItem();if(currentItem == nullptr){return;}//新生成一个QTreeWidgetItemQTreeWidgetItem* newItem = new QTreeWidgetItem();//设置文本,添加至父节点中,展开父节点newItem->setText(0, text);currentItem->addChild(newItem);currentItem->setExpanded(true);}void Widget::on_pushButton_3_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);}
}

运行结果:

1.8 容器类

1.8.1 QGroupBox

使用QGroupBox实现一个带有标题的分组框,可以把其他的控件放到里面作为一组,这样看起来能更好看一点。

注意:不要将QGroupBox和QButtonGroup混淆.

QGroupBox核心属性

属性

说明

title

分组框的标题

alignment

分组框内部内容的对齐方式

flat

是否是“扁平”模式

checkable

是否可选择.

设为true,则是title前方会多出一个可勾选的部分

checkeed

描述分组框的选择状态(前提是checkable为true)

分组框只是一个用来“美化界面”这样的组件,并不涉及到用户交互和业务逻辑,属于“锦上添花”

代码示例:使用QCroupBox优化之前的点餐界面

    ui->groupBox->setTitle("点餐");ui->comboBox->addItem("凉皮");ui->comboBox->addItem("烤肉");ui->spinBox->setValue(1);
void Widget::on_pushButton_clicked()
{qDebug() << ui->comboBox->currentText()<< "份数" << ui->spinBox->value();
}

运行结果:

1.8.2 Tab Widget

使用QTabWidget实现一个带有标签页的控件, 可以往里面添加一些widget,进一步的就可以通过标签页来切换。

TabWidget核心属性

属性

说明

tabPosition

标签页所在的位置.

North 上方

South 下方

West 左侧

East 右侧

currentIndex

当前选中了第几个标签页(从0开始计算)

currentTabText

当前选中的标签页的文本

currentTabName

当前选中的标签页的图标

currentTabToolTip

当前选中的标签页的提示信息

tabsCloseable

标签页是否关闭

moveable

标签页是否可以移动

核心信号

属性

说明

currentChanged(int)

在标签页发生切换时触发,参数为点击的选项卡编号

tabBarClicked(int)

在点击选项卡的标签条的时候触发,参数为被点击的选项卡编号

tabBarDoubleClicked(int)

在双击选项卡的标签页的时候触发,参数为被点击的选项卡编号

tabCloseRequest(int)

在标签页关闭时触发,参数为被关闭的选项卡编号

代码示例:使用标签页管理多组控件

1)在界面上创建一个QTabWidget,和两个按钮。按钮的objectName为pushButton_add和pushButton_remove

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QTabWidget>
#include <QDebug>
#include <QLabel>
MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow)
{ui->setupUi(this);connect(ui->pushButton_add, &QPushButton::clicked, this, &MainWindow::PushButtonAdd);connect(ui->pushButton_remove, &QPushButton::clicked, this, &MainWindow::PushButtonremove);QLabel* label_1 = new QLabel(ui->tab);label_1->setGeometry(100, 100, 200, 50);label_1->setText("标签1");QLabel* label_2 = new QLabel(ui->tab_2);label_2->setGeometry(100, 100, 200, 50);label_2->setText("标签2");
}MainWindow::~MainWindow()
{delete ui;
}void MainWindow::PushButtonAdd()
{/* 获取当前所存在的tab页面 */int count = ui->tabWidget->count();/* 生成新的tab页面,并将其添加至QTabWidget中 */QWidget* tag = new QWidget();ui->tabWidget->addTab(tag, QString("tab") + QString::number(count + 1));QLabel* label = new QLabel(tag);label->setGeometry(100, 100, 200, 50);label->setText(QString("标签") + QString::number(count + 1));ui->tabWidget->setCurrentIndex(count);
}void MainWindow::PushButtonremove()
{/* 获取当前选中的页面号,并删除它 */int index = ui->tabWidget->currentIndex();ui->tabWidget->removeTab(index);
}

运行结果:

1.9 布局管理器

之前使用Qt在界面上创建的控件, 都需要通过“绝对定位”的方式来设定的。

也就是每个控件所在的位置,都需要计算坐标,最后通过move和setGeometry方式来设置

这种设定方式其实并不是很方便,尤其在界面内容较多的情况下,不好计算,而且一个窗口大小往往是可以调整的,按照绝对定位的方式,也无法自适应窗口大小

因此Qt引入“布局管理器”(Layout)机制, 来解决上述问题

1.9.1 垂直布局

使用QVBoxLayout 表示垂直的布局管理器,V是vertical的缩写

属性说明
layoutLeftMargin左侧边距
layoutRightMargin右侧边距
layoutTopMargin上方边距
layoutBottomMargin下方边距
layoutSpacing相邻元素之间的间距

Layout只是用于界面布局,并没有提供信号

代码示例:使用QVBoxLayout管理多个控件

1)编写代码,创建布局管理器和三个按钮,并且把按钮添加到布局管理器中。

使用addWidget 把控件添加到布局管理器中
使用setLayout设置该布局管理器到widget中

#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* button_1 = new QPushButton("按钮1");QPushButton* button_2 = new QPushButton("按钮1");QPushButton* button_3 = new QPushButton("按钮1");QVBoxLayout* layout = new QVBoxLayout();layout->addWidget(button_1);layout->addWidget(button_2);layout->addWidget(button_3);this->setLayout(layout);
}Widget::~Widget()
{delete ui;
}

运行结果:

通过上述代码的方式,只能给这个widget设定一个布局管理器,实际上也是可以通过Qt Design在一个窗口中创建多个布局管理器

代码示例:

创建两个QVBoxLayout

1)在界面上创建两个QVBoxLayout,每个QVBoxLayout各放三个按钮

运行结果:

实际上一个Widget只能创建一个QVBoxLayout,那我我们这个是怎么实现的呢

注:这种情况下layout并非是窗口widget的布局管理器,因此无法随窗口的大小而改变

1.9.2 水平布局

使用QHBoxLayout表示垂直的布局管理器,H是horizontal的缩写,核心属性(和QVBoxLayout一致)

属性说明
layoutLeftMargin左侧边距
layoutRightMargin右侧边距
layoutTopMargin上方边距
layoutBottomMargin下方边距
layoutSpacing相邻元素之间的间距

代码示例:嵌套的layout

1) 在代码中创建addLayout,给其layout中添加子layot

#include "widget.h"
#include "ui_widget.h"
#include <QHBoxLayout>
#include <QPushButton>Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);//创建顶层layoutQVBoxLayout* layout = new QVBoxLayout();//创建按钮QPushButton* button_1 = new QPushButton("按钮1");QPushButton* button_2 = new QPushButton("按钮2");//添加到widget中this->setLayout(layout);layout->addWidget(button_1);layout->addWidget(button_2);//创建子layoutQHBoxLayout* layout_2 = new QHBoxLayout();QPushButton* button_3 = new QPushButton("按钮3");QPushButton* button_4 = new QPushButton("按钮4");layout_2->addWidget(button_3);layout_2->addWidget(button_4);//子layout添加到父layout中layout->addLayout(layout_2);
}Widget::~Widget()
{delete ui;
}

运行结果:

将其相互结合之后就可以做出复杂界面了

1.9.3 网格布局

Qt中提供了QGrdLayout用来实现网格布局的效果,可以达到M*N的这种效果。

核心属性

整体和QVBoxLayout以及QHBoxLayout相似,但是设置spacing的时候是按照垂直水平两个方向来设置的

属性说明
layoutLeftMargin左侧边距
layoutRightMargin右侧边距
layoutTopMargin上方边距
layoutBottomMargin下方边距
layoutHorizontalSpacing相邻元素之间水平方向的间距
layoutVerticalSpacing相邻元素之间垂直方向的间距
layoutRowStretch行方向的拉伸系数
layoutColumnStrectch列方向的拉伸系数

代码示例:使用QGridLayout管理元素

1)代码中创建QGridLayout和4个按钮(使用addWidget添加控件到布局管理器的时候,指定两个坐标,分别为第几行和第几列)

#include "widget.h"
#include "ui_widget.h"
#include <QGridLayout>
#include <QPushButton>Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);QGridLayout* layout = new QGridLayout();QPushButton* button_1 = new QPushButton("按钮1");QPushButton* button_2 = new QPushButton("按钮2");QPushButton* button_3 = new QPushButton("按钮3");QPushButton* button_4 = new QPushButton("按钮4");layout->addWidget(button_1, 0, 0);layout->addWidget(button_2, 0, 1);layout->addWidget(button_3, 1, 0);layout->addWidget(button_4, 1, 1);this->setLayout(layout);}Widget::~Widget()
{delete ui;
}

运行结果:

注:设置行和列的时候,如果设置的是一个很大的值,但是这个值和上一个值之间并没有其他的元素,那么并不会在中间腾出额外的控件

                                                                              如图所示

代码示例:设置QGridLayout中的大小比例

1)创建6个按钮,按照2行3列排放,使用setColumnStretch设置每一列的拉伸值

#include "widget.h"
#include "ui_widget.h"
#include <QGridLayout>
#include <QPushButton>Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);QGridLayout* layout = new QGridLayout();QPushButton* button_1 = new QPushButton("按钮1");QPushButton* button_2 = new QPushButton("按钮2");QPushButton* button_3 = new QPushButton("按钮3");QPushButton* button_4 = new QPushButton("按钮4");QPushButton* button_5 = new QPushButton("按钮5");QPushButton* button_6 = new QPushButton("按钮6");layout->addWidget(button_1, 0, 0);layout->addWidget(button_2, 0, 1);layout->addWidget(button_3, 0, 2);layout->addWidget(button_4, 1, 0);layout->addWidget(button_5, 1, 1);layout->addWidget(button_6, 1, 2);//设置列拉伸系数//第一列拉伸系数为1layout->setColumnStretch(0, 1);//第二列拉伸系数为0(即为不拉伸)layout->setColumnStretch(1, 0);//第三列拉伸系数为3layout->setColumnStretch(2, 3);this->setLayout(layout);}Widget::~Widget()
{delete ui;
}

运行结果:

上述效果并非很显眼,我们还可以通过设置行,然后通过QSizePolicy::Expanding尽可能填满整个布局管理器

代码⽰例: 设置垂直⽅向的拉伸系数
1) 编写代码, 创建 6 个按钮, 按照 3 ⾏ 2 列⽅式排列.
使⽤ setSizePolicy 设置按钮的尺⼨策略. 可选的值如下:
QSizePolicy::Ignored : 忽略控件的尺⼨,不对布局产⽣影响。
QSizePolicy::Minimum : 控件的最⼩尺⼨为固定值,布局时不会超过该值。
QSizePolicy::Maximum : 控件的最⼤尺⼨为固定值,布局时不会⼩于该值。
QSizePolicy::Preferred : 控件的理想尺⼨为固定值,布局时会尽量接近该值。
QSizePolicy::Expanding : 控件的尺⼨可以根据空间调整,尽可能占据更多空间。
QSizePolicy::Shrinking : 控件的尺⼨可以根据空间调整,尽可能缩⼩以适应空间。
#include "widget.h"
#include "ui_widget.h"
#include <QGridLayout>
#include <QPushButton>
#include <QSizePolicy>Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);QGridLayout* layout = new QGridLayout();QPushButton* button_1 = new QPushButton("按钮1");QPushButton* button_2 = new QPushButton("按钮2");QPushButton* button_3 = new QPushButton("按钮3");QPushButton* button_4 = new QPushButton("按钮4");QPushButton* button_5 = new QPushButton("按钮5");QPushButton* button_6 = new QPushButton("按钮6");layout->addWidget(button_1, 0, 0);layout->addWidget(button_2, 0, 1);layout->addWidget(button_3, 1, 0);layout->addWidget(button_4, 1, 1);layout->addWidget(button_5, 2, 0);layout->addWidget(button_6, 2, 1);//设置按钮的sizePolicy,此时按钮的水平方向和垂直方向都会尽量展开button_1->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);button_2->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);button_3->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);button_4->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);button_5->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);button_6->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);//设置行拉伸系数//第一行拉伸系数为1layout->setRowStretch(0, 1);//第二行拉伸系数为0(即为不拉伸)layout->setRowStretch(1, 0);//第三行拉伸系数为3layout->setRowStretch(2, 3);this->setLayout(layout);}Widget::~Widget()
{delete ui;
}

运行结果:

1.9.4 表格布局

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

代码⽰例: 使⽤ QFormLayout 创建表单.
1) 编写代码, 创建 QFormLayout , 以及三个 label 和三个 lineEdit
使⽤ addRow ⽅法来添加⼀⾏. 每⾏包含两个控件. 第⼀个控件固定是 QLabel / ⽂本, 第⼆个控件
则可以是任意控件.
如果把第⼀个参数填写为 NULL, 则什么都不显⽰.
#include "widget.h"
#include "ui_widget.h"
#include <QLabel>
#include <QLineEdit>
#include <QFormLayout>
#include <QPushButton>Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);QLabel* lable_1 = new QLabel("姓名");QLabel* lable_2 = new QLabel("班级");QLabel* lable_3 = new QLabel("年龄");QLineEdit* lineEdit_1 = new QLineEdit();QLineEdit* lineEdit_2 = new QLineEdit();QLineEdit* lineEdit_3 = new QLineEdit();QPushButton* button = new QPushButton("确认");QFormLayout* layout = new QFormLayout();layout->addRow(lable_1, lineEdit_1);layout->addRow(lable_2, lineEdit_2);layout->addRow(lable_3, lineEdit_3);layout->addRow(nullptr, button);this->setLayout(layout);}Widget::~Widget()
{delete ui;
}

运行结果:

1.9.5 Spacer

使用布局管理器的时候,可能需要在控件之间,添加一段空白,就可以使用QSpacerItem来表示

属性说明
width宽度
height高度
hData向的 sizePolicy
• QSizePolicy::Ignored : 忽略控件的尺
,不对布局产影响。
• QSizePolicy::Minimum : 控件的最
为固定值,布局时不会超过该值。
• QSizePolicy::Maximum : 控件的最
为固定值,布局时不会于该值。
• QSizePolicy::Preferred : 控件的理想尺
为固定值,布局时会尽量接近该
值。
• QSizePolicy::Expanding : 控件的尺
可以根据空间调整,尽可能占据更多空
间。
• QSizePolicy::Shrinking : 控件的尺
可以根据空间调整,尽可能缩以适应
空间。
vData垂直方向,同上

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/394216.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

OpenGL实现3D游戏编程【连载3】——3D空间模型光照初步

1、本节实现的内容 上一节课&#xff0c;我们建立了简单的坐标系&#xff0c;同时也显示了一个正方体&#xff0c;但正方体的颜色为纯红色&#xff0c;好像一个平面物体一样&#xff0c;我们这节课就可以加一些光照&#xff0c;并创建更多的模型&#xff0c;使这些物体变得更加…

显示学习5(基于树莓派Pico) -- 彩色LCD的驱动

一 环境搭建 使用的ST7715S驱动的1.8寸彩色屏&#xff0c;主控是我们熟悉的树莓派Pico。软件环境是micropython。连接是屏幕直接从Pico取3.3V的供电&#xff0c;然后总线用的SPI。 ST7735 PinPico PinVCC3.3VGNDGNDSCL (SCK)GP10SDA (MOSI)GP11RES (RST)GP17DC&#xff08;A0…

【HarmonyOS NEXT星河版开发学习】小型测试案例01-今日头条置顶练习

个人主页→VON 收录专栏→鸿蒙开发小型案例总结​​​​​ 基础语法部分会发布于github 和 gitee上面 ​ 前言 本系列可能是博客首发&#xff0c;鸿蒙开发星河版是一个全新的版本&#xff0c;由于参考视频较少鸿蒙开发不被重视导致csdn上面并没有全套的学习路线&#xff0c;…

第20周:Pytorch文本分类入门

目录 前言 一、前期准备 1.1 环境安装导入包 1.2 加载数据 1.3 构建词典 1.4 生成数据批次和迭代器 二、准备模型 2.1 定义模型 2.2 定义示例 2.3 定义训练函数与评估函数 三、训练模型 3.1 拆分数据集并运行模型 3.2 使用测试数据集评估模型 总结 前言 &#x1…

【JUC】03-CompletableFuture使用

1. CompletableFuture CompletableFuture可以进行回调通知、创建异步任务、多个任务前后依赖可以组合处理、对计算速度选最快。  CompletableFuture提供了一种类似于观察者模式的通知方式&#xff0c;可以在任务完成后通知监听方。 CompletableFuture实例化用CompletableFutur…

【弱网】模拟弱网环境

fiddler工具 调整上传/下载速率 打开fiddler脚本工具&#xff0c;在上方状态栏选择 Rules -> Customize Rules…&#xff0c;打开ScriptEditor编辑器 修改上传/下载速率&#xff0c;实现模拟指定弱网环境 计算公示&#xff1a;[1/(上或下行速率/8)] x 1000 网络上行下载2G2…

【Hive】学习笔记

Hive学习笔记 【一】Hive入门【1】什么是Hive【2】Hive的优缺点&#xff08;1&#xff09;优点&#xff08;2&#xff09;缺点 【3】Hive架构原理&#xff08;1&#xff09;用户接口&#xff1a;Client&#xff08;2&#xff09;元数据&#xff1a;Metastore&#xff08;3&…

相机标定——小孔成像、相机模型与坐标系

小孔成像 用一个带有小孔的板遮挡在墙体与物之间&#xff0c;墙体上就会形成物的倒影&#xff0c;我们把这样的现象叫小孔成像。 用一个带有小孔的板遮挡在墙体与物之间&#xff0c;墙体上就会形成物的倒影&#xff0c;我们把这样的现象叫小孔成像。前后移动中间的板&#xff…

Docker 常规安装简介

Docker常规安装简介 欢迎关注我的B站&#xff1a;https://space.bilibili.com/379384819 1. 安装mysql 1.1 docker hub上面查找mysql镜像 网址&#xff1a; https://hub.docker.com/_/mysql 1.2 从docker hub上&#xff08;阿里云加速器&#xff09;拉取mysql镜像到本地标…

Redis远程字典服务器(0)——分布式系统

目录 一&#xff0c;关于Redis 二&#xff0c;分布式系统 2.1 关于分布式 2.2 理解数据库分离 2.3 理解负载均衡 2.4 数据库读写分离 2.5 引入缓存 2.6 数据库分库分表 2.7 微服务 四&#xff0c;补充 五&#xff0c;总结 一&#xff0c;关于Redis MySQL是在磁盘中存…

分类预测 | Matlab实现PSO-XGBoost粒子群算法优化XGBoost的多特征分类预测

分类预测 | Matlab实现PSO-XGBoost粒子群算法优化XGBoost的多特征分类预测 目录 分类预测 | Matlab实现PSO-XGBoost粒子群算法优化XGBoost的多特征分类预测效果一览基本介绍程序设计参考资料 效果一览 基本介绍 Matlab实现PSO-XGBoost粒子群算法优化XGBoost的多特征分类预测&a…

英特尔:“芯”痛巨头

从全球芯片巨头到“芯”痛巨头&#xff0c; 英特尔 到底经历了什么&#xff1f; 今天券商中国说英特尔在QDII基金上这么多年&#xff0c;一直就没能进入主流持仓中&#xff0c;最后一只试探性持仓英特尔的QDII也已在今年3月末砍仓了&#xff0c; 这一砍还让这只QDII完美躲过…

医得快医疗服务交易服务平台/基于微信小程序的药品销售系统

获取源码联系方式请查看文章结尾&#x1f345; 摘 要 随着信息技术和网络技术的飞速发展&#xff0c;人类已进入全新信息化时代&#xff0c;传统管理技术已无法高效&#xff0c;便捷地管理信息。为了迎合时代需求&#xff0c;优化管理效率&#xff0c;各种各样的管理系统应运而…

【中间件】Redis从入门到精通-黑马点评综合实战

文章目录 一&#xff1a;Redis基础1.Redis是什么2.初识Redis3.Redis的数据结构A.通用命令B.String类型C.Key的层级格式D.Hash类型E.List类型F.Set类型G.SortedSet类型 二&#xff1a;Redis的Java客户端1.JedisA.引入依赖B.建立连接C.测试JedisD.释放资源 2.Jedis连接池3.Spring…

如何通过GD32 MCU内部ADC参考电压通道提高采样精度?

ADC采样精度受很多因素影响&#xff0c;比如电源波动、参考电压波动、输入信号波动等&#xff0c;GD32 MCU内部提供了一个参考电压通道&#xff0c;理论上可以优化由于电源和参考电压较大波动引入的采样误差。 如下图所示&#xff0c;GD32F303 ADC内部17通道为VREFINT参考电压…

密码学基础-为什么使用真随机数(True Random Number Generators)

密码学基础-为什么使用真随机数&#xff08;True Random Number Generators&#xff09; 概述 随机的意义很重要&#xff0c;就像你的银行密码如果是亲朋好友的生日&#xff0c;结婚纪念日&#xff08;可预测的&#xff09;&#xff0c;那么就容易被人测试出来&#xff1b;而…

从零开始学习性能测试

学习目标 理解性能测试定义、目的理解常见性能测试策略理解性能指标理解性能测试方法学习性能测试工具 什么是性能测试 测试中的非功能测试其实范围比较广&#xff0c;性能、稳定性、安全性等都可以放进这个范畴。非功能测试&#xff0c;一般比功能测试门槛高些&#xff0c;多数…

深入理解计算机系统 CSAPP lab:bomb

实验资源下载地址&#xff1a;csapp.cs.cmu.edu/3e/labs.html 请先查看writeup 解压后 当我们运行bomb时,发现该程序要求我们输入行,如果输入错误,程序就会返回BOOM!!!提示我们失败了. 所以我们的目标是输入正确的行.以解开bomb程序. 实验前先详细阅读bomb.c //bomb.c /*****…

计算机系统基础(一)

开始复习了软考软件设计师还有考研复习了&#xff0c;这个重合部分比较大&#xff0c;开始学习打卡&#xff0c;基础最重要&#xff0c;直接看书又多又杂&#xff0c;重点理不出来&#xff0c;学习记录。 计算机系统基础 冯诺依曼体系结构奠定了计算机的基础结构。五个部分组成…

认识Modbus RTU与Modbus TCP

&#xff08;选自成都纵横智控-Modbus RTU与Modbus TCP协议区别详解 &#xff09; Modbus RTU 和 Modbus TCP 是两种常用的工业通信协议&#xff0c;用于连接电子设备&#xff0c;但它们在多方面有所不同。以下是它们的详细比较&#xff1a; Modbus RTU 协议类型&#xff1a; …