Skip to content

Instantly share code, notes, and snippets.

@downthecrop
Created March 15, 2025 12:23
Show Gist options
  • Save downthecrop/6ca9945691a1e1d03e6345674e31c6c4 to your computer and use it in GitHub Desktop.
Save downthecrop/6ca9945691a1e1d03e6345674e31c6c4 to your computer and use it in GitHub Desktop.
from PyQt-Frameless-Window
# coding:utf-8
import sys
import objc
import Cocoa
from ctypes import c_void_p
from PyQt6.QtWidgets import QApplication, QMainWindow, QWidget, QVBoxLayout, QLabel
from PyQt6.QtCore import Qt, QTimer
def getNSWindow(winId):
""" Convert window handle to NSWindow """
view = objc.objc_object(c_void_p=c_void_p(int(winId)))
return view.window()
class MacWindowEffect:
""" Mac OS window effect """
def __init__(self, window):
self.window = window
def setAcrylicEffect(self):
""" Set acrylic effect for window """
# Get window dimensions
frame = Cocoa.NSMakeRect(0, 0, self.window.width(), self.window.height())
# Create visual effect view
visualEffectView = Cocoa.NSVisualEffectView.alloc().initWithFrame_(frame)
visualEffectView.setAutoresizingMask_(
Cocoa.NSViewWidthSizable | Cocoa.NSViewHeightSizable)
visualEffectView.setFrame_(frame)
visualEffectView.setState_(Cocoa.NSVisualEffectStateActive)
# Set material and blending mode (using Popover material for a nice acrylic look)
visualEffectView.setMaterial_(Cocoa.NSVisualEffectMaterialPopover)
visualEffectView.setBlendingMode_(Cocoa.NSVisualEffectBlendingModeBehindWindow)
# Get NSWindow and content view
nsWindow = getNSWindow(self.window.winId())
# Enable shadow
nsWindow.setHasShadow_(True)
# Make window background transparent
nsWindow.setBackgroundColor_(Cocoa.NSColor.clearColor())
nsWindow.setOpaque_(False)
# Add the visual effect view to the content view
contentView = nsWindow.contentView()
contentView.addSubview_positioned_relativeTo_(
visualEffectView, Cocoa.NSWindowBelow, None)
class AcrylicWindow(QMainWindow):
def __init__(self):
super().__init__()
# Set window properties
self.setWindowTitle('PyQt6 Acrylic Window')
self.setGeometry(100, 100, 500, 300)
self.setAttribute(Qt.WidgetAttribute.WA_TranslucentBackground)
# Create layout and widgets
central_widget = QWidget()
self.setCentralWidget(central_widget)
layout = QVBoxLayout(central_widget)
layout.setContentsMargins(20, 20, 20, 20)
# Add content
label = QLabel('PyQt6 Window with Acrylic Effect on macOS')
label.setStyleSheet('color: black; font-size: 18px;')
label.setAlignment(Qt.AlignmentFlag.AlignCenter)
layout.addWidget(label)
def showEvent(self, event):
""" Apply acrylic effect when window is shown """
super().showEvent(event)
# Use a timer to ensure the window is fully rendered before applying effect
QTimer.singleShot(100, self.applyEffect)
def applyEffect(self):
""" Apply the acrylic effect """
effect = MacWindowEffect(self)
effect.setAcrylicEffect()
def main():
app = QApplication(sys.argv)
window = AcrylicWindow()
window.show()
sys.exit(app.exec())
if __name__ == '__main__':
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment