[Qt] 基于 Qt 的文件选择与图片显示功能实现

news2024/10/5 13:54:20


文章目录

  • 基础版本:`open1()`
      • 功能解析:
      • 特点与限制:
  • 增加路径记忆功能:`open2()`
      • 功能解析:
      • 特点与改进:
  • 使用智能指针优化内存管理:`open3()`
      • 功能解析:
      • 特点与改进:
  • 图片自适应窗口:`open4()`
      • 功能解析:
      • 特点与改进:
  • 总结
        • 1. **基本功能:图片选择与显示**
        • 2. **路径记忆功能**
        • 3. **智能指针管理内存**
        • 4. **图片自适应窗口功能**
        • 5. **版本递进思路**

在这篇博客中,我们将带领 Qt 的初学者一步步实现一个简单的图片选择与显示功能,并逐渐优化代码,从最基础的版本开始,逐步添加更多的功能。本文中使用了 Qt 中多个重要的类和函数,例如 QFileDialogQSettingsQPixmap 等。文章为每个版本的实现进行详细讲解,帮助更好地理解 Qt 的使用。

基础版本:open1()

open1() 是一个最基础的实现,用于选择图片文件并在界面上显示图片。下面是该版本的实现:

void Widget::open1()
{
    // 打开文件对话框,供用户选择图片文件
    // getOpenFileName() 函数的四个参数依次是:
    // 1. 父组件,通常传递当前对象 this
    // 2. 对话框标题
    // 3. 初始打开的文件路径(此处是 D 盘根目录)
    // 4. 过滤器,限制显示的文件类型(这里是 PNG 和 JPG 格式的图片)
    QString filename = QFileDialog::getOpenFileName(this, "请选择图片", "D:/", "图片(*.png *.jpg)");

    // 如果用户没有选择任何文件,直接返回
    if(filename.isEmpty())
    {
        return;
    }

    // 将选择的文件路径显示在界面上的 QLineEdit 中
    ui->lineEdit_path->setText(filename);

    // 将选择的图片加载成 QPixmap 对象,并显示在 QLabel 中
    ui->label_image->setPixmap(QPixmap(filename));
}

功能解析:

  • QFileDialog::getOpenFileName
    用于显示文件选择对话框,返回所选文件的路径。如果用户取消选择,则返回空字符串。 。它返回用户选择的文件的完整路径。参数包括:
    • this: 父窗口指针。
    • "请选择图片": 对话框的标题。
    • "D:/": 初始路径,这里设置为 D: 盘。
    • "图片(*.png *.jpg)": 过滤器,限制用户只能选择 .png.jpg 格式的图片。
  • QLineEdit::setText()
    这个函数用于在界面上的文本框(这里是 lineEdit_path)中显示选中文件的路径。
  • QLabel::setPixmap()
    用于在标签中显示图片,将 QPixmap 对象加载的图片展示到界面上,QPixmap 对象用于加载图片。通过 setPixmap,我们可以将图片显示在 label_image 组件中。

特点与限制:

这个版本的代码实现了基础的图片选择与显示功能,但有一个明显的缺点:每次打开文件选择对话框时,路径都会重置为 D:/,不能记住上次用户选择的文件夹位置。

增加路径记忆功能:open2()

open2() 中,我们对 open1() 进行了增强,添加了保存和记忆上次打开路径的功能。为此, 通过 QSettings 类保存和读取上次使用的路径。

void Widget::open2()
{
    // 获取应用程序的配置文件路径,存放在当前应用的目录下
    QString config_path = qApp->applicationDirPath() + "/config/Setting.ini";
    qDebug() << config_path;  // 输出配置文件路径,便于调试查看

    // 使用 QSettings 读取 ini 文件中的配置信息,文件不存在时会自动创建
    QSettings* pIniSet = new QSettings(config_path, QSettings::IniFormat);

    // 从配置文件中读取上次使用的路径,如果没有记录则返回空字符串
    QString lastPath = pIniSet->value("/LastPath/path").toString();

    // 如果没有上次记录的路径,使用系统默认的图片目录
    if (lastPath.isEmpty())
    {
        // QStandardPaths::writableLocation 获取系统中常用路径
        lastPath = QStandardPaths::writableLocation(QStandardPaths::PicturesLocation);
    }

    // 打开文件选择对话框,初始路径设置为 lastPath
    QString filename = QFileDialog::getOpenFileName(this, "请选择图片", lastPath, "图片(*.png *.jpg)");

    // 如果用户没有选择文件,直接返回
    if(filename.isEmpty())
    {
        return;
    }

    // 将选择的文件路径显示在界面上的文本框中
    ui->lineEdit_path->setText(filename);

    // 显示选择的图片
    ui->label_image->setPixmap(QPixmap(filename));

    // 获取文件路径的目录部分,更新配置文件中的路径
    int end = filename.lastIndexOf("/");
    QString _path = filename.left(end);
    pIniSet->setValue("/LastPath/path", _path);

    // 删除 QSettings 对象,释放内存
    delete pIniSet;
    pIniSet = nullptr;

    qDebug() << _path;  // 输出更新后的路径,便于调试查看
}

