【Qt笔记】QScrollArea控件详解

 

目录

引言 

一、QScrollArea 的基本概念

二、QScrollArea 的主要属性

2.1 设置内容大小是否随滚动区域变化

2.2 设置水平与垂直滚动条

2.3 设置视口外边距

三、QScrollArea 的常用方法

3.1 设置显示小部件 

3.2 返回当前设置的小部件

3.3 设置内部小部件是否可以填充滚动区域

3.4 确保内部某个小部件可见

四、QScrollArea 的信号与槽

五、应用示例 

步骤 1: 创建Qt项目

步骤 2: 设计UI

步骤 3: 编写代码

实现效果 

代码解析

结语 


引言 

QScrollArea 是 Qt 框架中用于提供一个滚动条区域,允许用户滚动查看比当前可视区域更大的内容的控件。这个控件非常有用,尤其是在处理大型表格、文本区域、图像集合或任何需要滚动浏览的内容时。下面,我将详细介绍 QScrollArea 的各个方面,包括其用法、属性、方法、信号与槽,以及通过代码示例来展示如何在实际应用中使用它。  

一、QScrollArea 的基本概念

QScrollArea提供了一个滚动视图的框架,它本身不直接显示内容,而是将内容(通常是一个QWidget或其子类)作为其子项,并通过滚动条来访问这些内容的全部。QScrollArea支持水平和垂直滚动,并且可以根据需要自动调整滚动条的出现。

 

二、QScrollArea 的主要属性

2.1 设置内容大小是否随滚动区域变化

  • widgetResizable:一个布尔值属性,指示是否允许内部小部件(即内容)的大小随滚动区域的大小变化而调整。
// 创建一个QWidget作为滚动区域的内容  
QWidget *contentWidget = new QWidget;  
QVBoxLayout *layout = new QVBoxLayout(contentWidget);  
  
// 添加一些按钮以模拟内容  
for (int i = 0; i < 20; ++i) {  
    QPushButton *button = new QPushButton(QString("Button %1").arg(i + 1));  
    layout->addWidget(button);  
}  
  
// 创建QScrollArea并设置内容小部件  
QScrollArea scrollArea;  
scrollArea.setWidget(contentWidget);  
  
// 允许内容小部件根据滚动区域的大小变化而调整大小  
scrollArea.setWidgetResizable(true); // 设置为true以启用大小调整

2.2 设置水平与垂直滚动条

  • horizontalScrollBarPolicy 和 verticalScrollBarPolicy:这两个属性控制水平和垂直滚动条的策略,可以是 Qt::ScrollBarAlwaysOff(永不显示)、Qt::ScrollBarAlwaysOn(始终显示)、Qt::ScrollBarAsNeeded(根据需要显示)。
// 创建一个QTextEdit作为滚动区域的内容  
QTextEdit *textEdit = new QTextEdit;  
textEdit->setText("这是一段非常长的文本,用于演示滚动条策略。\n"  
                  "通过修改horizontalScrollBarPolicy和verticalScrollBarPolicy属性,"  
                  "可以控制滚动条的显示策略。");  
  
// 创建QScrollArea并设置内容小部件  
QScrollArea scrollArea;  
scrollArea.setWidget(textEdit);  
  
// 设置滚动条策略  
scrollArea.setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded);  
scrollArea.setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);

2.3 设置视口外边距

  • viewportMargins:设置视口(即内容显示区域)的外边距。
// 创建一个QTextEdit作为滚动区域的内容  
QTextEdit *textEdit = new QTextEdit;  
textEdit->setText("这是带有视口外边距的文本编辑器。\n"  
                  "通过修改viewportMargins属性,可以为滚动区域的视口设置外边距。");  
  
// 创建QScrollArea并设置内容小部件  
QScrollArea scrollArea;  
scrollArea.setWidget(textEdit);  
  
// 设置视口的外边距  
scrollArea.setViewportMargins(20, 10, 30, 40); // 左, 上, 右, 下

三、QScrollArea 的常用方法

