《QT实用小工具·四十四》支持图片和动图的文本编辑器

1、概述
源码放在文章末尾

该项目实现了一个功能丰富的文本编辑器,除了包含文本常规的编辑功能,还包括图片的插入功能和动图的插入功能,项目demo演示如下所示:
在这里插入图片描述

项目部分代码如下所示:

#include "imagehelper.h"#include <QFile>
#include <QFileInfo>
#include <QQmlFile>
#include <QQuickTextDocument>
#include <QDebug>Api::Api(QObject *parent): QObject(parent)
{
}bool Api::exists(const QString &arg)
{return QFile::exists(arg);
}QString Api::baseName(const QString &arg)
{return QFileInfo(arg).baseName();
}ImageHelper::ImageHelper(QObject *parent): QObject(parent),m_maxWidth(120),m_maxHeight(120)
{}ImageHelper::~ImageHelper()
{cleanup();
}void ImageHelper::insertImage(const QUrl &url)
{QImage image = QImage(QQmlFile::urlToLocalFileOrQrc(url));if (image.isNull()){qDebug() << "不支持的图像格式";return;}QString filename = url.toString();QString suffix = QFileInfo(filename).suffix();if (suffix == "GIF" || suffix == "gif") //如果是gif,则单独处理{QString gif = filename;if (gif.left(4) == "file")gif = gif.mid(8);else if (gif.left(3) == "qrc")gif = gif.mid(3);textCursor().insertHtml("<img src='" + url.toString() + "' width = " +QString::number(qMin(m_maxWidth, image.width())) + " height = " +QString::number(qMin(m_maxHeight, image.height()))+ "/>");textDocument()->addResource(QTextDocument::ImageResource, url, image);if (m_urls.contains(url))return;else{QMovie *movie = new QMovie(gif);movie->setCacheMode(QMovie::CacheNone);connect(movie, &QMovie::finished, movie, &QMovie::start);   //循环播放connect(movie, &QMovie::frameChanged, this, [url, this](int){QMovie *movie = qobject_cast<QMovie *>(sender());textDocument()->addResource(QTextDocument::ImageResource, url, movie->currentPixmap());emit needUpdate();});m_urls[url] = movie;movie->start();}}else{        QTextImageFormat format;format.setName(filename);format.setWidth(qMin(m_maxWidth, image.width()));format.setHeight(qMin(m_maxHeight, image.height()));textCursor().insertImage(format, QTextFrameFormat::InFlow);}
}void ImageHelper::cleanup()
{for (auto it : m_urls)it->deleteLater();m_urls.clear();
}QQuickTextDocument* ImageHelper::document() const
{return  m_document;
}void ImageHelper::setDocument(QQuickTextDocument *document)
{if (document != m_document){m_document = document;emit documentChanged();}
}int ImageHelper::cursorPosition() const
{return m_cursorPosition;
}void ImageHelper::setCursorPosition(int position)
{if (position != m_cursorPosition){m_cursorPosition = position;emit cursorPositionChanged();}
}int ImageHelper::selectionStart() const
{return m_selectionStart;
}void ImageHelper::setSelectionStart(int position)
{if (position != m_selectionStart){m_selectionStart = position;emit selectionStartChanged();}
}int ImageHelper::selectionEnd() const
{return m_selectionEnd;
}void ImageHelper::setSelectionEnd(int position)
{if (position != m_selectionEnd){m_selectionEnd = position;emit selectionEndChanged();}
}int ImageHelper::maxWidth() const
{return m_maxWidth;
}void ImageHelper::setMaxWidth(int max)
{if (max != m_maxWidth){m_maxWidth = max;emit maxWidthChanged();}
}int ImageHelper::maxHeight() const
{return m_maxHeight;
}void ImageHelper::setMaxHeight(int max)
{if (max != m_maxHeight){m_maxHeight = max;emit maxHeightChanged();}
}QTextDocument* ImageHelper::textDocument() const
{if (m_document)return m_document->textDocument();else return nullptr;
}QTextCursor ImageHelper::textCursor() const
{QTextDocument *doc = textDocument();if (!doc)return QTextCursor();QTextCursor cursor = QTextCursor(doc);if (m_selectionStart != m_selectionEnd){cursor.setPosition(m_selectionStart);cursor.setPosition(m_selectionEnd, QTextCursor::KeepAnchor);}else{cursor.setPosition(m_cursorPosition);}return cursor;
}