功能解析:

  • QSettings
    这是 Qt 提供的一个便捷的类,用于保存应用程序的配置信息,支持使用 ini 文件或者注册表。这里使用 ini 文件存储用户上次选择的路径。在这个例子中,配置文件是 Setting.ini,其中存储了用户上次打开文件的路径。
    • pIniSet->value("/LastPath/path").toString():读取配置中的路径值。
    • pIniSet->setValue("/LastPath/path", _path):在用户选择完图片后,保存其路径。
  • QStandardPaths::writableLocation()
    用于获取操作系统中特定类型的文件夹,例如图片、文档等。在这里当用户第一次打开程序时,程序会自动使用系统的图片目录作为初始路径。
  • **QString::lastIndexOf()**** 和 ****QString::left()**
    用于字符串的操作,lastIndexOf() 查找路径中的最后一个 /left() 截取文件路径的目录部分。

特点与改进:

open2()open1() 的基础上添加了路径记忆功能,每次打开文件选择对话框时,都会显示上次用户选择的文件夹,大大提高了用户体验。同时,它将路径存储在 ini 文件中,确保下次程序启动时可以继续记住路径。

使用智能指针优化内存管理:open3()

open2() 中,我们手动 newdeleteQSettings 对象,虽然这能正常工作,但容易导致内存泄漏问题。为了安全管理内存,open3() 使用了 C++11 引入的智能指针 std::unique_ptr,从而自动管理对象的生命周期。

void Widget::open3()
{
    // 获取应用程序的配置文件路径,存放在当前应用的目录下
    QString config_path = qApp->applicationDirPath() + "/config/Setting.ini";
    qDebug() << config_path;  // 输出配置文件路径,便于调试查看

    // 使用 std::unique_ptr 管理 QSettings 对象,自动管理内存
    std::unique_ptr<QSettings> pIniSet(new QSettings(config_path, QSettings::IniFormat));

    // 从配置文件中读取上次使用的路径
    QString lastPath = pIniSet->value("/LastPath/path").toString();

    // 如果没有上次记录的路径,使用系统默认的图片目录
    if (lastPath.isEmpty())
    {
        lastPath = QStandardPaths::writableLocation(QStandardPaths::PicturesLocation);
    }

    // 打开文件选择对话框,初始路径设置为 lastPath
    QString filename = QFileDialog::getOpenFileName(this, "请选择图片", lastPath, "图片(*.png *.jpg)");

    // 如果用户没有选择文件,直接返回
    if(filename.isEmpty())
    {
        return;
    }

    // 将选择的文件路径显示在界面上的文本框中
    ui->lineEdit_path->setText(filename);

    // 显示选择的图片
    ui->label_image->setPixmap(QPixmap(filename));

    // 获取文件路径的目录部分,更新配置文件中的路径
    int end = filename.lastIndexOf("/");
    QString _path = filename.left(end);
    pIniSet->setValue("/LastPath/path", _path);

    qDebug() << _path;  // 输出更新后的路径,便于调试查看
}

功能解析:

  • std::unique_ptr
    智能指针是 C++11 引入的内存管理工具,能够在对象不再需要时自动释放内存,从而避免内存泄漏。在这里使用 std::unique_ptr 来管理 QSettings 对象的生命周期,无需手动 delete

特点与改进:

open3() 的逻辑与 open2() 基本相同,不同的是通过 std::unique_ptr 自动管理内存,避免了手动管理的复杂性,提升了代码的健壮性。

图片自适应窗口:open4()

open4() 中,我们在显示图片时进行了进一步优化,添加了使图片自适应窗口大小的功能。

