QT实现屏幕水印技术方案
新建qt工程,在主函数加入以下代码:
int main(int argc, char *argv[])
{
/*对高分屏不同缩放比例的自适应处理方法 */
qputenv("QT_ENABLE_HIGHDPI_SCALING", "1");
QGuiApplication::setHighDpiScaleFactorRoundingPolicy(Qt::HighDpiScaleFactorRoundingPolicy::PassThrough);
QApplication a(argc, argv);
QScreen *screen = qApp->primaryScreen();
int nWidth2 = screen->size().width(); //屏幕宽
int nHeight2 = screen→size().height(); //屏幕高
Widget w;
w.resize(nWidth2, nHeight2);
w.setWindowFlags(Qt::WindowTransparentForInput | Qt::Tool | Qt::X11BypassWindowManagerHint | Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint);
w.setAttribute(Qt::WA_TranslucentBackground);
w.setAttribute(Qt::WA_TransparentForMouseEvents);
w.show();
return a.exec();
}
Qt::FramelessWindowHint 实现无边框;
Qt::WindowStaysOnTopHint 实现置顶;
Qt::WindowTransparentForInput 实现输入穿透;
Qt::Tool 实现悬浮;
Qt::X11BypassWindowManagerHint 实现不显示在任务栏中;
Qt::WA_TranslucentBackground 实现背景透明;
Qt::WA_TransparentForMouseEvents 实现子窗口输入穿透。
在Widget定义文件中重新实现paintEvent事件函数,在此函数中绘制水印
void Widget::paintEvent(QPaintEvent *event)
{
setWindowOpacity(0.6); //设置水印透明度
QFont font;
font.setFamily("Microsoft YaHei");
font.setPointSize(14);
font.setItalic(true);
watermark_width_ = 200;
watermark_height_ = 300;
watermark_inclination_angle_ = 45.0;
QString content = QString("%1 %2 %3 %4").arg("zhangsan*&^%$#@!~(,/.';)").arg("192.168.45.123").arg("\n").arg(QDateTime::currentDateTime().toString("yyyy-MM-dd HH:mm:ss"));
qreal ang = -watermark_inclination_angle_; //逆时针旋转
QScreen *screen = qApp->primaryScreen();
int width= screen->size().width();
int height= screen->size().height();
int project_Y = abs(this->width() * sin(ang)) + abs(this->height() * sin(ang));//原图像Y坐标在新坐标系Y轴上的投影长度
int project_X = abs(this->height()*sin(ang)) + abs(this->width()*cos(ang));//原图像x坐标在新坐标系x轴上的投影长度
int x_step = watermark_width_;
int y_step = watermark_height_;
int row_count= width/ y_step;//水印写多少行
int col_count= height/ x_step + 10;//水印写多少列 因为旋转了,如果不多加会导致水印缺少一块
for (int r = 0; r < row_count; r++)
{
for (int c = 0; c < col_count; c++)
{
QPainter p(this);
p.setFont(font);
p.setPen("#F50808");
p.translate(x_step * c, y_step * r);
p.rotate(ang);
p.drawText(QRect(0, 0, watermark_width_, watermark_height_), Qt::TextWordWrap, content);
}
}
}
可以通过定时调用repaint()实现绘图重绘
void Widget::slotUpdateWaterMark()
{
//刷新窗口,让整个窗口重绘 间接调用paintEvent();
repaint();
}
最终效果