90 lines
		
	
	
	
		
			3.1 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			90 lines
		
	
	
	
		
			3.1 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
| from io import BytesIO
 | |
| from PIL import Image, ImageDraw, ImageFont
 | |
| import PySimpleGUI as sg
 | |
| 
 | |
| """
 | |
|     Demo Rounded Rectangle Buttons created using PIL
 | |
|     
 | |
|     A BIG thank you to @jason990420 for his talented work creating this demo.
 | |
|     
 | |
|     Demonstrates how you can draw buttons rather than using the built-in buttons
 | |
|     with the help of the PIL module.
 | |
|     
 | |
|     One advantage is that the buttons will match your window's theme.
 | |
|     
 | |
|     You'll find more PySimpleGUI programs featured in 
 | |
|     Mike Driscoll's PIL book - "Pillow: Image Processing with Python"
 | |
|     
 | |
|     Copyright 2021 PySimpleGUI, @jason990420 
 | |
| """
 | |
| 
 | |
| 
 | |
| def im_to_data(im):
 | |
|     """
 | |
|     Convert a PIL.Image.Image to a bytes image
 | |
|     :param im: Image
 | |
|     :type: PIL.Image.Image object
 | |
|     :return image in bytes
 | |
|     :type: bytes
 | |
|     """
 | |
|     with BytesIO() as buffer:
 | |
|         im.save(buffer, format='PNG')
 | |
|         data = buffer.getvalue()
 | |
|     return data
 | |
| 
 | |
| 
 | |
| def rounded_rectangle(text,  font=('arial.ttf', 14), button_color=None,):
 | |
|     """
 | |
|     Generate rounded image with text aligned center.
 | |
|     :param text: text to show on image, '\n' to split lines.
 | |
|     :type text: str
 | |
|     :param font: font for text
 | |
|     :type font: Tuple
 | |
|     :return image in bytes
 | |
|     :type: bytes
 | |
|     """
 | |
|     pad, radius, spacing = 5, 10, 5
 | |
|     ttf_font = ImageFont.truetype(font=font[0], size=font[1])
 | |
|     if not text:
 | |
|         text = ' '
 | |
|     paragraph = text.split('\n')
 | |
|     w = max(map(lambda x: ttf_font.getsize(x)[0], paragraph)) + 2 * pad
 | |
|     h = sum(map(lambda x: ttf_font.getsize(x)[1], paragraph)) + 2 * pad + len(paragraph) * spacing
 | |
|     c0, c1 = button_color if button_color else sg.theme_button_color()
 | |
|     c0 = c0 if c0 != sg.COLOR_SYSTEM_DEFAULT else 'white'
 | |
|     c1 = c1 if c1 != sg.COLOR_SYSTEM_DEFAULT else 'white'
 | |
|     im = Image.new("RGBA", (w, h), (255, 255, 255, 0))
 | |
|     draw = ImageDraw.Draw(im)
 | |
|     draw.rounded_rectangle((0, 0, w-1, h-1), fill=c1, width=0, radius=radius)
 | |
|     draw.multiline_text((pad, pad), text, align='center', font=ttf_font, fill=c0, spacing=spacing)
 | |
|     return im_to_data(im)
 | |
| 
 | |
| 
 | |
| # sg.theme("dark red")
 | |
| sg.theme("dark green 7")
 | |
| # sg.set_options(font=("Arial", 16))
 | |
| layout = [[sg.Button('Normal Button')],
 | |
|            [sg.Button('', image_data=sg.EMOJI_BASE64_HAPPY_THUMBS_UP, border_width=0, button_color=(sg.theme_background_color(), sg.theme_background_color()))],
 | |
|           [sg.Button(image_data=rounded_rectangle('Button text\nwith 2 lines', font=('arial.ttf', 25)), button_color=(sg.theme_background_color(), sg.theme_background_color()), border_width=0)]]
 | |
| 
 | |
| layout += [
 | |
|       [sg.Button(
 | |
|         image_data=rounded_rectangle(text, font=('cour.ttf', 25)),
 | |
|         button_color=(sg.theme_button_color()[0], sg.theme_background_color()),
 | |
|         border_width=0)]
 | |
|      for text in (
 | |
|         "My button",
 | |
|         "Button with\n2 lines",
 | |
|         "A long long ..................long line",
 | |
|         "123\n2\n3")
 | |
|     ]
 | |
| 
 | |
| window = sg.Window('Image and Rounded Button', layout, finalize=True, keep_on_top=True, use_custom_titlebar=True)
 | |
| 
 | |
| while True:
 | |
| 
 | |
|     event, values = window.read()
 | |
|     if event in (sg.WINDOW_CLOSED, "Exit"):
 | |
|         break
 | |
| 
 | |
| window.close()
 |