Created
March 15, 2025 12:23
-
-
Save downthecrop/6ca9945691a1e1d03e6345674e31c6c4 to your computer and use it in GitHub Desktop.
from PyQt-Frameless-Window
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# 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