3.1 设置显示小部件 

  • setWidget(QWidget *widget):设置要显示在滚动区域中的小部件。这个小部件将作为滚动区域的内容。
// 创建一个QWidget作为滚动区域的内容  
QWidget *contentWidget = new QWidget;  
QVBoxLayout *layout = new QVBoxLayout(contentWidget);  
  
// 向contentWidget中添加一些按钮  
for (int i = 0; i < 20; ++i) {  
    QPushButton *button = new QPushButton(QString("Button %1").arg(i + 1));  
    layout->addWidget(button);  
}  
  
// 创建QScrollArea并设置内容小部件  
QScrollArea scrollArea;  
scrollArea.setWidget(contentWidget);

3.2 返回当前设置的小部件

  • widget():返回当前设置在滚动区域中的小部件。
// 获取并打印当前设置在滚动区域中的小部件  
QWidget *currentWidget = scrollArea.widget();  
qDebug() << "The current widget is:" << currentWidget;  

3.3 设置内部小部件是否可以填充滚动区域

  • setWidgetResizable(bool resizable):设置内部小部件是否可以调整大小以填充滚动区域。
// 创建一个QTextEdit作为滚动区域的内容  
QTextEdit *textEdit = new QTextEdit;  
textEdit->setPlainText("This is a very long text that will exceed the scroll area's visible area.");  
  
// 创建QScrollArea并设置内容小部件  
QScrollArea scrollArea;  
scrollArea.setWidget(textEdit);  
  
// 允许内容小部件根据滚动区域的大小变化而调整大小  
scrollArea.setWidgetResizable(true);

3.4 确保内部某个小部件可见

  • ensureVisible(int x, int y, int xmargin = 50, int ymargin = 50):确保滚动区域中的特定区域(通过x, y坐标指定)是可见的,xmargin和ymargin指定了额外边界以确保区域完全可见。
// 创建一个QTextEdit并填充一些文本  
QTextEdit *textEdit = new QTextEdit;  
textEdit->setPlainText("This is a very long text with specific parts that we want to ensure are visible.\n"  
                           "We will use ensureVisible to do this.");  
  
// 创建QScrollArea并设置内容小部件  
QScrollArea scrollArea;  
scrollArea.setWidget(textEdit);  
scrollArea.show();  
  
// 假设我们知道我们想要确保可见的具体位置(这里只是示例)  
int targetX = 100; // 假设的X坐标  
int targetY = 500; // 假设的Y坐标  
  
// 使用ensureVisible来确保这个位置是可见的  
scrollArea.ensureVisible(targetX, targetY, 20, 20); // 额外边界为20  
  
// 注意:在实际应用中,你可能需要根据实际情况来计算targetX和targetY

四、QScrollArea 的信号与槽

QScrollArea 本身不直接提供许多信号,但它继承自 QAbstractScrollArea,后者提供了一些与滚动相关的信号,如 horizontalScrollBarValueChanged(int value) 和 verticalScrollBarValueChanged(int value)。这些信号在滚动条的值改变时发射,可以用于同步滚动或触发其他动作。

五、应用示例 

这个示例将创建一个包含多个QLabel的QScrollArea,每个QLabel都展示一张图像。用户可以通过鼠标滚轮来缩放整个画廊,同时画廊的大小会根据内容动态调整。

步骤 1: 创建Qt项目

首先,你需要有一个Qt Widgets Application项目。

步骤 2: 设计UI

我们将使用Qt Designer来设计基本的UI,但主要逻辑将通过代码实现。

步骤 3: 编写代码

#include <QApplication>  
#include <QScrollArea>  
#include <QWidget>  
#include <QVBoxLayout>  
#include <QLabel>  
#include <QPixmap>  
#include <QWheelEvent>  
#include <QTransform>  
  
class ImageWidget : public QWidget {  
    Q_OBJECT  
public:  
    explicit ImageWidget(const QPixmap &pixmap, QWidget *parent = nullptr)  
        : QWidget(parent), originalPixmap(pixmap), scaleFactor(1.0) {  
        updatePixmap();  
    }  
  
