Qml 中实现水印工具

【写在前面】

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

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

本文将介绍如何在 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

发表评论

相关文章