基于Qml实现水印工具

 更新时间:2024年12月30日 08:24:50   作者:梦起丶  
这篇文章主要介绍了如何在 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 的各种属性,我们实现了一个带有文本和图像的水印效果,并且可以控制水印的大小、间距、偏移量、旋转角度、字体和字体颜色。

到此这篇关于基于Qml实现水印工具的文章就介绍到这了,更多相关Qml水印内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Dijkstra最短路径算法实现代码

    Dijkstra最短路径算法实现代码

    这篇文章主要介绍了Dijkstra最短路径算法实现代码,有需要的朋友可以参考一下
    2013-12-12
  • C++指针运算符(&和*)的实现

    C++指针运算符(&和*)的实现

    C++ 提供了两种指针运算符,一种是取地址运算符 &,一种是间接寻址运算符 *,本文就详细的介绍一下这两种运算符的使用,具有一定的参考价值,感兴趣的可以了解一下
    2023-08-08
  • C语言实现图书管理系统(文件数据库)

    C语言实现图书管理系统(文件数据库)

    这篇文章主要为大家详细介绍了C语言实现图书管理系统,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-03-03
  • C++ std::chrono库使用示例(实现C++ 获取日期,时间戳,计时等功能)

    C++ std::chrono库使用示例(实现C++ 获取日期,时间戳,计时等功能)

    std::chrono是C++标准库中的一个组件,用于表示和处理时间,这篇文章主要介绍了C++ std::chrono库使用指南(实现C++ 获取日期,时间戳,计时等功能),需要的朋友可以参考下
    2023-06-06
  • QT实战之实现图片浏览系统

    QT实战之实现图片浏览系统

    这篇文章主要介绍了如何利用QT编写一个图片浏览系统,可以支持自动播放,左右拖动切换,点击列表切换,点击按钮切换等功能,感兴趣的小伙伴可以跟随小编一起了解一下
    2023-04-04
  • C++ 学习之旅三 我和超级玛丽有个约会

    C++ 学习之旅三 我和超级玛丽有个约会

    学习了c++有一周有余了吧,感谢孙鑫老师的视频教程,让我   对C++有了基本的了解,并理解到C++与.net 的许许多多的区别,更要感谢网民为programaking的人,会为我提供了超级玛丽制作揭秘 这套宝贵的教程,让我 做做出了这个项目,对c++ 有了一个更深层次的认识
    2012-11-11
  • C语言俄罗斯方块游戏课程设计

    C语言俄罗斯方块游戏课程设计

    这篇文章主要为大家详细介绍了C语言俄罗斯方块游戏课程设计,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-06-06
  • C语言实现电影管理系统

    C语言实现电影管理系统

    这篇文章主要为大家详细介绍了C语言实现电影管理系统,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-08-08
  • C语言简明讲解队列的实现方法

    C语言简明讲解队列的实现方法

    队列(Queue)与栈一样,是一种线性存储结构,它具有如下特点:队列中的数据元素遵循“先进先出”(First In First Out)的原则,简称FIFO结构。在队尾添加元素,在队头删除元素
    2022-04-04
  • C语言实现扫雷附完整代码

    C语言实现扫雷附完整代码

    本文详细讲解了C语言实现扫雷并附完整代码,文中通过示例代码介绍的非常详细。对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-11-11

最新评论