English 简体中文 繁體中文 한국 사람 日本語 Deutsch русский بالعربية TÜRKÇE português คนไทย french
查看: 2|回复: 0

Qml 中实现水印工具

[复制链接]
查看: 2|回复: 0

Qml 中实现水印工具

[复制链接]
查看: 2|回复: 0

392

主题

0

回帖

1184

积分

管理员

积分
1184
溯源设备

392

主题

0

回帖

1184

积分

管理员

积分
1184
2025-2-7 00:35:55 | 显示全部楼层 |阅读模式
【写在前面】

在 Qt 的 Quick 模块中,QQuickPaintedItem 是一个非常有用的类,它允许我们在 Qml 中自定义绘制逻辑。
我们可以通过这种方式实现水印工具,包括在文本、图片或整个窗口上添加水印。
本文将介绍如何在 Qml 中实现一个简单但功能强大的水印工具,包括水印文本的透明度、颜色、字体大小、旋转角度等自定义功能。
<hr>【正文开始】

一、效果图


二、水印工具类的设计

首先,我们需要设计一个 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_Hwatermark.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.15import QtQuick.Controls 2.15import QtQuick.Window 2.15import QtQuick.Layouts 1.15import DelegateUI.Controls 1.0Window {    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 的各种属性,我们实现了一个带有文本和图像的水印效果,并且可以控制水印的大小、间距、偏移量、旋转角度、字体和字体颜色。
<hr>【结语】

通过使用 QQuickPaintedItem,我们可以在 Qml 中实现了一个功能丰富的水印工具。
这个工具允许我们自定义水印的外观和行为,并且可以很方便地在 Qml 中使用。
最后:项目链接(多多star呀..⭐_⭐):
Github: https://github.com/mengps/QmlControls
Gitee: https://gitee.com/MenPenS/QmlControls
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|智能设备 | 粤ICP备2024353841号-1

GMT+8, 2025-3-10 15:04 , Processed in 0.801320 second(s), 30 queries .

Powered by 智能设备

©2025

|网站地图