【Qt】仿360安全衛士介面(自定義陰影邊框類)

2022-01-13 22:00:07

00. 目錄

01. 概述

Qt預設的QDialog和QWidget都帶有邊框和標題列。如何實現一個不帶有標題列的邊框,並且邊框帶有陰影效果。其實很簡單,我們只需要自定義QDialog類,然後實現重繪事件即可。

效果圖如下所示(四周有陰影效果):
在這裡插入圖片描述

02. 開發環境

Windows系統:Windows10

Qt版本:Qt5.15或者Qt6

03. 自定義陰影邊框類設計與實現

shadowborderwidget.h

#ifndef SHADOWBORDERWIDGET_H
#define SHADOWBORDERWIDGET_H

#include <QDialog>
#include <QWidget>
#include <QMouseEvent>
#include <QPaintEvent>
#include <QPainterPath>
#include <QPainter>
#include <QtMath>


// 陰影邊框

class ShadowBorderWidget : public QDialog
{
    Q_OBJECT
public:
    //建構函式
    explicit ShadowBorderWidget(QWidget *parent = 0);
    //解構函式
    ~ShadowBorderWidget();

    // QWidget interface
protected:
    virtual void mousePressEvent(QMouseEvent *event);
    virtual void mouseReleaseEvent(QMouseEvent *event);
    virtual void mouseMoveEvent(QMouseEvent *event);
    virtual void paintEvent(QPaintEvent *event);

private:
    QPoint movePoint;       //移動的點
    bool isMousePressed;    //滑鼠左鍵是否按下


};

#endif // SHADOWBORDERWIDGET_H

shadowborderwidget.cpp

#include "shadowborderwidget.h"

/*
可以檢視幫助檔案:
void setWindowFlags ( Qt::WindowFlags type )
可以檢視demo/example:
Window Flags Example.

this->setWindowFlags(Qt::Dialog | Qt::WindowMinimizeButtonHint);

setWindowFlags ( Qt::WindowFlags type )
Qt::FrameWindowHint:沒有邊框的視窗
Qt::WindowStaysOnTopHint://總在最上面的視窗
Qt::CustomizeWindowHint://自定義視窗標題列,以下標誌必須與這個標誌一起使用才有效,
否則視窗將有預設的標題列
Qt::WindowTitleHint:顯示視窗標題列
Qt::WindowSystemMenuHint://顯示系統選單
Qt::WindowMinimizeButtonHint://顯示最小化按鈕
Qt::WindowMaximizeButtonHint://顯示最大化按鈕
Qt::WindowMinMaxButtonsHint://顯示最小化按鈕和最大化按鈕
Qt::WindowCloseButtonHint://顯示關閉按鈕

Qt::Drawer://去掉視窗左上角的圖示,右上角的最大化最小化按鈕

------解決方案--------------------
setWindowFlags(Qt::FramelessWindowHint);直接隱藏掉。。。

*/


//建構函式
ShadowBorderWidget::ShadowBorderWidget(QWidget *parent):QDialog(parent)
{
    //設定無邊框
    setWindowFlags(Qt::FramelessWindowHint | Qt::Dialog);

    //設定半透明背景
    setAttribute(Qt::WA_TranslucentBackground);

    //預設滑鼠左鍵沒有按下
    isMousePressed = false;

}

//解構函式
ShadowBorderWidget::~ShadowBorderWidget()
{

}


//滑鼠按下事件
void ShadowBorderWidget::mousePressEvent(QMouseEvent *event)
{
    //滑鼠左鍵移動和改變大小
    if (event->button() == Qt::LeftButton)
    {
        isMousePressed = true;
    }

    //視窗移動的距離
    movePoint = event->globalPos() - pos();
}


//滑鼠釋放事件
void ShadowBorderWidget::mouseReleaseEvent(QMouseEvent *)
{
    isMousePressed = false;
}

//滑鼠移動事件
void ShadowBorderWidget::mouseMoveEvent(QMouseEvent *event)
{
    //滑鼠是否按下
    if (isMousePressed)
    {
        QPoint movePos = event->globalPos();
        move(movePos - movePoint);
    }
}


//重繪事件  設定陰影效果
void ShadowBorderWidget::paintEvent(QPaintEvent *)
{

    QPainterPath path;
    path.setFillRule(Qt::WindingFill);
    path.addRect(10, 10, this->width() - 20, this->height() - 20);

    QPainter painter(this);
    painter.setRenderHint(QPainter::Antialiasing, true);
    painter.fillPath(path, QBrush(Qt::white));

    QColor color(0, 0, 0, 50);
    for (int i = 0; i < 10; i++)
    {
        QPainterPath path;
        path.setFillRule(Qt::WindingFill);
        path.addRect(10 - i, 10 - i, width() - (10 - i) * 2, height() 
        - (10 - i) * 2);
        color.setAlpha(150 - qSqrt(i) * 50);
        painter.setPen(color);
        painter.drawPath(path);
    }
}

04. 測試程式碼

main.cpp

#include "widget.h"
#include "shadowborderwidget.h"

#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);

    ShadowBorderWidget *w1 = new ShadowBorderWidget;
    w1->show();


    return a.exec();
}

05. 範例下載

下載:【Qt】仿360安全衛士介面(自定義陰影邊框類).rar

06. 附錄

6.1 Qt教學彙總
網址:https://dengjin.blog.csdn.net/article/details/115174639