Qt5 C++入门教程-第11章 窗口小部件2(Widgets)
bigegpt 2025-05-30 12:52 5 浏览
大道至简,在 Qt5 C++入门教程的这一部分,我们来继续谈谈一些基本的 Qt5 窗口小部件。我们有关于 QCheckBox, QListWidget, QProgressBar, QPixmap, QSplitter, and QTableWidget.这些窗口小部件的示例。
QCheckBox 组件
QCheckBox 是一种具有两种状态(选中和未选中)的小部件。它由一个带标签的复选框组成。当复选框被选中时,会在框内显示一个勾号。
在这个示例中,我们在窗口上显示了一个复选框。当该复选框被选中时,窗口将显示标题;反之则隐藏标题。
checkbox.h
#pragma once
#include <QWidget>
class CheckBox : public QWidget {
Q_OBJECT
public:
CheckBox(QWidget *parent = 0);
private slots:
void showTitle(int);
};
这是示例代码的头文件,定义了复选框窗口类的结构。
checkbox.cpp
#include <QCheckBox>
#include <QHBoxLayout>
#include "checkbox.h"
CheckBox::CheckBox(QWidget *parent)
: QWidget(parent) {
QHBoxLayout *hbox = new QHBoxLayout(this);
QCheckBox *cb = new QCheckBox("showTitle", this);
cb->setCheckState(Qt::Checked);
hbox->addWidget(cb, 0, Qt::AlignLeft | Qt::AlignTop);
connect(cb, &QCheckBox::stateChanged, this, &CheckBox::showTitle);
}
void CheckBox::showTitle(int state) {
if (state == Qt::Checked) {
setWindowTitle("QCheckBox ");
} else {
setWindowTitle("");
}
}
我们在窗口上创建了一个复选框,并将其状态变化事件连接到 showTitle 槽函数。
cb->setCheckState(Qt::Checked); 这行代码确保示例启动时复选框处于选中状态。
showTitle 函数根据复选框状态决定是否显示窗口标题:
void CheckBox::showTitle(int state) {
if (state == Qt::Checked) {
setWindowTitle("QCheckBox");
} else {
setWindowTitle("");
}
}
main.cpp
#include <QApplication>
#include "checkbox.h"
int main(int argc, char *argv[]) {
QApplication app(argc, argv);
CheckBox window;
window.resize(250, 150);
window.setWindowTitle("QCheckBox");
window.show();
return app.exec();
}
这个示例展示了如何使用 Qt 的 QCheckBox 组件实现窗口标题的动态显示与隐藏:
- 创建水平布局管理器放置复选框
- 设置复选框的初始状态为选中
- 通过信号槽机制监听复选框状态变化
- 根据状态动态更新窗口标题
运行程序后,取消 / 选中复选框可以观察到窗口标题的相应变化。
QListWidget
QListWidget 是用于显示项目列表的组件。在本示例中,我们将演示如何向列表组件中添加、重命名和删除项目。
listwidget.h
#pragma once
#include <QWidget>
#include <QPushButton>
#include <QListWidget>
class ListWidget : public QWidget {
Q_OBJECT
public:
ListWidget(QWidget *parent = 0);
private slots:
void addItem();
void renameItem();
void removeItem();
void clearItems();
private:
QListWidget *lw;
QPushButton *add;
QPushButton *rename;
QPushButton *remove;
QPushButton *removeAll;
};
这是示例的头文件,定义了包含列表组件和操作按钮的窗口类。
listwidget.cpp
#include "listwidget.h"
#include <QVBoxLayout>
#include <QInputDialog>
ListWidget::ListWidget(QWidget *parent)
: QWidget(parent) {
QVBoxLayout *vbox = new QVBoxLayout();
vbox->setSpacing(10);
QHBoxLayout *hbox = new QHBoxLayout(this);
lw = new QListWidget(this);
lw->addItem("The Omen");
lw->addItem("The Exorcist");
lw->addItem("Notes on a scandal");
lw->addItem("Fargo");
lw->addItem("Capote");
add = new QPushButton("Add", this);
rename = new QPushButton("Rename", this);
remove = new QPushButton("Remove", this);
removeAll = new QPushButton("Remove All", this);
vbox->setSpacing(3);
vbox->addStretch(1);
vbox->addWidget(add);
vbox->addWidget(rename);
vbox->addWidget(remove);
vbox->addWidget(removeAll);
vbox->addStretch(1);
hbox->addWidget(lw);
hbox->addSpacing(15);
hbox->addLayout(vbox);
connect(add, &QPushButton::clicked, this, &ListWidget::addItem);
connect(rename, &QPushButton::clicked, this, &ListWidget::renameItem);
connect(remove, &QPushButton::clicked, this, &ListWidget::removeItem);
connect(removeAll, &QPushButton::clicked, this, &ListWidget::clearItems);
setLayout(hbox);
}
void ListWidget::addItem() {
QString c_text = QInputDialog::getText(this, "Item", "Enter new item");
QString s_text = c_text.simplified();
if (!s_text.isEmpty()) {
lw->addItem(s_text);
int r = lw->count() - 1;
lw->setCurrentRow(r);
}
}
void ListWidget::renameItem() {
QListWidgetItem *curitem = lw->currentItem();
int r = lw->row(curitem);
QString c_text = curitem->text();
QString r_text = QInputDialog::getText(this, "Item",
"Enter new item", QLineEdit::Normal, c_text);
QString s_text = r_text.simplified();
if (!s_text.isEmpty()) {
QListWidgetItem *item = lw->takeItem(r);
delete item;
lw->insertItem(r, s_text);
lw->setCurrentRow(r);
}
}
void ListWidget::removeItem() {
int r = lw->currentRow();
if (r != -1) {
QListWidgetItem *item = lw->takeItem(r);
delete item;
}
}
void ListWidget::clearItems(){
if (lw->count() != 0) {
lw->clear();
}
}
我们展示了一个列表组件和四个按钮,用于实现向列表组件中添加、重命名和删除项目的功能。
功能解析
- 初始化列表 创建 QListWidget 组件并添加 5 个初始项目
- 添加项目(addItem 方法)弹出输入对话框(QInputDialog)获取用户输入文本。使用 simplified() 方法去除文本首尾空格。若输入非空,将文本添加到列表末尾,并通过 setCurrentRow() 选中新添加的项目。
- 重命名项目(renameItem 方法)通过 currentItem() 获取当前选中项,获取其文本和所在行号。在输入对话框中预填充当前项文本,用户修改后,使用 simplified() 处理输入文本。通过 takeItem(r) 移除旧项(需手动释放内存),再通过 insertItem(r, s_text) 插入新项,并保持选中状态。
- 删除项目(removeItem 方法)通过 currentRow() 获取当前选中行号(若未选中则返回 -1)。使用 takeItem(r) 移除指定行的项目,并手动释放内存。
- 清空列表(clearItems 方法)调用 clear() 方法移除列表中所有项目。
main.cpp
#include <QApplication>
#include "listwidget.h"
int main(int argc, char *argv[]) {
QApplication app(argc, argv);
ListWidget window;
window.setWindowTitle("QListWidget");
window.show();
return app.exec();
}
说明:主程序创建窗口并启动事件循环,显示包含列表组件和操作按钮的界面。
QProgressBar
QProgressBar 用于向用户显示操作的进度。
progressbar.h
#pragma once
#include <QWidget>
#include <QProgressBar>
#include <QPushButton>
class ProgressBarEx : public QWidget {
Q_OBJECT
public:
ProgressBarEx(QWidget *parent = 0);
private:
int progress;
QTimer *timer;
QProgressBar *pbar;
QPushButton *startBtn;
QPushButton *stopBtn;
static const int DELAY = 200;
static const int MAX_VALUE = 100;
void updateBar();
void startMyTimer();
void stopMyTimer();
};
这是示例的头文件,定义了包含进度条和操作按钮的窗口类。
progressbar.cpp
#include <QProgressBar>
#include <QTimer>
#include <QGridLayout>
#include "progressbar.h"
ProgressBarEx::ProgressBarEx(QWidget *parent)
: QWidget(parent) {
progress = 0;
timer = new QTimer(this);
connect(timer, &QTimer::timeout, this, &ProgressBarEx::updateBar);
QGridLayout *grid = new QGridLayout(this);
grid->setColumnStretch(2, 1);
pbar = new QProgressBar();
grid->addWidget(pbar, 0, 0, 1, 3);
startBtn = new QPushButton("Start", this);
connect(startBtn, &QPushButton::clicked, this, &ProgressBarEx::startMyTimer);
grid->addWidget(startBtn, 1, 0, 1, 1);
stopBtn = new QPushButton("Stop", this);
connect(stopBtn, &QPushButton::clicked, this, &ProgressBarEx::stopMyTimer);
grid->addWidget(stopBtn, 1, 1);
}
void ProgressBarEx::startMyTimer() {
if (progress >= MAX_VALUE) {
progress = 0;
pbar->setValue(0);
}
if (!timer->isActive()) {
startBtn->setEnabled(false);
stopBtn->setEnabled(true);
timer->start(DELAY);
}
}
void ProgressBarEx::stopMyTimer() {
if (timer->isActive()) {
startBtn->setEnabled(true);
stopBtn->setEnabled(false);
timer->stop();
}
}
void ProgressBarEx::updateBar() {
progress++;
if (progress <= MAX_VALUE) {
pbar->setValue(progress);
} else {
timer->stop();
startBtn->setEnabled(true);
stopBtn->setEnabled(false);
}
}
- 在这个示例中,我们使用了一个 QProgressBar(进度条)和两个按钮。一个按钮用于启动定时器,进而更新进度条;另一个按钮用于停止定时器。
- 定时器与进度条关联
timer = new QTimer(this);
connect(timer, &QTimer::timeout, this, &ProgressBarEx::updateBar);
使用 QTimer 来控制 QProgressBar 组件。
- 创建进度条
pbar = new QProgressBar();
创建 QProgressBar 的实例。其默认最小值和最大值为 0 和 100。
- 按钮状态控制
if (!timer->isActive()) {
startBtn->setEnabled(false);
stopBtn->setEnabled(true);
timer->start(DELAY);
}
根据进度条的状态启用或禁用按钮,这通过 setEnabled 方法实现。
- 启动定时器时:禁用 “开始” 按钮,启用 “停止” 按钮。
- 停止定时器时:反之。
- 进度更新逻辑
void ProgressBarEx::updateBar() {
progress++;
if (progress <= MAX_VALUE) {
pbar->setValue(progress);
} else {
timer->stop();
startBtn->setEnabled(true);
stopBtn->setEnabled(false);
}
}
- 进度值存储在 progress 变量中,通过 setValue 方法更新进度条的当前值。
- 当进度达到最大值时,停止定时器并恢复按钮的初始状态。
main.cpp
#include <QApplication>
#include "progressbar.h"
int main(int argc, char *argv[]) {
QApplication app(argc, argv);
ProgressBarEx window;
window.resize(250, 150);
window.setWindowTitle("QProgressBar");
window.show();
return app.exec();
}
主程序创建窗口并设置尺寸和标题,显示包含进度条和控制按钮的界面。
QPixmap
QPixmap 是用于处理图像的组件之一,它针对在屏幕上显示图像进行了优化。在我们的代码示例中,将使用 QPixmap 在窗口上显示一张图片。
pixmap.h
#pragma once
#include <QWidget>
class Pixmap : public QWidget {
public:
Pixmap(QWidget *parent = 0);
};
pixmap.cpp
#include <QPixmap>
#include <QLabel>
#include <QHBoxLayout>
#include "pixmap.h"
Pixmap::Pixmap(QWidget *parent)
: QWidget(parent) {
QHBoxLayout *hbox = new QHBoxLayout(this);
QPixmap pixmap("bojnice.jpg");
QLabel *label = new QLabel(this);
label->setPixmap(pixmap);
hbox->addWidget(label, 0, Qt::AlignTop);
}
我们展示了一张图片。
main.cpp
#include <QApplication>
#include "pixmap.h"
int main(int argc, char *argv[]) {
QApplication app(argc, argv);
Pixmap window;
window.setWindowTitle("QPixmap");
window.show();
return app.exec();
}
主程序文件,创建窗口并显示图像。
QSplitter
QSplitter 允许用户通过拖动子组件之间的边界来调整子组件的大小。在我们的示例中,将展示使用两个拆分器组织的三个 QFrame 组件。
splitter.h
#pragma once
#include <QWidget>
class Splitter : public QWidget {
public:
Splitter(QWidget *parent = 0);
};
splitter.cpp
#include <QFrame>
#include <QSplitter>
#include <QHBoxLayout>
#include "splitter.h"
Splitter::Splitter(QWidget *parent)
: QWidget(parent) {
QHBoxLayout *hbox = new QHBoxLayout(this);
QFrame *topleft = new QFrame(this);
topleft->setFrameShape(QFrame::StyledPanel);
QFrame *topright = new QFrame(this);
topright->setFrameShape(QFrame::StyledPanel);
// 创建水平拆分器并添加两个子框架
QSplitter *splitter1 = new QSplitter(Qt::Horizontal, this);
splitter1->addWidget(topleft);
splitter1->addWidget(topright);
QFrame *bottom = new QFrame(this);
bottom->setFrameShape(QFrame::StyledPanel);
// 创建垂直拆分器并添加水平拆分器和底部框架
QSplitter *splitter2 = new QSplitter(Qt::Vertical, this);
splitter2->addWidget(splitter1);
splitter2->addWidget(bottom);
// 设置子组件的初始尺寸
QList<int> sizes({50, 100});
splitter2->setSizes(sizes);
hbox->addWidget(splitter2);
}
示例中包含三个框架组件和两个拆分器组件。
main.cpp
#include <QDesktopWidget>
#include <QApplication>
#include "splitter.h"
int main(int argc, char *argv[]) {
QApplication app(argc, argv);
Splitter window;
window.resize(350, 300);
window.setWindowTitle("QSplitter");
window.show();
return app.exec();
}
主程序文件,创建窗口并设置初始尺寸,显示可拖动调整的拆分布局。
QTableWidget
QTableWidget 是电子表格应用中使用的一种独特组件(也称为网格组件),它是较为复杂的组件之一。在此示例中,我们仅在窗口上显示该组件。
table.h
#pragma once
#include <QWidget>
class Table : public QWidget {
public:
Table(QWidget *parent = 0);
};
table.cpp
#include <QHBoxLayout>
#include <QTableWidget>
#include "table.h"
Table::Table(QWidget *parent)
: QWidget(parent) {
QHBoxLayout *hbox = new QHBoxLayout(this);
QTableWidget *table = new QTableWidget(25, 25, this);
hbox->addWidget(table);
}
本示例在窗口上显示一个 QTableWidget 组件。
- QTableWidget *table = new QTableWidget(25, 25, this);
- 创建一个包含 25 行 和 25 列 的表格组件,参数依次为行数、列数和父对象。
main.cpp
#include <QApplication>
#include "table.h"
int main(int argc, char *argv[]) {
QApplication app(argc, argv);
Table window;
window.resize(400, 250);
window.setWindowTitle("QTableWidget");
window.show();
return app.exec();
}
主程序文件,创建窗口并设置尺寸为 400x250 像素,显示包含表格组件的界面。
相关推荐
- 【Docker 新手入门指南】第十章:Dockerfile
-
Dockerfile是Docker镜像构建的核心配置文件,通过预定义的指令集实现镜像的自动化构建。以下从核心概念、指令详解、最佳实践三方面展开说明,帮助你系统掌握Dockerfile的使用逻...
- Windows下最简单的ESP8266_ROTS_ESP-IDF环境搭建与腾讯云SDK编译
-
前言其实也没啥可说的,只是我感觉ESP-IDF对新手来说很不友好,很容易踩坑,尤其是对业余DIY爱好者搭建环境非常困难,即使有官方文档,或者网上的其他文档,但是还是很容易踩坑,多研究,记住两点就行了,...
- python虚拟环境迁移(python虚拟环境conda)
-
主机A的虚拟环境向主机B迁移。前提条件:主机A和主机B已经安装了virtualenv1.主机A操作如下虚拟环境目录:venv进入虚拟环境:sourcevenv/bin/active(1)记录虚拟环...
- Python爬虫进阶教程(二):线程、协程
-
简介线程线程也叫轻量级进程,它是一个基本的CPU执行单元,也是程序执行过程中的最小单元,由线程ID、程序计数器、寄存器集合和堆栈共同组成。线程的引入减小了程序并发执行时的开销,提高了操作系统的并发性能...
- 基于网络安全的Docker逃逸(docker)
-
如何判断当前机器是否为Docker容器环境Metasploit中的checkcontainer模块、(判断是否为虚拟机,checkvm模块)搭配学习教程1.检查根目录下是否存在.dockerenv文...
- Python编程语言被纳入浙江高考,小学生都开始学了
-
今年9月份开始的新学期,浙江省三到九年级信息技术课将同步替换新教材。其中,新初二将新增Python编程课程内容。新高一信息技术编程语言由VB替换为Python,大数据、人工智能、程序设计与算法按照教材...
- CentOS 7下安装Python 3.10的完整过程
-
1.安装相应的编译工具yum-ygroupinstall"Developmenttools"yum-yinstallzlib-develbzip2-develope...
- 如何在Ubuntu 20.04上部署Odoo 14
-
Odoo是世界上最受欢迎的多合一商务软件。它提供了一系列业务应用程序,包括CRM,网站,电子商务,计费,会计,制造,仓库,项目管理,库存等等,所有这些都无缝集成在一起。Odoo可以通过几种不同的方式进...
- Ubuntu 系统安装 PyTorch 全流程指南
-
当前环境:Ubuntu22.04,显卡为GeForceRTX3080Ti1、下载显卡驱动驱动网站:https://www.nvidia.com/en-us/drivers/根据自己的显卡型号和...
- spark+python环境搭建(python 环境搭建)
-
最近项目需要用到spark大数据相关技术,周末有空spark环境搭起来...目标spark,python运行环境部署在linux服务器个人通过vscode开发通过远程python解释器执行代码准备...
- centos7.9安装最新python-3.11.1(centos安装python环境)
-
centos7.9安装最新python-3.11.1centos7.9默认安装的是python-2.7.5版本,安全扫描时会有很多漏洞,比如:Python命令注入漏洞(CVE-2015-2010...
- Linux系统下,五大步骤安装Python
-
一、下载Python包网上教程大多是通过官方地址进行下载Python的,但由于国内网络环境问题,会导致下载很慢,所以这里建议通过国内镜像进行下载例如:淘宝镜像http://npm.taobao.or...
- centos7上安装python3(centos7安装python3.7.2一键脚本)
-
centos7上默认安装的是python2,要使用python3则需要自行下载源码编译安装。1.安装依赖yum-ygroupinstall"Developmenttools"...
- 利用本地数据通过微调方式训练 本地DeepSeek-R1 蒸馏模型
-
网络上相应的教程基本都基于LLaMA-Factory进行,本文章主要顺着相应的教程一步步实现大模型的微调和训练。训练环境:可自行定义,mac、linux或者window之类的均可以,本文以ma...
- 【法器篇】天啦噜,库崩了没备份(天啦噜是什么意思?)
-
背景数据库没有做备份,一天突然由于断电或其他原因导致无法启动了,且设置了innodb_force_recovery=6都无法启动,里面的数据怎么才能恢复出来?本例采用解析建表语句+表空间传输的方式进行...
- 一周热门
- 最近发表
- 标签列表
-
- mybatiscollection (79)
- mqtt服务器 (88)
- keyerror (78)
- c#map (65)
- resize函数 (64)
- xftp6 (83)
- bt搜索 (75)
- c#var (76)
- mybatis大于等于 (64)
- xcode-select (66)
- mysql授权 (74)
- 下载测试 (70)
- skip-name-resolve (63)
- linuxlink (65)
- pythonwget (67)
- logstashinput (65)
- hadoop端口 (65)
- vue阻止冒泡 (67)
- oracle时间戳转换日期 (64)
- jquery跨域 (68)
- php写入文件 (73)
- kafkatools (66)
- mysql导出数据库 (66)
- jquery鼠标移入移出 (71)
- 取小数点后两位的函数 (73)