void Widget::open4() 
{
    // 获取应用程序的配置文件路径,存放在当前应用的目录下
    QString config_path = qApp->applicationDirPath() + "/config/Setting.ini";
    qDebug() << config_path;  // 输出配置文件路径,便于调试查看

    // 使用 QSettings 读取 ini 文件中的配置信息
    QSettings* pIniSet = new QSettings(config_path, QSettings::IniFormat);

    // 从配置文件中读取上次使用的路径
    QString lastPath = pIniSet->value("/LastPath/path").toString();

    // 如果没有上次记录的路径,使用系统默认的图片目录
    if (lastPath.isEmpty())
    {
        lastPath = QStandardPaths::writableLocation(QStandardPaths::PicturesLocation);
    }

    // 打开文件选择对话框,初始路径设置为 lastPath
    QString filename = QFileDialog::getOpenFileName(this, "请选择图片", lastPath, "图片(*.png *.jpg)");

    // 如果用户没有选择文件,直接返回
    if(filename.isEmpty())
    {
        return;
    }

    // 将选择的文件路径显示在界面上的文本框中
    ui->lineEdit_path->setText(filename);

    // 使用 QPixmap 对象加载用户选择的图片
    QPixmap* pix = new QPixmap(filename);

    // 将图片缩放为适应 QLabel 的尺寸,但保持宽高比,保证图片不失真
    pix->scaled(ui->label_image->size(), Qt::KeepAspectRatioByExpanding);

    // 设置 QLabel 可以缩放显示图片(保持图片的完整性)
    ui->label_image->setScaledContents(true);

    // 显示缩放后的图片
    ui->label_image->setPixmap(*pix);

    // 释放 QPixmap 对象的内存
    delete pix;
    pix = nullptr;

    // 获取文件路径的目录部分,更新配置文件中的路径
    int end = filename.lastIndexOf("/");
    QString _path = filename.left(end);
    pIniSet->setValue("/LastPath/path", _path);

    // 释放 QSettings 对象的内存
    delete pIniSet;
    pIniSet = nullptr;

    qDebug() << _path;  // 输出更新后的路径,便于调试查看
}

功能解析:

  • **QPixmap::scaled()**
    该函数用于缩放图片。这里的 Qt::KeepAspectRatioByExpanding 参数表示保持图片的宽高比,在必要时扩展图片,以适应标签的大小。
  • **QLabel::setScaledContents()**
    该函数用于设置标签的显示内容是否可以缩放。如果为 true,则图片会根据标签的大小自动调整。

特点与改进:

open4() 添加了图片自适应窗口的功能,使得用户选择的图片可以根据窗口大小自动调整,不再受固定大小限制,增强了用户的视觉体验。该功能通过 QPixmap::scaled() 实现图片的缩放,并通过 QLabel::setScaledContents() 使图片能够适应标签控件的尺寸。

总结

1. 基本功能:图片选择与显示

首先,在最基本的版本 open1() 中,用户可以通过 QFileDialog::getOpenFileName() 打开文件选择对话框,选择一个图片文件(支持 .png.jpg 格式)。当用户选择图片后,程序会将图片路径显示在界面上的文本框中,并通过 QPixmap 加载并显示图片。该功能实现了最基础的图片选择与显示功能,但没有记住用户上次操作路径的能力。

2. 路径记忆功能

open2() 版本中,程序通过 QSettings 实现了路径记忆功能。程序会在配置文件 Setting.ini 中保存用户上次选择图片的路径,并在下次运行时默认打开上次路径所在的文件夹,从而提升用户体验。如果用户是首次运行或配置文件中无路径信息,程序会默认打开系统的“图片库”目录。

QSettings 通过键值对的方式在配置文件中存储和读取数据,程序通过以下步骤实现:

  • 读取配置文件中的上次路径。
  • 如果上次路径不存在,使用默认路径。
  • 更新配置文件中的路径。
3. 智能指针管理内存

open3() 版本中,代码采用了智能指针 std::unique_ptr 来替代手动的内存管理(newdelete),以提高代码的健壮性并避免内存泄漏问题。std::unique_ptr 是 C++11 引入的智能指针类型,可以在作用域结束时自动释放内存,从而不需要手动调用 delete。这一改进使代码更加清晰,降低了错误发生的可能性。

4. 图片自适应窗口功能