源码下载

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

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

相关文章

echarts实现水滴图

使用echarts实现水滴图 引入依赖&#xff0c;echarts-liquidfill3兼容echarts5; 安装依赖 "echarts": "^5.4.3","echarts-liquidfill": "^3.1.0",npm install echarts-liquidfill3.1.0 -S实现的效果图 构建一个水滴图的页面 <tem…

Scanpy(1)数据结构和样本过滤

注&#xff1a;主要讲述scanpy处理数据的结构、数据过滤&#xff08;生信领域&#xff09;和数据预处理&#xff08;和机器学习类似&#xff0c;但是又有不同。&#xff09; 1. Scanpy简介与安装 Scanpy 是一个可扩展的工具包&#xff0c;用于分析与 AnnData&#xff08;一种…

【spring mvc】配置默认Servlet处理器

最近在开发项目时遇到将springmvc无法处理的静态资源请求转发给tomcat默认的servlet进行处理的场景&#xff0c;然后根据DispatcherServlet请求的路径&#xff0c;找到了如何配置默认Servlet处理器。 一、配置方式 具体需要看您是否使用了springmvc提供的方式完成的注入配置&…

SpringCloud系列(19)--将服务消费者Consumer注册进Consul

前言&#xff1a;在上一章节中我们把服务提供者Provider注册进了Consul&#xff0c;而本章节则是关于如何将服务消费者Consumer注册进Consul 1、再次创建一个服务提供者模块&#xff0c;命名为consumerconsul-order80 (1)在父工程下新建模块 (2)选择模块的项目类型为Maven并选…

LabelMe和x-anyLabeling标注工具的合二为一版

LabelMe标注辅助工具&#xff0c;anylabeling标注辅助 LabelMe和X-AnyLabeling都是用于图像标注的工具&#xff0c;它们各自具有独特的特点和功能。 LabelMe是一款广泛使用的开源图像标注工具&#xff0c;专门用于图像标注和语义分割。它提供了一个平台&#xff0c;使用户能够手…

2024LarkXR新增功能系列之九| 优化分配策略:增加GPU检查参数

Paraverse平行云实时云渲染解决方案LarkXR在2024年新增了优化分配策略&#xff0c;增强了GPU检查参数的能力&#xff0c;满足了复杂元宇宙/数字孪生场景多样性的可视化的需求&#xff0c;为这些应用找到了更好的解决方案。新版本的LarkXR在渲染请求分配策略上做出了显著的改进。…

币圈资讯Cryptosquare论坛

在加密货币世界中&#xff0c;信息的及时获取对于投资者和交易者至关重要。今天&#xff0c;我将向大家介绍Cryptosquare这个综合性资讯论坛&#xff0c;它汇集了币圈新闻、空投信息、社会热点以及与Web3相关的工作信息。让我们一起解锁加密世界的种种可能性&#xff0c;探索Cr…

创建SpringBoot和RabbitMQ的整合项目

文章目录 创建SpringBoot和RabbitMQ的整合项目首先快速创建一个maven项目引入SpringBoot整合rabbitMQ的依赖在src/main目录下创建resources目录并引入配置文件写消息发送者MessageSender写消息接收者MessageReceiver写RabbitMQConfig配置类写SpringBoot启动主类CommandLineRunn…

Vue Router与Vite的无缝集成

Vue Router和Vite是Vue.js生态系统中两个非常强大的工具。Vue Router是Vue.js官方的路由管理器&#xff0c;用于构建单页面应用程序。Vite是一个基于ESM的构建工具&#xff0c;用于快速构建现代化的Web应用程序。 Vue Router和Vite之间的无缝集成非常简单&#xff0c;只需要遵…

装饰器模式(模拟⼀个单点登录功能扩充)

