基于Qml實(shí)現(xiàn)水印工具
寫在前面
在 Qt 的 Quick 模塊中,QQuickPaintedItem 是一個(gè)非常有用的類,它允許我們?cè)?Qml 中自定義繪制邏輯。
我們可以通過這種方式實(shí)現(xiàn)水印工具,包括在文本、圖片或整個(gè)窗口上添加水印。
本文將介紹如何在 Qml 中實(shí)現(xiàn)一個(gè)簡單但功能強(qiáng)大的水印工具,包括水印文本的透明度、顏色、字體大小、旋轉(zhuǎn)角度等自定義功能。
一、效果圖

二、水印工具類的設(shè)計(jì)
首先,我們需要設(shè)計(jì)一個(gè) C++ 類來表示水印工具。這個(gè)類將繼承自 QQuickPaintedItem,并添加一些屬性來控制水印的外觀和行為。這些屬性包括水印文本、圖像、大小、間距、偏移量、旋轉(zhuǎn)角度、字體和字體顏色。
watermark.h
在 Watermark 類的頭文件中,我們聲明了所有的屬性和相應(yīng)的信號(hào)、槽函數(shù)。使用 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函數(shù)
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 類的實(shí)現(xiàn)文件中,我們主要實(shí)現(xiàn)了屬性的 setter 和 getter 函數(shù),這些函數(shù)在屬性值改變時(shí)會(huì)觸發(fā)相應(yīng)的信號(hào),并調(diào)用update()函數(shù)來請(qǐng)求重新繪制。同時(shí),我們也實(shí)現(xiàn)了paint()函數(shù),它使用 QPainter 來繪制水印。
// watermark.cpp的實(shí)現(xiàn)省略,具體可參考提供的 watermark.cpp 文件
WatermarkPrivate.h
WatermarkPrivate 是 Watermark 類的私有實(shí)現(xiàn)部分,它包含了所有的成員變量和輔助函數(shù)。這些成員變量包括水印文本、圖像URL、網(wǎng)絡(luò)請(qǐng)求回復(fù)、圖像緩存、字體和字體顏色等。
// WatermarkPrivate類的聲明省略,具體可參考watermark.cpp文件中的WatermarkPrivate部分
三、 Qml 中的使用
main.qml
在 Qml 文件中,我們可以使用 Watermark 元素來添加水印。通過設(shè)置 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("導(dǎo)出")
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("導(dǎo)出")
onClicked: {
content2.grabToImage((result)=>{
result.saveToFile("./content2.png");
Qt.openUrlExternally("file:./");
});
}
}
}
}
}
}
在這個(gè) Qml 文件中,我們創(chuàng)建了兩個(gè)個(gè) Watermark 元素并通過設(shè)置 Watermark 的各種屬性,我們實(shí)現(xiàn)了一個(gè)帶有文本和圖像的水印效果,并且可以控制水印的大小、間距、偏移量、旋轉(zhuǎn)角度、字體和字體顏色。
到此這篇關(guān)于基于Qml實(shí)現(xiàn)水印工具的文章就介紹到這了,更多相關(guān)Qml水印內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- Qt6 QML實(shí)現(xiàn)DateTimePicker組件的示例代碼
- Qt?QML實(shí)現(xiàn)無邊框窗口的實(shí)例代碼
- QML與C++交互之創(chuàng)建自定義對(duì)象的實(shí)現(xiàn)
- Qt6+QML實(shí)現(xiàn)Windows屏幕錄制功能
- Qt?Qml實(shí)現(xiàn)毛玻璃效果
- Qt qml實(shí)現(xiàn)動(dòng)態(tài)輪播圖效果
- QML與C++幾種交互方式
- Qt QML使用虛擬鍵盤的示例代碼
- C++與QML進(jìn)行數(shù)據(jù)交互的常見方法總結(jié)
- C++與QML交互的項(xiàng)目實(shí)踐
- Qt6 QML Flickable控件詳解
相關(guān)文章
C++數(shù)據(jù)結(jié)構(gòu)AVL樹全面分析
今天的這一篇博客,我要跟大家介紹一顆樹——AVL樹,它也是一顆二叉搜索樹,它就是在二叉搜索樹中加了一個(gè)平衡因子的概念在里面,下面我就來和大家聊一聊這棵樹是個(gè)怎么樣的樹2021-10-10
C++中基類和派生類之間的轉(zhuǎn)換實(shí)例教程
這篇文章主要介紹了C++中基類和派生類之間的轉(zhuǎn)換,有助于深入理解C++面向?qū)ο蟪绦蛟O(shè)計(jì),需要的朋友可以參考下2014-08-08
使用C++ Matlab中的lp2lp函數(shù)教程詳解
本文介紹如何使用C++編寫數(shù)字濾波器設(shè)計(jì)算法,實(shí)現(xiàn)Matlab中的lp2lp函數(shù),將低通濾波器轉(zhuǎn)換為參數(shù)化的低通濾波器,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)吧2023-04-04
OpenCV實(shí)現(xiàn)幀差法檢測運(yùn)動(dòng)目標(biāo)
這篇文章主要為大家詳細(xì)介紹了OpenCV實(shí)現(xiàn)幀差法檢測運(yùn)動(dòng)目標(biāo),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-03-03