open4() 版本进一步优化了图片的显示效果,使图片可以自适应窗口大小。当用户选择图片后,程序通过 QPixmap::scaled() 函数按照 QLabel 的大小对图片进行缩放,并且保持图片的宽高比,防止图片失真。此外,QLabel::setScaledContents(true) 设置让图片能够随着标签控件大小自动调整,从而提升了用户的视觉体验。

5. 版本递进思路

每个版本的改进都基于前一个版本的逻辑,逐步增加功能,增强代码可读性和用户体验:

  • open1():基础功能,图片选择与显示。
  • open2():通过 QSettings 添加路径记忆功能,改善用户体验。
  • open3():引入智能指针管理,避免内存泄漏。
  • open4():实现图片自适应窗口大小的功能,增强视觉效果。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

线程互斥函数的例子

代码 #include<stdio.h> #include<pthread.h> #include<sched.h> void *producter_f(void *arg); void *consumer_f(void *arg); int buffer_has_item0; pthread_mutex_t mutex; int running1; int main(void) {pthread_t consumer_t;pthread_t producter_t…

PCL 点云体素滤波

目录 一、概述 1.1原理 1.2实现步骤 1.3应用场景 二、代码实现 2.1关键函数 2.1.1 体素滤波实现 2.1.2 可视化函数 2.2完整代码 三、实现效果 PCL点云算法汇总及实战案例汇总的目录地址链接&#xff1a; PCL点云算法与项目实战案例汇总&#xff08;长期更新&#xf…

Session会话管理技术

Session会话管理技术 会话: 两个交互,在开发中是指浏览器和服务器它们两个的交互 会话管理: 管理会话中产生的数据,一般是记录登录状态 补充: 状态管理,就是管理数据 1、 Session概述 Session用于记录用户的状态。Session指的是在一段时间内&#xff0c;单个客户端与Web服务…

【C++】—— 类和对象(中)

【C】—— 类和对象(中) 文章目录 【C】—— 类和对象(中)前言1. 类的默认成员函数2. 构造函数3. 析构函数4. 拷贝构造函数5. 赋值运算符重载5.1 运算符重载5.2 赋值运算符重载 结语 前言 小伙伴们大家好呀&#xff0c;昨天的 【C】——类和对象(上) 大家理解的怎么样了 今天…

【AI人工智能】文心智能体,双人冒险游戏智能体创作分享

背景 最近半年&#xff0c;“AI agent”&#xff08;智能体&#xff09;这一词汇变得非常热门。许多人以为创建自己的智能体会很复杂&#xff0c;实际上&#xff0c;现有的平台已经大大降低了操作门槛。只要有创意&#xff0c;几乎每个人都可以轻松创建属于自己的智能体。今天…

WordPress响应式Git主题响应式CMS主题模板

兼容 IE9、谷歌 Chrome 、火狐 Firefox 等主流浏览器 扁平化的设计加响应式布局&#xff0c;兼容电脑、和各个尺寸手机的完美响应 主题设置面板新增多种AD位&#xff0c;PC端和移动设备各不相同 在主题设置选项中就可以进行基本的SEO设置&#xff1a;首页、分类、文章等页面…

跟我学C++中级篇——函数调用的本质

一、进程的执行过程 正常的情况下&#xff0c;程序会被计算机从硬盘加载到内存中&#xff0c;然后跳转到主入口函数进行执行。依次按照逻辑对相关的模块进行加载调用。其中&#xff0c;最常用的就是调用一个函数&#xff0c;可以说&#xff0c;函数是C/C程序中的一个重要的基础…

Python——异常处理机制

Python 异常处理机制 Python异常与异常处理机制针对 Traceback 的解读try-except-else-finallyexcept语句except语句的机制在 except 语句中引用当前被处理的 Python 异常 finally语句finally语句执行后才能抛出未被处理的异常finally中执行return会导致异常丢失 raise 语句rai…

集合框架02:Collection使用(1)

视频链接&#xff1a;13.05 Collection使用&#xff08;1&#xff09;_哔哩哔哩_bilibilihttps://www.bilibili.com/video/BV1zD4y1Q7Fw?p5&vd_sourceb5775c3a4ea16a5306db9c7c1c1486b5 代码示例&#xff1a; package com.yundait.Demo01;import java.util.ArrayList; i…

hbuilderx+uniapp+Android健身房管理系统 微信小程序z488g