目录 定义 模拟⼀个单点登录功能扩充 模拟Spring的HandlerInterceptor 模拟单点登录功能 代码实现 抽象类装饰⻆⾊ 装饰⻆⾊逻辑实现 测试验证 定义 装饰器的核⼼就是再不改原有类的基础上给类新增功能。不改变原有类&#xff0c;使⽤装饰器模式会是另外⼀种思路更为灵…

【黑马点评Redis——002商户查询缓存】

1. 商户查询缓存 2. 知识储备和课程内容 2.1 什么是缓存 缓存是数据交换的缓冲区&#xff0c;是存贮数据的临时地方&#xff0c;一般读写性能较高。 浏览器缓存应用层缓存数据库缓存CPU缓存磁盘缓存 缓存的作用&#xff1a; 降低后端负载提高读写效率&#xff0c;降低响应…

B站无限评论暴力截留协议及教程

B站无限评论暴力截留协议及教程 B站无限评论暴力截留协议及教程&#xff0c;需要抓CK &#xff0c;教程里面有讲如何抓取 网盘自动获取 链接&#xff1a;https://pan.baidu.com/s/1lpzKPim76qettahxvxtjaQ?pwd0b8x 提取码&#xff1a;0b8x

springboot路劲映射

般情况下&#xff0c;使用了页面模板后&#xff0c;用户需要通过控制器才能访问页面。有一些页面需要在控制器中加载数据&#xff0c;然后渲染&#xff0c;才能显示出来;还有一些页面在控制器中不需要加载数据&#xff0c;只是完成简单的跳转&#xff0c;对于这种页面&#xff…

C++:week1:C语言基础

文章目录 (一) C语言概述1.预处理指令&#xff1a;宏定义、宏函数2.生成可执行程序的过程3.进程与虚拟内存空间 (二) 格式化输入输出1.变量及命名2.格式化输入输出、输入输出模型(1)CPU、内存、外部设备的速度矛盾(2)printf(3)scanf 3.代码即注释4.程序出错的原因、调试程序5.其…

C++并发编程 - 线程管理

目录 等待线程的完成 传递参数 属性API Reference 我们的std::thread对象就是在创建的时候方才执行函数&#xff0c;而不是使用某一个类似于run的API执行。这使得我们启动一个线程的方式变得很简单&#xff1a; void task(void); // A demo std::thread(task); 我们这样就…

提示词优化的自动化探索:Automated Prompt Engineering

编者按&#xff1a; 作者在尝试教授母亲使用 LLM 完成工作任务时&#xff0c;意识到提示词的优化并不像想象中简单。提示词的自动优化对于经验并不丰富的提示词撰写者很有价值&#xff0c;他们没有足够的经验去调整和改进提供给模型的提示词&#xff0c;这引发了对自动化提示词…

C++学习之指针和引用

指针 指针是一个变量&#xff0c;其值为另一个变量的地址&#xff0c;即&#xff0c;内存位置的直接地址。就像其他变量或常量一样&#xff0c;您必须在使用指针存储其他变量地址之前&#xff0c;对其进行声明。指针变量声明的一般形式为&#xff1a; type *var-name; 在这里…

kotlin 编写一个简单的天气预报app (七)使用material design

一、优化思路 对之前的天气预报的app进行了优化&#xff0c;原先的天气预报程序逻辑是这样的。 使用text和button组合了一个输入城市&#xff0c;并请求openweathermap对应数据&#xff0c;并显示的功能。 但是搜索城市的时候&#xff0c;可能会有错误&#xff0c;比如大小写…

steam打不开没反应 steam客户端启动不了一直无响应的解决方法

steam打不开没反应 steam客户端启动不了一直无响应的解决方法 steam这个平台想必各位游戏爱好者们肯定不会陌生&#xff0c;作为全球最大的游戏服务平台&#xff0c;steam不仅为玩家们提供了全面的游戏服务&#xff0c;还经常给玩家们提供各种游戏优惠&#xff0c;并且每年四…

addr2line.exe

2024年4月28日&#xff0c;周日上午 什么是addr2line.exe&#xff1f; addr2line.exe 是一个用于将程序地址转换为文件名和行号的工具。通常情况下&#xff0c;当程序出现崩溃或者错误时&#xff0c;系统会生成一个包含程序崩溃点地址的错误报告。 addr2line.exe 可以帮助开发…