【写在前面】

在 Qt 的 Quick 模块中,QQuickPaintedItem 是一个非常有用的类,它允许我们在 Qml 中自定义绘制逻辑。

我们可以通过这种方式实现水印工具,包括在文本、图片或整个窗口上添加水印。

本文将介绍如何在 Qml 中实现一个简单但功能强大的水印工具,包括水印文本的透明度、颜色、字体大小、旋转角度等自定义功能。


【正文开始】

一、效果图

二、水印工具类的设计

首先,我们需要设计一个 C++ 类来表示水印工具。这个类将继承自 QQuickPaintedItem,并添加一些属性来控制水印的外观和行为。这些属性包括水印文本、图像、大小、间距、偏移量、旋转角度、字体和字体颜色。

watermark.h

Watermark 类的头文件中,我们声明了所有的属性和相应的信号、槽函数。使用 Q_PROPERTY 宏来声明 Qml 中可访问的属性。

#ifndef WATERMARK_H
#define WATERMARK_H #include <QQuickPaintedItem> QT_FORWARD_DECLARE_CLASS(WatermarkPrivate); class Watermark : public QQuickPaintedItem
{
Q_OBJECT // 声明QML中可访问的属性
Q_PROPERTY(QString text READ text WRITE setText NOTIFY textChanged FINAL)
Q_PROPERTY(QUrl image READ image WRITE setImage NOTIFY imageChanged FINAL)
Q_PROPERTY(QSize markSize READ markSize WRITE setMarkSize NOTIFY markSizeChanged FINAL)
Q_PROPERTY(QPointF gap READ gap WRITE setGap NOTIFY gapChanged FINAL)
Q_PROPERTY(QPointF offset READ offset WRITE setOffset NOTIFY offsetChanged FINAL)
Q_PROPERTY(qreal rotate READ rotate WRITE setRotate NOTIFY rotateChanged FINAL)
Q_PROPERTY(QFont font READ font WRITE setFont NOTIFY fontChanged FINAL)
Q_PROPERTY(QColor fontColor READ fontColor WRITE setFontColor NOTIFY fontColorChanged FINAL) public:
Watermark(QQuickItem *parent = nullptr);
~Watermark(); // 属性的getter和setter函数
QString text() const;
void setText(const QString &text); QUrl image() const;
void setImage(const QUrl &image); QSize markSize() const;
void setMarkSize(const QSize &markSize); QPointF gap() const;
void setGap(const QPointF &gap); QPointF offset() const;
void setOffset(const QPointF &offset); qreal rotate() const;
void setRotate(qreal rotate); QFont font() const;
void setFont(const QFont &font); QColor fontColor() const;
void setFontColor(const QColor &fontColor); signals:
void textChanged();
void imageChanged();
void markSizeChanged();
void gapChanged();
void offsetChanged();
void rotateChanged();
void fontChanged();
void fontColorChanged(); protected:
void paint(QPainter *painter); private:
Q_DECLARE_PRIVATE(Watermark);
QScopedPointer<WatermarkPrivate> d_ptr;
}; #endif // WATERMARK_H

watermark.cpp

Watermark 类的实现文件中,我们主要实现了属性的 settergetter 函数,这些函数在属性值改变时会触发相应的信号,并调用update()函数来请求重新绘制。同时,我们也实现了paint()函数,它使用 QPainter 来绘制水印。

// watermark.cpp的实现省略,具体可参考提供的 watermark.cpp 文件

WatermarkPrivate.h

WatermarkPrivateWatermark 类的私有实现部分,它包含了所有的成员变量和辅助函数。这些成员变量包括水印文本、图像URL、网络请求回复、图像缓存、字体和字体颜色等。

// WatermarkPrivate类的声明省略,具体可参考watermark.cpp文件中的WatermarkPrivate部分

三、 Qml 中的使用

main.qml

在 Qml 文件中,我们可以使用 Watermark 元素来添加水印。通过设置 Watermark 的属性,我们可以控制水印的外观和行为。

import QtQuick 2.15
import QtQuick.Controls 2.15
import QtQuick.Window 2.15
import QtQuick.Layouts 1.15 import DelegateUI.Controls 1.0 Window {
id: window
width: 1080
height: 600
visible: true
title: qsTr("DelegateUI Watermark") RowLayout {
anchors.fill: parent ColumnLayout {
Layout.preferredWidth: parent.width * 0.5
Layout.preferredHeight: parent.height * 0.5 Item {
id: content1
Layout.fillWidth: true
Layout.fillHeight: true Watermark {
id: watermark1
anchors.fill: parent
offset.x: -50
offset.y: -50
rotate: slider1.value
fontColor: "#30ff0000"
} Text {
anchors.centerIn: parent
text: qsTr("文字水印测试")
font.pointSize: 36
}
} RowLayout {
Layout.fillWidth: true
Layout.maximumHeight: 40 Slider {
id: slider1
Layout.preferredWidth: 150
Layout.fillHeight: true
value: -22
from: -360
to: 360
stepSize: 1
} TextField {
id: markText
Layout.fillWidth: true
Layout.fillHeight: true
text: "DelegateUI Watermark"
placeholderText: qsTr("输入水印文本")
font.family: "微软雅黑"
selectByMouse: true
} Button {
Layout.preferredWidth: 80
Layout.fillHeight: true
text: qsTr("确定")
onClicked: watermark1.text = markText.text;
} Button {
Layout.preferredWidth: 80
Layout.fillHeight: true
text: qsTr("导出")
onClicked: {
content1.grabToImage((result)=>{
result.saveToFile("./content1.png");
Qt.openUrlExternally("file:./");
});
}
}
}
} ColumnLayout {
Layout.preferredWidth: parent.width * 0.5
Layout.preferredHeight: parent.height * 0.5 Item {
id: content2
Layout.fillWidth: true
Layout.fillHeight: true Watermark {
id: watermark2
anchors.fill: parent
offset.x: -50
offset.y: -50
markSize.width: 200
markSize.height: 150
rotate: slider2.value
opacity: 0.2
} Text {
anchors.centerIn: parent
text: qsTr("图像水印测试")
font.pointSize: 36
}
} RowLayout {
Layout.fillWidth: true
Layout.maximumHeight: 40 Slider {
id: slider2
Layout.preferredWidth: 150
Layout.fillHeight: true
value: -22
from: -360
to: 360
stepSize: 1
} TextField {
id: markImage
Layout.fillWidth: true
Layout.fillHeight: true
text: "https://avatars.githubusercontent.com/u/33405710?v=4"
placeholderText: qsTr("输入水印图片链接")
font.family: "微软雅黑"
selectByMouse: true
} Button {
Layout.preferredWidth: 80
Layout.fillHeight: true
text: qsTr("确定")
onClicked: watermark2.image = markImage.text;
} Button {
Layout.preferredWidth: 80
Layout.fillHeight: true
text: qsTr("导出")
onClicked: {
content2.grabToImage((result)=>{
result.saveToFile("./content2.png");
Qt.openUrlExternally("file:./");
});
}
}
}
}
}
}

在这个 Qml 文件中,我们创建了两个个 Watermark 元素并通过设置 Watermark 的各种属性,我们实现了一个带有文本和图像的水印效果,并且可以控制水印的大小、间距、偏移量、旋转角度、字体和字体颜色。


【结语】

通过使用 QQuickPaintedItem,我们可以在 Qml 中实现了一个功能丰富的水印工具。

这个工具允许我们自定义水印的外观和行为,并且可以很方便地在 Qml 中使用。

最后:项目链接(多多star呀.._):

Github: https://github.com/mengps/QmlControls

Gitee: https://gitee.com/MenPenS/QmlControls