目录 项目介绍支持以下技术栈&#xff1a;具体实现截图HBuilderXuniappmysql数据库与主流编程语言java类核心代码部分展示登录的业务流程的顺序是&#xff1a;数据库设计性能分析操作可行性技术可行性系统安全性数据完整性软件测试详细视频演示源码获取方式 项目介绍 用户功能…

震撼!工业史上第一家万级别规模的工业数字化设备效果图平台

耗时八年打造&#xff0c;国内第一家万级别规模的工业数字化设备效果图平台 平台&#xff1a;www.kingview3d.cn 创作者&#xff1a;kingview3d郭工 行业&#xff1a;煤矿综合自动化、污水处理、净水处理、楼宇暖通、环保工程、医药废水处理、二供、无负压加压站、提升泵站、一…

模拟器GSN3之DHCP动态分配IP地址配置案例

前文《详解DHCP服务工作原理及配置案例》介绍了DHCP服务工作原理&#xff0c;要想彻底理解、应用DHCP服务&#xff0c;须通过实证案例学习&#xff0c;该文在GSN3虚拟环境下&#xff0c;构建DHCP服务的环境。 一、配置环境&#xff1a; 1、GSN3 2、路由器&#xff1a;R1、R2…

【微服务】服务注册与发现、分布式配置管理 - Consul(day5)

概述 作用 Consul的两大作用就是服务发现和注册与分布式配置管理。 服务发现在介绍Eureka组件的时候已经进行过详细概述&#xff0c;大概就是将硬编码到服务中的IP地址和端口号进行解耦&#xff0c;从而实现动态扩缩容、容错处理、服务管理等功能&#xff0c;通过服务注册和…

MAC备忘录空白解决方案

打开icloud->备忘录 取消勾选同步此MAC后再次勾选&#xff0c;然后点击完成即可。

<<迷雾>> 第7章 会变魔术的触发器(3)--R-S 触发器 示例电路

用来验证或非门反馈功能的完整电路 info::操作说明 如演示出现异常, 可点右侧面板的重置按钮重置 此处 R 和 S 都使用的是按钮开关 点击 R 可让 Q 熄灭 点击 S 可让 Q 亮起 primary::在线交互操作链接 https://cc.xiaogd.net/?startCircuitLinkhttps://book.xiaogd.net/cyjsjd…

针对线上消息积压的排查思路以及解决方案

一、背景 我们在日常工作中&#xff0c;经常会碰到线上告警&#xff0c;消息队列消息积压了&#xff0c;试想如果对消息的消费速率有要求的场景&#xff0c;消息积压一定会或多或少对自己本身的业务场景有影响&#xff0c;这里就针对消息积压的场景&#xff0c;谈谈具体的排查…

过滤器Filter【详解】

过滤器Filter 1、 现有问题 在以往的Servlet中&#xff0c;有冗余的代码&#xff0c;多个Servlet都有重复的代码 比如编码格式设置 登录信息认证 2、 概念 过滤器&#xff08;Filter&#xff09;是处于客户端与服务器目标资源之间的一道过滤技术。 过滤器 3、 过滤器作用 执…

Python办公自动化教程(006):Word添加标题

2.3 word标题 介绍&#xff1a; 在 python-docx 中&#xff0c;您可以使用 add_heading() 方法为文档添加标题。此方法允许您指定标题的文本和级别&#xff08;例如&#xff0c;一级标题、二级标题等&#xff09;。标题级别的范围是从 0 到 9&#xff0c;其中 0 表示文档的主标…

深度解析:从浏览器输入链接到页面展现的奇幻历程

〇、前言 当我们在浏览器中输入一个网址&#xff0c;例如&#xff1a;example.com&#xff0c;按下回车键后&#xff0c;会发生什么呢&#xff1f; 主要会发生以下这些过程&#xff1a;域名解析、建立HTTP连接、发送HTTP请求、数据传输、渲染网页、断开HTTP连接。 一、域名解…

类型转换【C++提升】(隐式转换、显式转换、自定义转换、转换构造函数、转换运算符重载......你想知道的全都有)

更多精彩内容..... &#x1f389;❤️播主の主页✨&#x1f618; Stark、-CSDN博客 本文所在专栏&#xff1a; C系列语法知识_Stark、的博客-CSDN博客 座右铭&#xff1a;梦想是一盏明灯&#xff0c;照亮我们前行的路&#xff0c;无论风雨多大&#xff0c;我们都要坚持不懈。 一…