《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;
}

源码下载

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

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

相关文章

基于深度学习神经网络的AI图片上色DDcolor系统源码

第一步&#xff1a;DDcolor介绍 DDColor 是最新的 SOTA 图像上色算法&#xff0c;能够对输入的黑白图像生成自然生动的彩色结果&#xff0c;使用 UNet 结构的骨干网络和图像解码器分别实现图像特征提取和特征图上采样&#xff0c;并利用 Transformer 结构的颜色解码器完成基于视…

循环单链表的介绍与操作

定义 区别 链表合并 整合代码 typedef struct node{int data;node* next;; }lnode,*linklist; lnode* n; linklist l;//定义 void init(linklist &l){lnode lnew lnode;l->nextl;lnode *rl; } //单循环链表的合并 linklist merge(linklist &a,linklist b){//存头结…

注意力机制:SENet详解

SENet&#xff08;Squeeze-and-Excitation Networks&#xff09;是2017年提出的一种经典的通道注意力机制&#xff0c;这种注意力可以让网络更加专注于一些重要的featuremap&#xff0c;它通过对特征通道间的相关性进行建模&#xff0c;把重要的特征图进行强化来提升模型的性能…

ZISUOJ 高级语言程序设计实训-基础C(部分题)

说明&#xff1a; 有几个题是不会讲的&#xff0c;我只能保证大家拿保底分。 题目列表&#xff1a; 问题 A: 求平均数1 思路&#xff1a; 送分题…… 参考题解&#xff1a; #include <iostream> #include <iomanip> using std::cin; using std::cout;int main(…

C++项目在Linux下编译动态库

一、说明 最近在Windows下开发了一个C线程池项目&#xff0c;准备移植到Linux下&#xff0c;并且编译成动态库进行使用。现将具体过程在此记录。 二、准备 1、项目文件 我的项目文件如下&#xff0c;其中除main.cpp是测试文件之外&#xff0c;其他都是线程池项目相关的 将C…

双系统下删除ubuntu

絮絮叨叨 由于我在安装Ubuntu的时候没有自定义安装位置&#xff0c;而是使用与window共存的方式让Ubuntu自己选择安装位置&#xff0c;导致卸载时我不知道去格式化哪个分区&#xff0c;查阅多方资料后无果&#xff0c;后在大佬帮助下找到解决方案 解决步骤 1、 插上Ubuntu安…

【IR 论文】DPR — 最早提出使用嵌入向量来检索文档的模型

论文&#xff1a;Dense Passage Retrieval for Open-Domain Question Answering ⭐⭐⭐⭐⭐ EMNLP 2020, Facebook Research Code: github.com/facebookresearch/DPR 文章目录 一、论文速读二、DPR 的训练2.1 正样本和负样本的选取2.2 In-batch negatives 技巧 三、实验3.1 数据…

医学影像增强:空间域方法与频域方法等

医学影像图像增强是一项关键技术,旨在改善图像质量,以便更好地进行疾病诊断和评估。增强方法通常分为两大类:空间域方法和频域方法。 一、 空间域方法 空间域方法涉及直接对医学影像的像素值进行操作,以提高图像的视觉质量。以下是一些常用的空间域方法: 对比度调整:通过…

双向链表的介绍

引入 特点 操作 定义 插入 删除 小结 整合代码&#xff1a; //定义 typedef struct node{int data;node* next,prior; }Dlnode,*Dlinklist;//初始 void init(Dlinklist &l){Dlnode lnew Dlnode;l->nextNULL;l->priorNULL; }//插入&#xff1a;插入指定位置&#…

buuctf-misc-rar

13.rar 题目&#xff1a;直接破解就可以了 这个借用工具Aparch进行4位纯数字暴力破解&#xff0c;根据题目的提示是4位的纯数字&#xff0c;那我们就选择数字的破解 在长度这里&#xff0c;把最小口令长度和最大口令长度都选择为4 获得密码后进行解压。

各省财政涉农支出统计数据集(2001-2022年)