    void wheelEvent(QWheelEvent *event) override {  
        // 实现缩放功能  
        const double degrees = event->angleDelta().y() / 8.0;  
        const double step = (degrees > 0) ? 1.15 : 0.85;  
        scaleFactor *= step;  
        scaleFactor = qBound(0.1, scaleFactor, 4.0); // 限制缩放比例  
        updatePixmap();  
        update();  
    }  
  
    void updatePixmap() {  
        QPixmap scaledPixmap = originalPixmap.scaled(originalPixmap.size() * scaleFactor,  
                                                     Qt::KeepAspectRatio, Qt::SmoothTransformation);  
        resizedPixmap = scaledPixmap;  
    }  
  
protected:  
    void paintEvent(QPaintEvent *event) override {  
        QPainter painter(this);  
        painter.setRenderHint(QPainter::Antialiasing);  
        painter.drawPixmap(rect(), resizedPixmap);  
    }  
  
private:  
    QPixmap originalPixmap;  
    QPixmap resizedPixmap;  
    double scaleFactor;  
};  
  
int main(int argc, char *argv[]) {  
    QApplication app(argc, argv);  
  
    // 创建滚动区域  
    QScrollArea scrollArea;  
    QWidget *contentWidget = new QWidget;  
    QVBoxLayout *layout = new QVBoxLayout(contentWidget);  
  
    // 添加图像  
    QStringList imageFiles = {"path/to/image1.jpg", "path/to/image2.jpg", "path/to/image3.jpg"};  
    for (const QString &imagePath : imageFiles) {  
        QPixmap pixmap(imagePath);  
        if (!pixmap.isNull()) {  
            ImageWidget *imageWidget = new ImageWidget(pixmap);  
            imageWidget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);  
            layout->addWidget(imageWidget);  
        }  
    }  
  
    scrollArea.setWidget(contentWidget);  
    scrollArea.setWidgetResizable(true);  
  
    scrollArea.show();  
  
    return app.exec();  
}  

实现效果 

 

代码解析

  1. ImageWidget 类:这是一个自定义的QWidget子类,用于展示可缩放的图像。它重写了wheelEvent来处理鼠标滚轮事件以实现缩放功能,并重写了paintEvent来绘制缩放后的图像。

  2. 缩放实现:在wheelEvent中,我们根据滚轮的方向计算缩放比例,并更新内部的scaleFactor。然后,我们调用updatePixmap来重新计算缩放后的图像,并触发update来重绘小部件。

  3. QScrollArea 使用:我们创建了一个QScrollArea,并设置了一个自定义的QWidget作为其内容。这个QWidget使用QVBoxLayout来布局多个ImageWidget实例,每个实例都展示了一个图像。

  4. 动态布局:由于ImageWidget的setSizePolicy被设置为Expanding,它们将尝试填充所有可用空间,同时QScrollArea的setWidgetResizable(true)允许内容小部件根据需要进行大小调整。

  5. 注意:请确保替换imageFiles中的路径为你的实际图像路径。

结语 

QScrollArea是 Qt 中一个非常实用的控件,它允许开发者在有限的屏幕空间内展示大量的内容。通过调整其属性和使用相关的方法,开发者可以灵活地控制滚动条的行为和内容的大小。以上内容详细介绍了 QScrollArea的基本概念、主要属性、常用方法、信号与槽,并通过一个具体的代码示例展示了如何在 Qt 应用程序中使用它。希望这些内容能帮助你更好地理解和使用 QScrollArea。 

 

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【bug】通过lora方式微调sdxl inpainting踩坑

