commit
b94b090d5b
|
@ -0,0 +1,45 @@
|
||||||
|
from time import sleep
|
||||||
|
import PySimpleGUI as sg
|
||||||
|
|
||||||
|
"""
|
||||||
|
Demonstration of multiple OneLineProgressMeter's
|
||||||
|
|
||||||
|
Shows how 2 progress meters can be running at the same time.
|
||||||
|
Note -- If the user wants to cancel a meter, it's important to use the "Cancel" button, not the X
|
||||||
|
If the software determined that a meter should be cancelled early,
|
||||||
|
calling OneLineProgresMeterCancel(key) will cancel the meter with the matching key
|
||||||
|
"""
|
||||||
|
|
||||||
|
sg.ChangeLookAndFeel('Dark')
|
||||||
|
|
||||||
|
layout = [
|
||||||
|
[sg.T('One-Line Progress Meter Demo', font=('Any 18'))],
|
||||||
|
[sg.T('Outer Loop Count', size=(15,1), justification='r'), sg.In(default_text='100', size=(5,1), key='CountOuter', do_not_clear=True),
|
||||||
|
sg.T('Delay'), sg.In(default_text='10', key='TimeOuter', size=(5,1), do_not_clear=True), sg.T('ms')],
|
||||||
|
[sg.T('Inner Loop Count', size=(15,1), justification='r'), sg.In(default_text='100', size=(5,1), key='CountInner', do_not_clear=True) ,
|
||||||
|
sg.T('Delay'), sg.In(default_text='10', key='TimeInner', size=(5,1), do_not_clear=True), sg.T('ms')],
|
||||||
|
[sg.SimpleButton('Show', pad=((0,0), 3), bind_return_key=True), sg.T('me the meters!')]
|
||||||
|
]
|
||||||
|
|
||||||
|
form = sg.FlexForm('One-Line Progress Meter Demo')
|
||||||
|
form.Layout(layout)
|
||||||
|
|
||||||
|
while True:
|
||||||
|
button, values = form.Read()
|
||||||
|
if button is None:
|
||||||
|
break
|
||||||
|
if button == 'Show':
|
||||||
|
max_outer = int(values['CountOuter'])
|
||||||
|
max_inner = int(values['CountInner'])
|
||||||
|
delay_inner = int(values['TimeInner'])
|
||||||
|
delay_outer = int(values['TimeOuter'])
|
||||||
|
for i in range(max_outer):
|
||||||
|
if not sg.OneLineProgressMeter('Outer Loop', i+1, max_outer, 'outer'):
|
||||||
|
break
|
||||||
|
sleep(delay_outer/1000)
|
||||||
|
for j in range(max_inner):
|
||||||
|
if not sg.OneLineProgressMeter('Inner Loop', j+1, max_inner, 'inner'):
|
||||||
|
break
|
||||||
|
sleep(delay_inner/1000)
|
||||||
|
|
||||||
|
exit(69)
|
111
PySimpleGUI.py
111
PySimpleGUI.py
|
@ -1044,6 +1044,7 @@ class ProgressBar(Element):
|
||||||
super().__init__(ELEM_TYPE_PROGRESS_BAR, scale=scale, size=size, auto_size_text=auto_size_text, key=key, pad=pad)
|
super().__init__(ELEM_TYPE_PROGRESS_BAR, scale=scale, size=size, auto_size_text=auto_size_text, key=key, pad=pad)
|
||||||
return
|
return
|
||||||
|
|
||||||
|
# returns False if update failed
|
||||||
def UpdateBar(self, current_count, max=None):
|
def UpdateBar(self, current_count, max=None):
|
||||||
if self.ParentForm.TKrootDestroyed:
|
if self.ParentForm.TKrootDestroyed:
|
||||||
return False
|
return False
|
||||||
|
@ -2952,7 +2953,7 @@ def _ProgressMeter(title, max_value, *args, orientation=None, bar_color=(None,No
|
||||||
local_orientation = DEFAULT_METER_ORIENTATION if orientation is None else orientation
|
local_orientation = DEFAULT_METER_ORIENTATION if orientation is None else orientation
|
||||||
local_border_width = DEFAULT_PROGRESS_BAR_BORDER_WIDTH if border_width is None else border_width
|
local_border_width = DEFAULT_PROGRESS_BAR_BORDER_WIDTH if border_width is None else border_width
|
||||||
bar2 = ProgressBar(max_value, orientation=local_orientation, size=size, bar_color=bar_color, scale=scale, border_width=local_border_width, relief=DEFAULT_PROGRESS_BAR_RELIEF)
|
bar2 = ProgressBar(max_value, orientation=local_orientation, size=size, bar_color=bar_color, scale=scale, border_width=local_border_width, relief=DEFAULT_PROGRESS_BAR_RELIEF)
|
||||||
form = FlexForm(title, auto_size_text=True)
|
form = FlexForm(title, auto_size_text=True, grab_anywhere=True)
|
||||||
|
|
||||||
# Form using a horizontal bar
|
# Form using a horizontal bar
|
||||||
if local_orientation[0].lower() == 'h':
|
if local_orientation[0].lower() == 'h':
|
||||||
|
@ -2996,10 +2997,12 @@ def _ProgressMeterUpdate(bar, value, text_elem, *args):
|
||||||
if value >= bar.MaxValue or not rc:
|
if value >= bar.MaxValue or not rc:
|
||||||
bar.BarExpired = True
|
bar.BarExpired = True
|
||||||
bar.ParentForm._Close()
|
bar.ParentForm._Close()
|
||||||
|
if rc: # if update was OK but bar expired, decrement num windows
|
||||||
|
_my_windows.Decrement()
|
||||||
if bar.ParentForm.RootNeedsDestroying:
|
if bar.ParentForm.RootNeedsDestroying:
|
||||||
try:
|
try:
|
||||||
bar.ParentForm.TKroot.destroy()
|
bar.ParentForm.TKroot.destroy()
|
||||||
_my_windows.Decrement()
|
# _my_windows.Decrement()
|
||||||
except: pass
|
except: pass
|
||||||
bar.ParentForm.RootNeedsDestroying = False
|
bar.ParentForm.RootNeedsDestroying = False
|
||||||
bar.ParentForm.__del__()
|
bar.ParentForm.__del__()
|
||||||
|
@ -3071,42 +3074,42 @@ def EasyProgressMeter(title, current_value, max_value, *args, orientation=None,
|
||||||
# STATIC VARIABLE!
|
# STATIC VARIABLE!
|
||||||
# This is a very clever form of static variable using a function attribute
|
# This is a very clever form of static variable using a function attribute
|
||||||
# If the variable doesn't yet exist, then it will create it and initialize with the 3rd parameter
|
# If the variable doesn't yet exist, then it will create it and initialize with the 3rd parameter
|
||||||
EasyProgressMeter.EasyProgressMeterData = getattr(EasyProgressMeter, 'EasyProgressMeterData', EasyProgressMeterDataClass())
|
EasyProgressMeter.Data = getattr(EasyProgressMeter, 'Data', EasyProgressMeterDataClass())
|
||||||
# if no meter currently running
|
# if no meter currently running
|
||||||
if EasyProgressMeter.EasyProgressMeterData.MeterID is None: # Starting a new meter
|
if EasyProgressMeter.Data.MeterID is None: # Starting a new meter
|
||||||
if int(current_value) >= int(max_value):
|
if int(current_value) >= int(max_value):
|
||||||
return False
|
return False
|
||||||
del(EasyProgressMeter.EasyProgressMeterData)
|
del(EasyProgressMeter.Data)
|
||||||
EasyProgressMeter.EasyProgressMeterData = EasyProgressMeterDataClass(title, 1, int(max_value), datetime.datetime.utcnow(), [])
|
EasyProgressMeter.Data = EasyProgressMeterDataClass(title, 1, int(max_value), datetime.datetime.utcnow(), [])
|
||||||
EasyProgressMeter.EasyProgressMeterData.ComputeProgressStats()
|
EasyProgressMeter.Data.ComputeProgressStats()
|
||||||
message = "\n".join([line for line in EasyProgressMeter.EasyProgressMeterData.StatMessages])
|
message = "\n".join([line for line in EasyProgressMeter.Data.StatMessages])
|
||||||
EasyProgressMeter.EasyProgressMeterData.MeterID, EasyProgressMeter.EasyProgressMeterData.MeterText= _ProgressMeter(title, int(max_value), message, *args, orientation=orientation, bar_color=bar_color, size=size, scale=scale, button_color=button_color, border_width=local_border_width)
|
EasyProgressMeter.Data.MeterID, EasyProgressMeter.Data.MeterText= _ProgressMeter(title, int(max_value), message, *args, orientation=orientation, bar_color=bar_color, size=size, scale=scale, button_color=button_color, border_width=local_border_width)
|
||||||
EasyProgressMeter.EasyProgressMeterData.ParentForm = EasyProgressMeter.EasyProgressMeterData.MeterID.ParentForm
|
EasyProgressMeter.Data.ParentForm = EasyProgressMeter.Data.MeterID.ParentForm
|
||||||
return True
|
return True
|
||||||
# if exactly the same values as before, then ignore.
|
# if exactly the same values as before, then ignore.
|
||||||
if EasyProgressMeter.EasyProgressMeterData.MaxValue == max_value and EasyProgressMeter.EasyProgressMeterData.CurrentValue == current_value:
|
if EasyProgressMeter.Data.MaxValue == max_value and EasyProgressMeter.Data.CurrentValue == current_value:
|
||||||
return True
|
return True
|
||||||
if EasyProgressMeter.EasyProgressMeterData.MaxValue != int(max_value):
|
if EasyProgressMeter.Data.MaxValue != int(max_value):
|
||||||
EasyProgressMeter.EasyProgressMeterData.MeterID = None
|
EasyProgressMeter.Data.MeterID = None
|
||||||
EasyProgressMeter.EasyProgressMeterData.ParentForm = None
|
EasyProgressMeter.Data.ParentForm = None
|
||||||
del(EasyProgressMeter.EasyProgressMeterData)
|
del(EasyProgressMeter.Data)
|
||||||
EasyProgressMeter.EasyProgressMeterData = EasyProgressMeterDataClass() # setup a new progress meter
|
EasyProgressMeter.Data = EasyProgressMeterDataClass() # setup a new progress meter
|
||||||
return True # HAVE to return TRUE or else the new meter will thing IT is failing when it hasn't
|
return True # HAVE to return TRUE or else the new meter will thing IT is failing when it hasn't
|
||||||
EasyProgressMeter.EasyProgressMeterData.CurrentValue = int(current_value)
|
EasyProgressMeter.Data.CurrentValue = int(current_value)
|
||||||
EasyProgressMeter.EasyProgressMeterData.MaxValue = int(max_value)
|
EasyProgressMeter.Data.MaxValue = int(max_value)
|
||||||
EasyProgressMeter.EasyProgressMeterData.ComputeProgressStats()
|
EasyProgressMeter.Data.ComputeProgressStats()
|
||||||
message = ''
|
message = ''
|
||||||
for line in EasyProgressMeter.EasyProgressMeterData.StatMessages:
|
for line in EasyProgressMeter.Data.StatMessages:
|
||||||
message = message + str(line) + '\n'
|
message = message + str(line) + '\n'
|
||||||
message = "\n".join(EasyProgressMeter.EasyProgressMeterData.StatMessages)
|
message = "\n".join(EasyProgressMeter.Data.StatMessages)
|
||||||
args= args + (message,)
|
args= args + (message,)
|
||||||
rc = _ProgressMeterUpdate(EasyProgressMeter.EasyProgressMeterData.MeterID, current_value,
|
rc = _ProgressMeterUpdate(EasyProgressMeter.Data.MeterID, current_value,
|
||||||
EasyProgressMeter.EasyProgressMeterData.MeterText, *args)
|
EasyProgressMeter.Data.MeterText, *args)
|
||||||
# if counter >= max then the progress meter is all done. Indicate none running
|
# if counter >= max then the progress meter is all done. Indicate none running
|
||||||
if current_value >= EasyProgressMeter.EasyProgressMeterData.MaxValue or not rc:
|
if current_value >= EasyProgressMeter.Data.MaxValue or not rc:
|
||||||
EasyProgressMeter.EasyProgressMeterData.MeterID = None
|
EasyProgressMeter.Data.MeterID = None
|
||||||
del(EasyProgressMeter.EasyProgressMeterData)
|
del(EasyProgressMeter.Data)
|
||||||
EasyProgressMeter.EasyProgressMeterData = EasyProgressMeterDataClass() # setup a new progress meter
|
EasyProgressMeter.Data = EasyProgressMeterDataClass() # setup a new progress meter
|
||||||
return False # even though at the end, return True so don't cause error with the app
|
return False # even though at the end, return True so don't cause error with the app
|
||||||
return rc # return whatever the update told us
|
return rc # return whatever the update told us
|
||||||
|
|
||||||
|
@ -3120,6 +3123,60 @@ def EasyProgressMeterCancel(title, *args):
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
# global variable containing dictionary will all currently running one-line progress meters.
|
||||||
|
_one_line_progress_meters = {}
|
||||||
|
|
||||||
|
# ============================== OneLineProgressMeter =====#
|
||||||
|
def OneLineProgressMeter(title, current_value, max_value, key, *args, orientation=None, bar_color=(None,None), button_color=None, size=DEFAULT_PROGRESS_BAR_SIZE, scale=(None, None), border_width=None):
|
||||||
|
|
||||||
|
global _one_line_progress_meters
|
||||||
|
|
||||||
|
local_border_width = DEFAULT_PROGRESS_BAR_BORDER_WIDTH if border_width is not None else border_width
|
||||||
|
try:
|
||||||
|
meter_data = _one_line_progress_meters[key]
|
||||||
|
except: # a new meater is starting
|
||||||
|
if int(current_value) >= int(max_value): # if already expired then it's an old meter, ignore
|
||||||
|
return False
|
||||||
|
meter_data = EasyProgressMeterDataClass(title, 1, int(max_value), datetime.datetime.utcnow(), [])
|
||||||
|
_one_line_progress_meters[key] = meter_data
|
||||||
|
meter_data.ComputeProgressStats()
|
||||||
|
message = "\n".join([line for line in meter_data.StatMessages])
|
||||||
|
meter_data.MeterID, meter_data.MeterText= _ProgressMeter(title, int(max_value), message, *args, orientation=orientation, bar_color=bar_color, size=size, scale=scale, button_color=button_color, border_width=local_border_width)
|
||||||
|
meter_data.ParentForm = meter_data.MeterID.ParentForm
|
||||||
|
return True
|
||||||
|
|
||||||
|
# if exactly the same values as before, then ignore, return success.
|
||||||
|
if meter_data.MaxValue == max_value and meter_data.CurrentValue == current_value:
|
||||||
|
return True
|
||||||
|
meter_data.CurrentValue = int(current_value)
|
||||||
|
meter_data.MaxValue = int(max_value)
|
||||||
|
meter_data.ComputeProgressStats()
|
||||||
|
message = ''
|
||||||
|
for line in meter_data.StatMessages:
|
||||||
|
message = message + str(line) + '\n'
|
||||||
|
message = "\n".join(meter_data.StatMessages)
|
||||||
|
args= args + (message,)
|
||||||
|
rc = _ProgressMeterUpdate(meter_data.MeterID, current_value,
|
||||||
|
meter_data.MeterText, *args)
|
||||||
|
# if counter >= max then the progress meter is all done. Indicate none running
|
||||||
|
if current_value >= meter_data.MaxValue or not rc:
|
||||||
|
del _one_line_progress_meters[key]
|
||||||
|
return False
|
||||||
|
return rc # return whatever the update told us
|
||||||
|
|
||||||
|
|
||||||
|
def OneLineProgressMeterCancel(key):
|
||||||
|
global _one_line_progress_meters
|
||||||
|
|
||||||
|
try:
|
||||||
|
meter_data = _one_line_progress_meters[key]
|
||||||
|
except: # meter is already deleted
|
||||||
|
return
|
||||||
|
OneLineProgressMeter('', meter_data.MaxValue, meter_data.MaxValue, key=key)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# input is #RRGGBB
|
# input is #RRGGBB
|
||||||
# output is #RRGGBB
|
# output is #RRGGBB
|
||||||
def GetComplimentaryHex(color):
|
def GetComplimentaryHex(color):
|
||||||
|
|
Loading…
Reference in New Issue