Merge pull request #1195 from deajan/wx_custom_icon_fix
Allow custom icon to work via SetOptions
This commit is contained in:
commit
6a9d3f9550
|
@ -0,0 +1,18 @@
|
||||||
|
---
|
||||||
|
name: Custom issue template
|
||||||
|
about: PySimpleGUI custom template
|
||||||
|
title: "[FILL IN PREFIX] Description"
|
||||||
|
labels: ''
|
||||||
|
assignees: ''
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Issue Title Prefixes - [Bug], [Question], [Enhancement]
|
||||||
|
|
||||||
|
### What is the import statement in your program that imports the PySimpleGUI package?
|
||||||
|
|
||||||
|
### Your PySimpleGUI version if known:
|
||||||
|
|
||||||
|
### Operating System and version:
|
||||||
|
|
||||||
|
### What's up?
|
|
@ -0,0 +1,3 @@
|
||||||
|
.env
|
||||||
|
venv
|
||||||
|
__pycache__
|
|
@ -1,6 +1,5 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
import sys
|
import sys
|
||||||
import sys
|
|
||||||
if sys.version_info[0] >= 3:
|
if sys.version_info[0] >= 3:
|
||||||
import PySimpleGUI as sg
|
import PySimpleGUI as sg
|
||||||
else:
|
else:
|
||||||
|
|
|
@ -0,0 +1,136 @@
|
||||||
|
#! /usr/bin/env python
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
"""
|
||||||
|
Quick and dirty threading example for PySimpleGUI progress bar executing class methods
|
||||||
|
Written in 2018 by Orsiris de Jong, www.netpower.fr, works with Python 3+
|
||||||
|
"""
|
||||||
|
|
||||||
|
from threading import Thread
|
||||||
|
from concurrent.futures import Future
|
||||||
|
from time import time, sleep
|
||||||
|
import PySimpleGUI as sg
|
||||||
|
|
||||||
|
# Helper functions for threading class functions with return values using future from https://stackoverflow.com/a/19846691/2635443
|
||||||
|
def call_with_future(fn, future, args, kwargs):
|
||||||
|
try:
|
||||||
|
result = fn(*args, **kwargs)
|
||||||
|
future.set_result(result)
|
||||||
|
except Exception as exc:
|
||||||
|
future.set_exception(exc)
|
||||||
|
|
||||||
|
def threaded(fn):
|
||||||
|
def wrapper(*args, **kwargs):
|
||||||
|
future = Future()
|
||||||
|
Thread(target=call_with_future, args=(fn, future, args, kwargs)).start()
|
||||||
|
return future
|
||||||
|
return wrapper
|
||||||
|
|
||||||
|
# Some fancy class which functions should be threaded or not using decorator
|
||||||
|
class SomeFancyClass:
|
||||||
|
def __init__(self):
|
||||||
|
self.somevar = 'Some initial class variable'
|
||||||
|
|
||||||
|
# Adding this decoroator to thread the function below
|
||||||
|
@threaded
|
||||||
|
def func_to_be_threaded(self):
|
||||||
|
print(self.somevar)
|
||||||
|
sleep(7)
|
||||||
|
self.somevar = 'New value'
|
||||||
|
return('Return from func_to_be_threaded is ' + self.somevar)
|
||||||
|
|
||||||
|
|
||||||
|
@threaded
|
||||||
|
def another_thread_function(self):
|
||||||
|
print(self.somevar)
|
||||||
|
sleep(3)
|
||||||
|
return ('Return from another_thread_function is ' + self.somevar)
|
||||||
|
|
||||||
|
def non_threaded_function(self):
|
||||||
|
print('waiting')
|
||||||
|
sleep(5)
|
||||||
|
print('finished waiting')
|
||||||
|
|
||||||
|
# The main progress bar method
|
||||||
|
def progressbar(myClass):
|
||||||
|
maxwait = 10 # Wait for 10 seconds max with the progress bar before asking to cancel
|
||||||
|
progress = 0
|
||||||
|
startTime = 0
|
||||||
|
currentTime = 0
|
||||||
|
|
||||||
|
function_one = None
|
||||||
|
function_two = None
|
||||||
|
function_one_done = False
|
||||||
|
function_two_done = False
|
||||||
|
|
||||||
|
# layout of the progress bar window
|
||||||
|
layout = [[sg.Text('Launching threads')],
|
||||||
|
[sg.ProgressBar(100, orientation='h', size=(20, 20), key='progressbar')],
|
||||||
|
[sg.Cancel()]]
|
||||||
|
|
||||||
|
# create the progress bar
|
||||||
|
window = sg.Window('Init', text_justification='center').Layout(layout)
|
||||||
|
|
||||||
|
startTime = time()
|
||||||
|
|
||||||
|
while True:
|
||||||
|
event, values = window.Read(timeout=300)
|
||||||
|
if event == 'Cancel' or event is None:
|
||||||
|
if function_one != None:
|
||||||
|
function_one.cancel()
|
||||||
|
if function_two != None:
|
||||||
|
function_two.cancel()
|
||||||
|
window.Close()
|
||||||
|
exit()
|
||||||
|
|
||||||
|
if function_one == None:
|
||||||
|
# Launch first threaded function
|
||||||
|
function_one = myClass.func_to_be_threaded()
|
||||||
|
|
||||||
|
if function_two == None:
|
||||||
|
# Launch second threaded function
|
||||||
|
function_two = myClass.another_thread_function()
|
||||||
|
|
||||||
|
print('function_one is done: ' + str(function_one.done()))
|
||||||
|
print('function_two is done: ' + str(function_two.done()))
|
||||||
|
|
||||||
|
if function_one.done() == True and function_one_done == False:
|
||||||
|
function_one_done = True
|
||||||
|
print(function_one.result())
|
||||||
|
progress += 70
|
||||||
|
|
||||||
|
if function_two.done() == True and function_two_done == False:
|
||||||
|
function_two_done = True
|
||||||
|
print(function_two.result())
|
||||||
|
progress += 30
|
||||||
|
|
||||||
|
window.FindElement('progressbar').UpdateBar(progress)
|
||||||
|
|
||||||
|
currentTime = time()
|
||||||
|
if (currentTime - startTime) > maxwait:
|
||||||
|
action = sg.Popup('Seems that it takes too long, shall we continue the program',custom_text=('No', 'Yes'))
|
||||||
|
if action == 'No':
|
||||||
|
function_one.cancel()
|
||||||
|
function_two.cancel()
|
||||||
|
break
|
||||||
|
elif action == 'Yes':
|
||||||
|
startTime = time() # Lets give another 10 seconds or check if functions must be stopped
|
||||||
|
"""
|
||||||
|
TODO: We could relaunch the functions with
|
||||||
|
function_one.cancel()
|
||||||
|
if function_one.cancelled():
|
||||||
|
function_one = myClass.func_to_be_threaded()
|
||||||
|
"""
|
||||||
|
|
||||||
|
if progress >= 100:
|
||||||
|
sg.Popup('Execution finished')
|
||||||
|
break
|
||||||
|
window.Close()
|
||||||
|
|
||||||
|
def main():
|
||||||
|
myClass = SomeFancyClass()
|
||||||
|
progressbar(myClass)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
main()
|
|
@ -1548,6 +1548,8 @@ class Button(Element):
|
||||||
folder_name = tk.filedialog.askdirectory(initialdir=self.InitialFolder) # show the 'get folder' dialog box
|
folder_name = tk.filedialog.askdirectory(initialdir=self.InitialFolder) # show the 'get folder' dialog box
|
||||||
if folder_name != '':
|
if folder_name != '':
|
||||||
try:
|
try:
|
||||||
|
if sys.platform == 'win32':
|
||||||
|
folder_name = folder_name.replace("/", "\\")
|
||||||
strvar.set(folder_name)
|
strvar.set(folder_name)
|
||||||
self.TKStringVar.set(folder_name)
|
self.TKStringVar.set(folder_name)
|
||||||
except:
|
except:
|
||||||
|
@ -1558,6 +1560,8 @@ class Button(Element):
|
||||||
else:
|
else:
|
||||||
file_name = tk.filedialog.askopenfilename(filetypes=filetypes, initialdir=self.InitialFolder) # show the 'get file' dialog box
|
file_name = tk.filedialog.askopenfilename(filetypes=filetypes, initialdir=self.InitialFolder) # show the 'get file' dialog box
|
||||||
if file_name != '':
|
if file_name != '':
|
||||||
|
if sys.platform == 'win32':
|
||||||
|
file_name = file_name.replace("/", "\\")
|
||||||
strvar.set(file_name)
|
strvar.set(file_name)
|
||||||
self.TKStringVar.set(file_name)
|
self.TKStringVar.set(file_name)
|
||||||
elif self.BType == BUTTON_TYPE_COLOR_CHOOSER:
|
elif self.BType == BUTTON_TYPE_COLOR_CHOOSER:
|
||||||
|
@ -1572,6 +1576,8 @@ class Button(Element):
|
||||||
file_name = tk.filedialog.askopenfilenames(filetypes=filetypes, initialdir=self.InitialFolder)
|
file_name = tk.filedialog.askopenfilenames(filetypes=filetypes, initialdir=self.InitialFolder)
|
||||||
if file_name != '':
|
if file_name != '':
|
||||||
file_name = ';'.join(file_name)
|
file_name = ';'.join(file_name)
|
||||||
|
if sys.platform == 'win32':
|
||||||
|
file_name = file_name.replace("/", "\\")
|
||||||
strvar.set(file_name)
|
strvar.set(file_name)
|
||||||
self.TKStringVar.set(file_name)
|
self.TKStringVar.set(file_name)
|
||||||
elif self.BType == BUTTON_TYPE_SAVEAS_FILE:
|
elif self.BType == BUTTON_TYPE_SAVEAS_FILE:
|
||||||
|
@ -1581,6 +1587,8 @@ class Button(Element):
|
||||||
file_name = tk.filedialog.asksaveasfilename(filetypes=filetypes,
|
file_name = tk.filedialog.asksaveasfilename(filetypes=filetypes,
|
||||||
initialdir=self.InitialFolder) # show the 'get file' dialog box
|
initialdir=self.InitialFolder) # show the 'get file' dialog box
|
||||||
if file_name != '':
|
if file_name != '':
|
||||||
|
if sys.platform == 'win32':
|
||||||
|
file_name = file_name.replace("/", "\\")
|
||||||
strvar.set(file_name)
|
strvar.set(file_name)
|
||||||
self.TKStringVar.set(file_name)
|
self.TKStringVar.set(file_name)
|
||||||
elif self.BType == BUTTON_TYPE_CLOSES_WIN: # this is a return type button so GET RESULTS and destroy window
|
elif self.BType == BUTTON_TYPE_CLOSES_WIN: # this is a return type button so GET RESULTS and destroy window
|
||||||
|
|
|
@ -2985,7 +2985,7 @@ class Window:
|
||||||
self.Font = font if font else DEFAULT_FONT
|
self.Font = font if font else DEFAULT_FONT
|
||||||
self.RadioDict = {}
|
self.RadioDict = {}
|
||||||
self.BorderDepth = border_depth
|
self.BorderDepth = border_depth
|
||||||
self.WindowIcon = icon if icon is not None else Window.user_defined_icon
|
self.WindowIcon = Window.user_defined_icon if Window.user_defined_icon is not None else icon if icon is not None else DEFAULT_WINDOW_ICON
|
||||||
self.AutoClose = auto_close
|
self.AutoClose = auto_close
|
||||||
self.NonBlocking = False
|
self.NonBlocking = False
|
||||||
self.TKroot = None
|
self.TKroot = None
|
||||||
|
@ -5803,15 +5803,8 @@ def SetOptions(icon=None, button_color=None, element_size=(None, None), button_e
|
||||||
global DEFAULT_ELEMENT_TEXT_COLOR
|
global DEFAULT_ELEMENT_TEXT_COLOR
|
||||||
global DEFAULT_INPUT_TEXT_COLOR
|
global DEFAULT_INPUT_TEXT_COLOR
|
||||||
global DEFAULT_TOOLTIP_TIME
|
global DEFAULT_TOOLTIP_TIME
|
||||||
global _my_windows
|
|
||||||
|
|
||||||
if icon:
|
Window.user_defined_icon = icon
|
||||||
try:
|
|
||||||
with open(icon, 'r') as icon_file:
|
|
||||||
pass
|
|
||||||
except:
|
|
||||||
raise FileNotFoundError
|
|
||||||
_my_windows.user_defined_icon = icon
|
|
||||||
|
|
||||||
if button_color != None:
|
if button_color != None:
|
||||||
DEFAULT_BUTTON_COLOR = button_color
|
DEFAULT_BUTTON_COLOR = button_color
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
# PySimpleGUI-HowDoI
|
# PySimpleGUI-exemaker
|
||||||
|
|
||||||
## Introduction
|
## Introduction
|
||||||
This package contains a GUI front-end to PyInstaller. Use this tool to create EXE files from your python programs
|
This package contains a GUI front-end to PyInstaller. Use this tool to create EXE files from your python programs
|
||||||
|
|
Loading…
Reference in New Issue