Qt預設的QDialog和QWidget都帶有邊框和標題列。如何實現一個不帶有標題列的邊框,並且邊框帶有陰影效果。其實很簡單,我們只需要自定義QDialog類,然後實現重繪事件即可。
效果圖如下所示(四周有陰影效果):
Windows系統:Windows10
Qt版本:Qt5.15或者Qt6
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);
}
}
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();
}
下載:【Qt】仿360安全衛士介面(自定義陰影邊框類).rar
6.1 Qt教學彙總
網址:https://dengjin.blog.csdn.net/article/details/115174639