Closed Minoslo closed 5 months ago
Not sure what the requirement you want, if possible, can you give me an exact image for your target.
Hi Jason, Thank you so much for being so fast. What I'm trying to accomplish is something I saw in modern solar software. I'm attaching an image. I think I can get the top-down blur effect by researching more on how to make my own color map in Matplotlib. Instead of starting with the orange color and blur it into white, I can blur into black and maybe that solves half the problem. But blurring the horizontal edges, I don't know how to do it, really. I tried to investigate to see if I could modify the alpha channel of the sg object Graph(), but it's not possible or I haven't been able to do it, and it may not even be the solution. Greetings and thank you in advance whether or not there is a solution to the problem.
Pd: Thank you so much for your posts, I saw the circular progress bar one and I included it in my project after spending so many hours trying to realize how the code works. For me it was fascinating how did you use the pillow package for solving that.
Not sure how it can be done or not by using matplotlib, but it cannot be done by using PySimpleGUI/tkinter.
For my knowledge, if the target is correct for you, I will do it by using Pillow library and PySimpleGUI Image element.
import io
import time
import random
import threading
from PIL import Image, ImageDraw, ImageFilter
import PySimpleGUI as sg
class GUI():
def __init__(self, size=(400, 300)):
self.w, self.h = self.size = size
sg.theme('DarkBlue3')
sg.set_options(font=("Courier New", 16))
layout = [
[sg.Image(size=self.size, background_color='black', key='IMAGE')],
[sg.Push(), sg.Button("BLUR"), sg.Push()]
]
self.window = sg.Window(
'Title', layout=layout, enable_close_attempted_event=True,
use_default_focus=False, margins=(0, 0), finalize=True)
self.window["BLUR"].block_focus()
self.blur = False
self.running = True
threading.Thread(target=self.get_data, daemon=True).start()
self.start()
def get_data(self, fg=(255, 255, 255, 255), bg=(0, 0, 0, 255)):
y = self.h//2
while self.running:
self.data = [(i, random.randint(-y, y) + y) for i in range(self.w)]
im = Image.new("RGBA", self.size, color=bg)
draw = ImageDraw.Draw(im, mode="RGBA")
draw.line(self.data, fill=fg, width=1)
draw.line([(0, y), (self.w, y)], fill=fg, width=1)
if self.blur:
im = im.filter(ImageFilter.BLUR)
data = self.image_to_data(im)
self.window.write_event_value("Update", data)
time.sleep(0.1) # time delay to reduce the CPU loading
def image_to_data(self, im):
with io.BytesIO() as output:
im.save(output, format="PNG")
data = output.getvalue()
return data
def start(self):
while True:
event, values = self.window.read()
if event == sg.WINDOW_CLOSE_ATTEMPTED_EVENT:
break
elif event == 'Update':
data = values[event]
self.window['IMAGE'].update(data)
elif event == 'BLUR':
self.blur = not self.blur
self.running = False
time.sleep(0.2) # wait thread stop
self.window.close()
GUI()
Hi Jason,
First of all, I'm sorry I didn't answer in these two days. It's been Holy Week in my city and I've been a bit absent. The solution you show me is great man! But I'd like to know if it can be fine-tuned it a little bit more and just blur the edges.
Best regards and thank you very much!
just blur the edges.
What the edges are ? No exact definition for the edges may get nothing returned.
That's nice, I want to learn that library so this is a good chance to do it. Just to clarify what I trying to mean by edges: That blurred effect that occurs in this image and that blends the graphic with the background.
Firstly, I created an edge-spur mask by PIL.Image
Then using Image.alpha_composite
with both images, main image and the mask.
import io
import time
import random
import threading
from PIL import Image, ImageDraw, ImageFilter
import PySimpleGUI as sg
class GUI():
def __init__(self, size):
self.w, self.h = self.size = size
sg.theme('DarkBlue3')
sg.set_options(font=("Courier New", 16))
layout = [
[sg.Image(size=self.size, background_color='black', key='IMAGE')],
[sg.Push(), sg.Button("BLUR"), sg.Push()]
]
self.window = sg.Window(
'Title', layout=layout, enable_close_attempted_event=True,
use_default_focus=False, margins=(0, 0), finalize=True)
self.window["BLUR"].block_focus()
self.blur = False
self.running = True
threading.Thread(target=self.get_data, daemon=True).start()
self.start()
def get_data(self, fg=(255, 255, 255, 255), bg=(0, 0, 0, 255)):
y = self.h//2
while self.running:
self.data = [(i, random.randint(-y, y) + y) for i in range(self.w)]
im = Image.new("RGBA", self.size, color=bg)
draw = ImageDraw.Draw(im, mode="RGBA")
draw.line(self.data, fill=fg, width=1)
draw.line([(0, y), (self.w, y)], fill=fg, width=1)
if self.blur:
im = Image.alpha_composite(im, mask)
data = self.image_to_data(im)
self.window.write_event_value("Update", data)
time.sleep(0.1) # time delay to reduce the CPU loading
def image_to_data(self, im):
with io.BytesIO() as output:
im.save(output, format="PNG")
data = output.getvalue()
return data
def start(self):
while True:
event, values = self.window.read()
if event == sg.WINDOW_CLOSE_ATTEMPTED_EVENT:
break
elif event == 'Update':
data = values[event]
self.window['IMAGE'].update(data)
elif event == 'BLUR':
self.blur = not self.blur
self.running = False
time.sleep(0.2) # wait thread stop
self.window.close()
# Create an edge-spur mask
size = w, h = (400, 300)
mask = Image.new("RGBA", size, color=(0, 0, 0, 0)) # Black
width = 100
for x in range(w):
for y in range(h):
r, g, b, a = mask.getpixel((x, y))
alpha1, alpha2 = 0, 0
if x < width:
alpha1 = int((width - x)/width * 255)
elif x > w - width:
alpha1 = int((x - w + width)/width * 255)
if y < width:
alpha2 = int((width - y)/width * 255)
elif y > h - width:
alpha2 = int((y - h + width)/width * 255)
alpha = max(alpha1, alpha2)
mask.putpixel((x, y), (r, g, g, alpha))
GUI(size)
THAT'S EXACTLY what I wanted man! You are awesome Jason, thank you very much. I'll try to apply this one, after be able to know how did you do that hehe, to my graph. Thank you man.
Should I close this thread, Jason?
Type of Issue (Enhancement, Error, Bug, Question)
Question
Operating System
Windows 11
PySimpleGUI Port (tkinter, Qt, Wx, Web)
tkinter
Versions
Version information can be obtained by calling
sg.main_get_debug_data()
Or you can print each version shown in ()Python version (
sg.sys.version
)3.12.0 (tags/v3.12.0:0fb18b0, Oct 2 2023, 13:03:39) [MSC v.1935 64 bit (AMD64)]
PySimpleGUI Version (
sg.__version__
)4.60.5
GUI Version (tkinter (
sg.tclversion_detailed
), PySide2, WxPython, Remi)8.6.13
Your Experience In Months or Years (optional)
Have used another Python GUI Framework? (tkinter, Qt, etc) (yes/no is fine) No
Anything else you think would be helpful? I'm pretty much a Python begginer
Troubleshooting
These items may solve your problem. Please check those you've done by changing - [ ] to - [X]
Detailed Description
The graphic rectangle containing the chart is too noticeable. I'd like it to be more integrated into the design, for example, blurring the edges or something like that. I'm not sure if there's a solution and I'm not sure if the solution is about PySimpleGUI or Matplotlib, so I'm sorry in advance if this is not the correct place to ask my question.
I hope someone can help me to keep learning about PySimpleGUI.
Thanks.
Edited: Include a short video rather than an image
Code To Duplicate
A short program that isolates and demonstrates the problem (Do not paste your massive program, but instead 10-20 lines that clearly show the problem)
This pre-formatted code block is all set for you to paste in your bit of code:
Screenshot, Sketch, or Drawing
https://github.com/PySimpleGUI/PySimpleGUI/assets/157976718/264f0404-5c85-46c4-b303-f9db029924b6
Watcha Makin?
Hi everyone 😊,
I've been learning about PySimpleGUI because I wanted to make an interface for myself since I have solar installation in my house. PySimpleGUI was my best choice to get started with Python GUIs and so I did. I was able to render all the data I wanted in multiple layouts in the same window thanks to all the demos that exist on the web. My way forward was to copy the code from the demos, try to understand how everything works by changing things and, once understood, try to modify it to be the way I wanted it to be. Now I was trying to include a graph in the GUI using Matplotlib and I think I did a really good job (and I say THINK, don't judge me too much). This graph is going to represent how much solar energy is being produced overall. Gradients are also great because at the end (now that I know how it works), it will represent in blue how much energy my load is consuming out of the total and in orange how much energy is free to go to my batteries or the grid.