Qml 中实现水印工具
【写在前面】
在 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 类的实现文件中,我们主要实现了属性的 setter 和 getter 函数,这些函数在属性值改变时会触发相应的信号,并调用update()函数来请求重新绘制。同时,我们也实现了paint()函数,它使用 QPainter 来绘制水印。
// watermark.cpp的实现省略,具体可参考提供的 watermark.cpp 文件
WatermarkPrivate.h
WatermarkPrivate 是 Watermark 类的私有实现部分,它包含了所有的成员变量和辅助函数。这些成员变量包括水印文本、图像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 中实现水印工具的更多相关文章
- qml 中 使用 shader
使用绘制工具如Photoshop .Flash已经可以创建许多效果非常绚丽的图像.动画等. Qt/QML 的努力其实是在这些工具发展的后面, 因此很多效果在Qt中无法实现. 不得不佩服Qt小组的才智, ...
- R语言作为BI中ETL的工具
R语言作为BI中ETL的工具,增删改 R语言提供了强大的R_package与各种数据库进行数据交互. 外加其强大数据变换清洗函数,为ETL提供一条方便快捷的道路. RODBC ROracal RMys ...
- iOS开发小技巧--微博项目中的键盘工具条
微博项目中的键盘工具条 项目中的键盘工具条不能使用inputAccessoryView,因为inputAccessoryView不能实现键盘隐藏的时候,工具条还显示在眼前,如图: 所以,果断决定将工具 ...
- qml中打开本地html
main.cpp QString tmploc = QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation); QDi ...
- MAPINFO中利用GridMaker工具创建栅格图层
在工作中需要使用栅格地图,以往都是由研发人员来创建,今天偶然发现Mapinfo中有GridMaker这样一个工具,结合网络搜索自己试了一下,居然做成功了,这里把步骤记录下来,方便以后查看. 1.首先在 ...
- java中常用的工具类(一)
我们java程序员在开发项目的是常常会用到一些工具类.今天我汇总了一下java中常用的工具方法.大家可以在项目中使用.可以收藏!加入IT江湖官方群:383126909 我们一起成长 一.String工 ...
- Engine中执行gp工具返回的要素图层如何获取?
来自:http://zhihu.esrichina.com.cn/?/question/12087 Engine中执行gp工具返回的[解决办法]:需要用gpUtils.DecodeFeatureLay ...
- 在 virtualbox 的 centos7 虚拟机中安装增强工具
在 virtualbox 的 centos7 虚拟机中安装增强工具 centos7 刚刚安装完成时,直接安装 virtualbox 增强工具会出错,需要先把 gcc / kernel-devel / ...
- JAVA中封装JSONUtils工具类及使用
在JAVA中用json-lib-2.3-jdk15.jar包中提供了JSONObject和JSONArray基类,用于JSON的序列化和反序列化的操作.但是我们更习惯将其进一步封装,达到更好的重用. ...
- 在VS2103环境中集成Doxygen工具
自己已将学习了两三次了吧,差不多这次该总结一下: Doxygen是一种开源跨平台的,以类似JavaDoc风格描述的文档系统,完全支持C.C++.Java.Objective-C和IDL语言,部分支持P ...
随机推荐
- 详解 JuiceFS 在多云架构下的数据同步与一致性
随着大模型流行,GPU 算力资源正变得日益稀缺,传统的"算力跟着存储跑"的策略需要转变为"存储跟着算力跑".为了确保数据一致性和管理的便捷性,企业通常在特定地区 ...
- Nginx 反向代理 (泛域名->泛域名,https,静态文件)
Nginx 反向代理配置指南 (泛域名 -> 泛域名, HTTPS, 静态文件) 完整版 server { # 监听80端口 listen 80; listen 443 ssl http2;; ...
- 一文解秘Rust如何与Java互操作
本博客所有文章除特别声明外,均采用CC BY-NC-SA 4.0许可协议.转载请注明来自 唯你 使用场景 JAVA 与 Rust 互操作让 Rust 可以背靠 Java 大生态来做更多事情,而 Jav ...
- 2个月搞定计算机二级C语言——真题(10)解析
1. 前言 本篇我们讲解2个月搞定计算机二级C语言--真题10 2. 程序填空题 2.1 题目要求 2.2 提供的代码 #include <stdio.h> #pragma warning ...
- delphi Image 32 动画演示1
Image 32 自带的Demo,添加一些注解. unit uFrmAnimation; interface uses Winapi.Windows, Winapi.Messages, System. ...
- Python 在PDF中绘制线条、矩形、椭圆形
在PDF中绘制图形可以增强文档的视觉效果.通过添加不同类型的形状,如实线.虚线.矩形.圆形等,可以使文档更加生动有趣,提高读者的阅读兴趣.这对于制作报告.演示文稿或是教材特别有用.本文将通过以下几个示 ...
- po文件如何转为excel
其实.po文件是一种翻译文件格式,类似于 key - value的列表 可以理解为两列,由于我们想把这个po数据读出来放入 excel.因为大部分人看不懂po文件的.虽然我们可以借助工具 poedit ...
- Python中函数或者类对象带()与不带()的区别——闭包和函数返回时的常见现象
Python中函数或者类对象带()与不带()的区别-----闭包和函数返回时的常见现象 - 函数不带括号时,调用的是这个函数本身 ,是整个函数体,是一个函数对象,不需等该函数执行完成,返回一个已定义函 ...
- http: server gave HTTP response to HTTPS client
出现这问题的原因是:Docker自从1.3.X之后docker registry交互默认使用的是HTTPS,但是搭建私有镜像默认使用的是HTTP服务,所以与私有镜像交时出现以上错误. 这个报错是在本地 ...
- linux学习用到的命令
创建快件方式 ln 创建目录的快件方式 sudo ln -s /root/myhack/ /root/Desktop以上指令是创建软链接到桌面. ln -s /mnt/hgfs/VMware_shar ...