报错内容 ValueError: Attempting to unscale FP16 gradients. 报错位置 if accelerator.sync_gradients:params_to_clip (itertools.chain(unet_lora_parameters, text_lora_parameters_one, text_lora_parameters_two)if args.train_text_encoderelse unet_lora_parameters…

ICP算法介绍,机器人姿态估计,三维点云配准

介绍 ICP算法&#xff0c;即Iterative Closest Point&#xff08;迭代最近点&#xff09;算法&#xff0c;是一种广泛应用于计算机视觉和图像处理领域的几何配准算法。它的主要目的是通过最小化两组点集之间的距离来找出一组变换&#xff0c;使得两组点集尽可能地对齐。ICP算法…

37拼购:电商新风尚,共享双赢的购物革命

随着2024年电商市场的日益繁荣&#xff0c;商品海洋中的同质化问题愈发严峻&#xff0c;消费者在茫茫商海中寻觅独特价值的难度陡增。在此背景下&#xff0c;一种名为“37悦享拼”的创新电商模式横空出世&#xff0c;它巧妙融合了私域社交与电商精髓&#xff0c;旨在打破传统壁…

9.18作业

提示并输入一个字符串&#xff0c;统计该字符串中字母、数字、空格、其他字符的个数并输出 代码展示 #include <iostream>using namespace std;int main() {string str;int countc 0; // 字母计数int countn 0; // 数字计数int count 0; // 空格计数int counto 0;…

部署自己的对话大模型,使用Ollama + Qwen2 +FastGPT 实现

部署资源 AUTODL 使用最小3080Ti 资源&#xff0c;cuda > 12.0使用云服务器&#xff0c;部署fastGPT oneAPI&#xff0c;M3E 模型 操作步骤 配置代理 export HF_ENDPOINThttps://hf-mirror.com下载qwen2模型 - 如何下载huggingface huggingface-cli download Qwen/Qwen2-…

Java | Leetcode Java题解之第402题移掉K位数字

题目&#xff1a; 题解&#xff1a; class Solution {public String removeKdigits(String num, int k) {Deque<Character> deque new LinkedList<Character>();int length num.length();for (int i 0; i < length; i) {char digit num.charAt(i);while (!…

ERP进销存管理系统的业务全流程 Axure高保真原型源文件分享

这是一套ERP进销存管理系统的业务全流程Axure高保真原型设计文档。 原型预览地址&#xff1a;https://ppndif.axshare.com 产品意义&#xff1a; 提高工作效率&#xff1a; 电子记账替代手工记账&#xff0c;减少工作负担和人为错误。 实时查看库存情况&#xff0c;减少盘点时…

MySQL常用语句(一)

#数据库操作思路 #相关实验 <SQL语句简介> <web安全SQL语句基本操作> #数据库管理 #创建数据库 在与数据进行任何操作之前&#xff0c;需要创建一个数据库。数据库是数据的容器&#xff0c;用于存储和操作诸如表、数据库视图、触发器、存储过程等数据的数据集…

项目管理 | 一文读懂什么是敏捷开发管理

在快速变化的商业环境中&#xff0c;项目管理方式也在不断演进&#xff0c;其中敏捷开发管理因其高效、灵活和适应性强的特点&#xff0c;逐渐成为众多企业和团队的首选。本文将详细解析敏捷开发管理的定义、具体内容及其核心角色&#xff0c;帮助读者全面理解这一先进的项目管…

Alinx MPSoC驱动开发第17章I2C实验修改设备树后petalinux编译报错

问题描述 在使用Alinx的MPSoC Linux驱动开发手册第17章进行I2C驱动学习时&#xff0c;在按照手册&#xff0c;在system-user.dtsi文件最后添加引用i2c1节点内容&#xff1a; 然后使用petalinux-build命令进行编译&#xff0c;后报错如下&#xff1a; 尝试解决问题 1&#xff0c…

vscode软件在 C发中常用插件

一. 简介 本文简单介绍一下&#xff0c;当做 C开发时 vscode软件常用的插件。 vscode软件是 微软公司目前提供的一款免费的开发软件&#xff0c;可以通过 vscode官网下载 vscode。 二. vscode软件在 C开发中常用插件 注意&#xff1a;vscode软件安装后&#xff0c;可以直接…

FlinkCDC 3.2.0 新增优点 Pattern Replacement in routing rules

新增优点&#xff1a;Pattern Replacement in routing rules flinkcdc 3.2.0版本相较于3.1.0版本&#xff0c;避免了多表多sink多次写 route 路由的麻烦&#xff0c;类似于统一前后缀的形式多表多sink&#xff0c;通过<>正则&#xff0c;大大减少了书写 官网&#xff1…

鸿蒙开发之ArkUI 界面篇 九 QQ音乐登录界面揭秘

我们需要实现的效果如下图&#xff1a; : 分析&#xff0c;垂直方向&#xff0c;四个按钮&#xff0c;从上往下第一个是Image&#xff0c;第二个是Text、第三个是是Button、第四个是Button&#xff0c;垂直布局用Column&#xff0c;代码实现如下&#xff1a; Entry Component…

【C语言进阶】动态内存与柔性数组:C语言开发者必须知道的陷阱与技巧

&#x1f4dd;个人主页&#x1f339;&#xff1a;Eternity._ ⏩收录专栏⏪&#xff1a;C语言 “ 登神长阶 ” &#x1f921;往期回顾&#x1f921;&#xff1a;C语言动态内存管理 &#x1f339;&#x1f339;期待您的关注 &#x1f339;&#x1f339; ❀C语言动态内存管理 &…

RabbitMQ 基础入门

文章内容是学习过程中的知识总结&#xff0c;如有纰漏&#xff0c;欢迎指正 文章目录 前言 1. 重要概念 1.1 Publisher 1.2 Message 1.3 Exchange 1.4 BindingKey 1.5 Routingkey 1.6 Queue 1.7 Consumer 1.8 Connection 1.9 Channel 1.10 Virtual Host 1.11Broker 2. RabbitMQ…

三菱变频器以模拟量电流进行频率设定(电流输入)

POINT 1、在 STF(STR)信号 ON 时&#xff0c;发出启动指令。2、请将 AU 信号置为 ON。 3、请设定 Pr.79 运行模式选择 “2”(外部运行模式)。 接线示例 重点&#xff1a;请将 AU 信号置为 ON。 操作示例&#xff1a;以 60Hz 运行。 1、接通电源时的画面&#xff0c;监视器显…

vue3+ant design vue 中弹窗自定义按钮设置及以冒号为基准布局

1、自定义弹窗按钮&#xff0c;去除取消和确定按钮。&#xff08;网上很多方法都是说通过插槽来实现&#xff0c;但是试了下不生效&#xff0c;那既然插槽不生效的话&#xff0c;干脆直接写按钮就好了&#xff09; <a-modalv-model:open"open"title"人员信息…

如何挑选适用的WMS 智能仓储管理系统?这份盘点攻略请收好!

本文将盘点十款WMS智能仓储管理系统&#xff0c;为企业选型提供参考&#xff01; 在现代企业的物流运作中&#xff0c;仓库就如同一个关键的枢纽&#xff0c;连接着生产与销售的各个环节。而一个高效的 WMS 智能仓储管理系统&#xff0c;就像是一位精明的管家&#xff0c;能让仓…

选购到不好的宠物空气净化器会有什么危害?有哪几款推荐

前三个月真的是被我男朋友气到了&#xff0c;明明说好的一起养猫&#xff0c;他又嫌这嫌那的&#xff0c;真的是无语住。 在养猫前的一个月就说好了&#xff0c;谁下班早谁就先回家收拾&#xff0c;包括进门开窗通风、给猫喂食、还有铲猫砂盆。但是他现在抱怨说太麻烦了&#…

开源即时通讯IM框架MobileIMSDK的H5端技术概览

一、基本介绍 MobileIMSDK的H5端是一套纯JS编写的基于标准WebSocket的即时通讯库&#xff1a; 1&#xff09;超轻量级、极少依赖&#xff1b;2&#xff09;纯JS编写、高度提炼&#xff0c;简单易用&#xff1b;3&#xff09;基于标准WebSocket协议&#xff0c;客户端兼容性好…