【写在前面】

在 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. Machine Learning Week_7 Support Vector Machines

    目录 1 Large Margin Classification 1.1 Optimization Objective 1.1 Logistic Regresson 1.2 Cost 1.3 Supp ...

  2. NDT论文翻译

    The Normal Distributions Transform: A New Approach to Laser Scan Matching 正态分布变换:激光扫描匹配的新方法 摘要:匹配 2D ...

  3. 腾讯云禁止root用户登录

    背景 买了腾讯云的云主机服务,装的 OpenCloudOS 系统,结果没几天就提示异常登录和恶意文件.结果还改了我的密码,导致我xshell登陆不了,通过腾讯云后台登进去发现有挖矿病毒,但还没完全跑起 ...

  4. 基于surging的木舟平台如何构建起微服务

    一.概述 木舟平台分为微服务平台和物联网平台, 上面几篇都是介绍如何通过网络组件接入设备,那么此篇文章就细致介绍下在木舟平台下如何构建微服务. 木舟 (Kayak) 是什么? 木舟(Kayak)是基于 ...

  5. 拯救php性能的神器webman-数据库

    有了webman的这个框架,我们得看看它是怎么使用数据库的,毕竟我们不能一直用内存变量啊. 好,很简单一句话跑起来. composer require -W illuminate/database i ...

  6. python 爬虫基本玩法,统计杭电oj题目正确率并排序

    python爬虫主要用两个库:Urllib和BeautifulSoup4.一个用来爬取网页,一个用来解析网页. Urllib是Python内置的HTTP请求库,它包含四个模块: 1.request,最 ...

  7. (Redis基础教程之十三) 如何从命令行更改Redis的配置

    介绍 Redis是一个开源的内存中键值数据存储.Redis有几个命令,可让您即时更改Redis服务器的配置设置.本教程将介绍其中一些命令,并说明如何使这些配置更改永久生效. 如何使用本指南 本指南以备 ...

  8. JAVA并发编程学习笔记之CLH队列锁

    NUMA与SMP SMP(Symmetric Multi-Processor),即对称多处理器结构,指服务器中多个CPU对称工作,每个CPU访问内存地址所需时间相同.其主要特征是共享,包含对CPU,内 ...

  9. SoftReference,WeakReference&WeakHashMap

    zz http://java.chinaitlab.com/oop/716371.html 在JDK1.2以前的版本中,当一个对象不被任何变量引用,那么程序就无法再使用这个对象.也就是说,只有对象处于 ...

  10. nginx之常见错误

    在此只介绍源码安装nginx的时候,发生的一些常见的错误 1. nginx访问出现File not found 1) php-fpm找不到SCRIPT_FILENAME中执行的PHP文件 更改配置文件 ...