亞克力效果的實現思路
上一篇博客《如何在pyqt中實現窗口磨砂效果》 中實現了win7中的Aero效果,但是和win10的亞克力效果相比,Aero還是差了點內味。所以今天早上又在網上搜了一圈,無意中發現了這篇博客《使用 SetWindowCompositionAttribute 來控制程序的窗口邊框和背景》,點進去認真看了一遍之后深受啟發,於是又去改了一下上次實現Aero效果時所用的函數,重新編譯為dll給python調用,需要注意的是,要想成功使用編譯好的dll必須在Visual Studio里面裝好C++,如果不想裝的話可以參見《如何在pyqt中通過調用SetWindowCompositionAttribute實現Win10亞克力效果》,這里面用純Python的方法實現了亞克力效果。
具體實現流程
- 在
WindowCompositionAttribute.h
的枚舉類ACCENT_STATE
中新增一個ACCENT_ENABLE_ACRYLICBLURBEHIND
參數,初值為4; - 定義setBlur()函數的時候,
ACCENT_POLICY accent = { ACCENT_ENABLE_ACRYLICBLURBEHIND, 0, gradientColor, 0 }
,和上次相比列表的第一個參數變成了ACCENT_ENABLE_ACRYLICBLURBEHIND
,第三個參數由0變為了gradientColor
,這個參數用來設置窗口的背景色; - 在VS2019里面把寫好的函數編譯為
acrylic.dll
; - 在python中通過
hWnd=ctypes.wintypes.HWND(int(self.winId()))
,把WId類型強制轉換為HWND類型,接着設置背景色gradientColor = DWORD(0x50F2F2F2)
,0x50F2F2F2
的前兩位是透明度,后面六位是bgr,最后ctypes.cdll.LoadLibrary('acrylic_dll\\acrylic.dll').setBlur(hWnd,gradientColor)
,實現動態鏈接庫的載入和接口函數的調用,源代碼如下:
import sys
from ctypes import cdll
from ctypes.wintypes import HWND, DWORD
from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import QApplication, QWidget
class Demo(QWidget):
""" 亞克力效果的實現 """
def __init__(self):
super().__init__()
self.resize(500, 500)
# 去除邊框,沒有這一步的話窗口陰影也會加上亞克力效果
self.setWindowFlags(Qt.FramelessWindowHint)
# 背景透明
self.setAttribute(Qt.WA_TranslucentBackground)
# 調用api
hWnd = HWND(int(self.winId())) # 直接HWND(self.winId())會報錯
gradientColor = DWORD(0x50F2F2F2) # 設置和亞克力效果相疊加的背景顏色
cdll.LoadLibrary('acrylic_dll\\acrylic.dll').setBlur(hWnd, gradientColor)
if __name__ == "__main__":
app = QApplication(sys.argv)
demo = Demo()
demo.show()
sys.exit(app.exec_())
運行效果如下(硝子依舊如此美麗٩(๑>◡<๑)۶)

源代碼以及dll
百度網盤(提取碼:2la9):鏈接