动态

详情 返回 返回

Qml 中實現水印工具 - 动态 详情

【寫在前面】

在 Qt 的 Quick 模塊中,QQuickPaintedItem 是一個非常有用的類,它允許我們在 Qml 中自定義繪製邏輯。

我們可以通過這種方式實現水印工具,包括在文本、圖片或整個窗口上添加水印。

本文將介紹如何在 Qml 中實現一個簡單但功能強大的水印工具,包括水印文本的透明度、顏色、字體大小、旋轉角度等自定義功能。


【正文開始】

一、效果圖

image

二、水印工具類的設計

首先,我們需要設計一個 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

user avatar sihaihande 头像 zego 头像 shaogongbra 头像 ospo 头像
点赞 4 用户, 点赞了这篇动态!
点赞

Add a new 评论

Some HTML is okay.