01、数据简介 财政涉农支出是指在政府预算中&#xff0c;用于支持农业、农村和农民发展的财政支出。这些支出旨在促进农村经济的发展&#xff0c;提高农民收入&#xff0c;改善农村生产生活条件&#xff0c;推进农业现代化。 在未来的发展中&#xff0c;各省将继续加大财政涉…

【研发管理】产品经理知识体系-产品设计与开发工具

导读&#xff1a;产品设计与开发工具的重要性体现在多个方面&#xff0c;它们对于产品的成功开发、质量提升以及市场竞争力都具有至关重要的影响。产品设计工具可以帮助设计师更高效地创建和优化产品原型。开发工具在产品开发过程中发挥着至关重要的作用。产品设计与开发工具还…

这三个AI导航站,你绝对用得到!!

Hi&#xff0c;这里是前端后花园&#xff0c;专注分享前端软件网站、工具资源。不得不说AI正在慢慢改变我们学习和工作方式&#xff0c;今天带来这三个AI导航站&#xff0c;总有一个你用得到&#xff0c;记得收藏啊&#xff01; AI工具集 https://ai-bot.cn/ 网站汇集了700 …

Linux多线程(三) 线程池C++实现

一、线程池原理 我们使用线程的时候就去创建一个线程&#xff0c;这样实现起来非常简便。但如果并发的线程数量很多&#xff0c;并且每个线程都是执行一个时间很短的任务就结束了&#xff0c;这样频繁创建线程就会大大降低系统的效率&#xff0c;因为频繁创建线程和销毁线程需…

华为MRS服务使用记录

背景&#xff1a;公司的业务需求是使用华为的这一套成品来进行开发&#xff0c;使用中发现&#xff0c;这个产品跟原生的Hadoop的那一套的使用&#xff0c;还是有很大的区别的&#xff0c;现记录一下&#xff0c;避免以后忘了 一、原始代码的下载 下载地址&#xff1a;MRS样例…

STM32HAL库++ESP8266+cJSON连接阿里云物联网平台

实验使用资源&#xff1a;正点原子F1 USART1&#xff1a;PA9P、A10&#xff08;串口打印调试&#xff09; USART3&#xff1a;PB10、PB11&#xff08;WiFi模块&#xff09; DHT11&#xff1a;PG11&#xff08;采集数据、上报&#xff09; LED0、1&#xff1a;PB5、PE5&#xff…

input框添加验证(如只允许输入数字)中文输入导致显示问题的解决方案

文章目录 input框添加验证(如只允许输入数字)中文输入导致显示问题的解决方案问题描述解决办法 onCompositionStart与onCompositionEnd input框添加验证(如只允许输入数字)中文输入导致显示问题的解决方案 问题描述 测试环境&#xff1a;react antd input (react的事件与原生…

浅谈在Java代码中创建线程的多种方式

文章目录 一、Thread 类1.1 跨平台性 二、Thread 类里的常用方法三、创建线程的方法1、自定义一个类&#xff0c;继承Thread类&#xff0c;重写run方法1.1、调用 start() 方法与调用 run() 方法来创建线程&#xff0c;有什么区别&#xff1f;1.2、sleep()方法 2、自定义一个类&…

嵌入式常见存储器

阅读引言&#xff1a; 在看一款芯片的数据手册的时候&#xff0c; 无意间翻到了它的启动模式(Boot Mode), 发现这种这么多种ROM&#xff0c;所以就写下了这篇文章。 目录 一、存储器汇总 二、易失性存储器(RAM) 1. SRAM 1.1 单口SRAM 1.2 双口SRAM 2. DRAM 2.1 SDRAM 2…

Fast-DetectGPT 无需训练的快速文本检测

本文提出了一种新的文本检测方法 ——Fast-DetectGPT&#xff0c;无需训练&#xff0c;直接使用开源小语言模型检测各种大语言模型&#xff0c;如GPT等生成的文本内容。 Fast-DetectGPT 将检测速度提高了 340 倍&#xff0c;将检测准确率相对提升了 75%&#xff0c;超过商用系…