Qml 中实现水印工具的更多相关文章

  1. qml 中 使用 shader

    使用绘制工具如Photoshop .Flash已经可以创建许多效果非常绚丽的图像.动画等. Qt/QML 的努力其实是在这些工具发展的后面, 因此很多效果在Qt中无法实现. 不得不佩服Qt小组的才智, ...

  2. R语言作为BI中ETL的工具

    R语言作为BI中ETL的工具,增删改 R语言提供了强大的R_package与各种数据库进行数据交互. 外加其强大数据变换清洗函数,为ETL提供一条方便快捷的道路. RODBC ROracal RMys ...

  3. iOS开发小技巧--微博项目中的键盘工具条

    微博项目中的键盘工具条 项目中的键盘工具条不能使用inputAccessoryView,因为inputAccessoryView不能实现键盘隐藏的时候,工具条还显示在眼前,如图: 所以,果断决定将工具 ...

  4. qml中打开本地html

    main.cpp QString tmploc = QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation); QDi ...

  5. MAPINFO中利用GridMaker工具创建栅格图层

    在工作中需要使用栅格地图,以往都是由研发人员来创建,今天偶然发现Mapinfo中有GridMaker这样一个工具,结合网络搜索自己试了一下,居然做成功了,这里把步骤记录下来,方便以后查看. 1.首先在 ...

  6. java中常用的工具类(一)

    我们java程序员在开发项目的是常常会用到一些工具类.今天我汇总了一下java中常用的工具方法.大家可以在项目中使用.可以收藏!加入IT江湖官方群:383126909 我们一起成长 一.String工 ...

  7. Engine中执行gp工具返回的要素图层如何获取?

    来自:http://zhihu.esrichina.com.cn/?/question/12087 Engine中执行gp工具返回的[解决办法]:需要用gpUtils.DecodeFeatureLay ...

  8. 在 virtualbox 的 centos7 虚拟机中安装增强工具

    在 virtualbox 的 centos7 虚拟机中安装增强工具 centos7 刚刚安装完成时,直接安装 virtualbox 增强工具会出错,需要先把 gcc / kernel-devel / ...

  9. JAVA中封装JSONUtils工具类及使用

    在JAVA中用json-lib-2.3-jdk15.jar包中提供了JSONObject和JSONArray基类,用于JSON的序列化和反序列化的操作.但是我们更习惯将其进一步封装,达到更好的重用. ...

  10. 在VS2103环境中集成Doxygen工具

    自己已将学习了两三次了吧,差不多这次该总结一下: Doxygen是一种开源跨平台的,以类似JavaDoc风格描述的文档系统,完全支持C.C++.Java.Objective-C和IDL语言,部分支持P ...

随机推荐

  1. Whizard:跨越 Thanos 从开源项目到生产就绪的鸿沟

    此文是根据 KubeSphere 在 KubeCon China 2024 上的演讲分享整理而成. 议题简介 作为最受欢迎和强大的 Prometheus 长期存储项目之一,Thanos 被社区广泛采用 ...

  2. 云原生爱好者周刊:开源替代品开始围剿 Docker Desktop

    云原生一周动态要闻: Docker 更新和扩展了产品订阅 NGINX Ingress Controller 1.0.0 发布 Tanzu 应用平台的公开测试版发布 IBM 开源 Tornjak Kub ...

  3. Unreal RecastNavigation 开源项目详解

    0 前言 Recastnavigation是一个游戏AI导航库,像Unity,UE引擎中都集成了这个开源项目, HALO中使用的也是这个开源库.导航最重要的就是为NPC寻路,以及其他的寻路需求. 需要 ...

  4. 基于pandas的数据清洗

    数据清洗是数据科学和数据分析中非常重要的一个步骤.它指的是在数据分析之前,对数据进行预处理,以确保数据的质量和一致性.使用Python的pandas库进行数据清洗是一种常见的做法,因为pandas提供 ...

  5. Next.js 实战开发入门 1 开发环境部署 - 曲速引擎 Warp Drive

    开发目标 我们将构建一个简化版本的财务仪表板,其内容包括:公共主页.登录页面.受身份验证保护的仪表板页面.用户可以添加.编辑和删除发票 开发环境配置 开发客户端 Windows 10 (不限系统,兼容 ...

  6. git安装-Tortoise git 安装汉化教程

    1.首先下载 去官网下载 如果下载比较慢的,链接自取 https://pan.quark.cn/s/fcb9d0b39c7f 2. 安装git 3. 安装git图形化工具Tortoise git 4. ...

  7. QT中的宏定义

    1.操作系统宏 //在<QtGlobal>中,定义了各个系统的宏定义 //Defined on AIX. #ifdef Q_OS_AIX // Defined on Android. #d ...

  8. 开源 - Ideal库 - 常用时间转换扩展方法(二)

    书接上回,我们继续来分享一些关于时间转换的常用扩展方法. 01.时间转日期时间 TimeOnly 该方式是把TimeOnly类型转为DateTime类型,其中日期部分使用系统当前日期,时间部分则使用T ...

  9. 推荐7款程序员常用的API管理工具

    前言 现如今API接口的编写与调试已成为开发人员不可或缺的技能,工欲善其事,必先利其器,选择一款优秀的API管理工具显得尤为重要.本文大姚给大家推荐7款程序员常用的API管理工具,大家可以根据自身和团 ...

  10. .NET Core 特性(Attribute)底层原理浅谈

    简介 烂大街的资料不再赘述,简单来说就是给代码看的注释 Attribute的使用场景 Attribute不仅仅局限于C#中,在整个.NET框架中都提供了非常大的拓展点,任何地方都有Attribute的 ...