Merge pull request #1167 from PySimpleGUI/Dev-latest

Dev latest
This commit is contained in:
MikeTheWatchGuy 2019-02-18 20:12:30 -05:00 committed by GitHub
commit bc1a852ee6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 235 additions and 128 deletions

View File

@ -6170,7 +6170,7 @@ class QuickMeter(object):
layout = []
if self.orientation.lower().startswith('h'):
col = []
col += [[T(arg)] for arg in args]
col += [[T(''.join(map(lambda x: str(x)+'\n',args)),key='_OPTMSG_')]] ### convert all *args into one string that can be updated
col += [[T('', size=(30,10), key='_STATS_')],
[ProgressBar(max_value=self.max_value, orientation='h', key='_PROG_', size=self.size, bar_color=self.bar_color)],
[Cancel(button_color=self.button_color), Stretch()]]
@ -6178,7 +6178,7 @@ class QuickMeter(object):
else:
col = [[ProgressBar(max_value=self.max_value, orientation='v', key='_PROG_', size=self.size, bar_color=self.bar_color)]]
col2 = []
col2 += [[T(arg)] for arg in args]
col2 += [[T(''.join(map(lambda x: str(x)+'\n',args)),key='_OPTMSG_')]] ### convert all *args into one string that can be updated
col2 += [[T('', size=(30,10), key='_STATS_')],
[Cancel(button_color=self.button_color), Stretch()]]
layout = [Column(col), Column(col2)]
@ -6187,11 +6187,12 @@ class QuickMeter(object):
return self.window
def UpdateMeter(self, current_value, max_value):
def UpdateMeter(self, current_value, max_value,*args): ### support for *args when updating
self.current_value = current_value
self.max_value = max_value
self.window.Element('_PROG_').UpdateBar(self.current_value, self.max_value)
self.window.Element('_STATS_').Update('\n'.join(self.ComputeProgressStats()))
self.window.Element('_OPTMSG_').Update(value=''.join(map(lambda x: str(x)+'\n',args))) ### update the string with the args
event, values = self.window.Read(timeout=0)
if event in('Cancel', None) or current_value >= max_value:
self.window.Close()
@ -6239,10 +6240,11 @@ def OneLineProgressMeter(title, current_value, max_value, key, *args, orientatio
else:
meter = QuickMeter.active_meters[key]
rc = meter.UpdateMeter(current_value, max_value)
rc = meter.UpdateMeter(current_value, max_value,*args) ### pass the *args to to UpdateMeter function
OneLineProgressMeter.exit_reasons = getattr(OneLineProgressMeter,'exit_reasons', QuickMeter.exit_reasons)
return rc == METER_OK
def OneLineProgressMeterCancel(key):
try:
meter = QuickMeter.active_meters[key]

View File

@ -8,6 +8,16 @@ import base64
import calendar
from random import randint
###### ##### ##### # # ### #####
# # # # # # # # # ##### # ###### # # # # # # # #####
# # # # # # ## ## # # # # # # # # # # #
###### # ##### # # ## # # # # ##### # #### # # # # # #
# # # # # # ##### # # # # # # # # # # #
# # # # # # # # # # # # # # # # # #
# # ##### # # # # ###### ###### ##### ##### ### #### # #
FORCE_PYQT5 = False
if not FORCE_PYQT5:
@ -4404,9 +4414,48 @@ def AddMenuItem(top_menu, sub_menu_info, element, is_sub_menu=False, skip=False)
AddMenuItem(top_menu, item, element)
i += 1
"""
QQQQQQQQQ tttt
QQ:::::::::QQ ttt:::t
QQ:::::::::::::QQ t:::::t
Q:::::::QQQ:::::::Q t:::::t
Q::::::O Q::::::Qttttttt:::::ttttttt
Q:::::O Q:::::Qt:::::::::::::::::t
Q:::::O Q:::::Qt:::::::::::::::::t
Q:::::O Q:::::Qtttttt:::::::tttttt
Q:::::O Q:::::Q t:::::t
Q:::::O Q:::::Q t:::::t
Q:::::O QQQQ:::::Q t:::::t
Q::::::O Q::::::::Q t:::::t tttttt
Q:::::::QQ::::::::Q t::::::tttt:::::t
QQ::::::::::::::Q tt::::::::::::::t
QQ:::::::::::Q tt:::::::::::tt
QQQQQQQQ::::QQ ttttttttttt
Q:::::Q
QQQQQQ
"""
# My crappy Qt code starts here
# ░░░░░░░░░░░█▀▀░░█░░░░░░
# ░░░░░░▄▀▀▀▀░░░░░█▄▄░░░░
# ░░░░░░█░█░░░░░░░░░░▐░░░
# ░░░░░░▐▐░░░░░░░░░▄░▐░░░
# ░░░░░░█░░░░░░░░▄▀▀░▐░░░
# ░░░░▄▀░░░░░░░░▐░▄▄▀░░░░
# ░░▄▀░░░▐░░░░░█▄▀░▐░░░░░
# ░░█░░░▐░░░░░░░░▄░█░░░░░
# ░░░█▄░░▀▄░░░░▄▀▐░█░░░░░
# ░░░█▐▀▀▀░▀▀▀▀░░▐░█░░░░░
# ░░▐█▐▄░░▀░░░░░░▐░█▄▄░░░
# ░░░▀▀▄░░░░░░░░▄▐▄▄▄▀░░░
# ░░░░░░░░░░░░░░░░░░░░░░░
# ------------------------------------------------------------------------------------------------------------------ #
# ------------------------------------------------------------------------------------------------------------------ #
# ===================================== TK CODE STARTS HERE ====================================================== #
# ===================================== Qt CODE STARTS HERE ====================================================== #
# ------------------------------------------------------------------------------------------------------------------ #
# ------------------------------------------------------------------------------------------------------------------ #
def style_entry(**kwargs):
@ -5735,27 +5784,28 @@ class QuickMeter(object):
def BuildWindow(self, *args):
layout = []
if self.orientation.lower().startswith('h'):
col = [*[[T(arg)] for arg in args],
[T('', size=(25,8), key='_STATS_')],
col = [[T(''.join(map(lambda x: str(x)+'\n',args)),key='_OPTMSG_')]] ### convert all *args into one string that can be updated
col += [[T('', size=(25,5), key='_STATS_')],
[ProgressBar(max_value=self.max_value, orientation='h', key='_PROG_', size=self.size,
bar_color=self.bar_color)],
[Cancel(button_color=self.button_color), Stretch()] ]
[Cancel(button_color=self.button_color), Stretch()]]
layout += [Column(col)]
else:
col = [[ProgressBar(max_value=self.max_value, orientation='v', key='_PROG_', size=self.size, bar_color=self.bar_color)]]
col2 = [*[[T(arg)] for arg in args],
[T('', size=(25, 8), key='_STATS_')],[Cancel(button_color=self.button_color), Stretch()] ]
col2 = [[T(''.join(map(lambda x: str(x)+'\n',args)),key='_OPTMSG_')]] ### convert all *args into one string that can be updated
col2 += [[T('', size=(25,5), key='_STATS_')],[Cancel(button_color=self.button_color), Stretch()]]
layout += [Column(col), Column(col2)]
self.window = Window(self.title, grab_anywhere=self.grab_anywhere, border_depth=self.border_width)
self.window.Layout([layout]).Finalize()
return self.window
def UpdateMeter(self, current_value, max_value):
def UpdateMeter(self, current_value, max_value, *args):
self.current_value = current_value
self.max_value = max_value
self.window.Element('_PROG_').UpdateBar(self.current_value, self.max_value)
self.window.Element('_STATS_').Update('\n'.join(self.ComputeProgressStats()))
self.window.Element('_OPTMSG_').Update(value=''.join(map(lambda x: str(x)+'\n',args))) ### update the string with the args
event, values = self.window.Read(timeout=0)
if event in('Cancel', None) or current_value >= max_value:
self.window.Close()
@ -5803,7 +5853,7 @@ def OneLineProgressMeter(title, current_value, max_value, key, *args, orientatio
else:
meter = QuickMeter.active_meters[key]
rc = meter.UpdateMeter(current_value, max_value)
rc = meter.UpdateMeter(current_value, max_value, *args)
OneLineProgressMeter.exit_reasons = getattr(OneLineProgressMeter,'exit_reasons', QuickMeter.exit_reasons)
return rc == METER_OK

View File

@ -11,7 +11,7 @@ from queue import Queue
import remi
import logging
import traceback
import os
g_time_start = 0
g_time_end = 0
@ -143,7 +143,7 @@ DEFAULT_PROGRESS_BAR_BORDER_WIDTH = 1
DEFAULT_PROGRESS_BAR_RELIEF = RELIEF_GROOVE
PROGRESS_BAR_STYLES = ('default', 'winnative', 'clam', 'alt', 'classic', 'vista', 'xpnative')
DEFAULT_PROGRESS_BAR_STYLE = 'default'
DEFAULT_METER_ORIENTATION = 'Horizontal'
DEFAULT_METER_ORIENTATION = 'horizontal'
DEFAULT_SLIDER_ORIENTATION = 'vertical'
DEFAULT_SLIDER_BORDER_WIDTH = 1
DEFAULT_SLIDER_RELIEF = 00000
@ -439,6 +439,28 @@ class Element():
def Update(self, widget, background_color=None, text_color=None, font=None, visible=None, disabled=None, tooltip=None):
if font is not None:
font_info = font_parse_string(font) # family, point size, other
widget.style['font-family'] = font_info[0]
widget.style['font-size'] = '{}px'.format(font_info[1])
if background_color not in (None, COLOR_SYSTEM_DEFAULT):
widget.style['background-color'] = background_color
if text_color not in (None, COLOR_SYSTEM_DEFAULT):
widget.style['color'] = text_color
if disabled:
widget.set_enabled(False)
elif disabled is False:
widget.set_enabled(True)
if visible is False:
widget.attributes['hidden'] = 'true'
elif visible is True:
del(widget.attributes['hidden'])
if tooltip is not None:
widget.attributes['title'] = tooltip
# if font:
# widget.SetFont(font_to_wx_font(font))
# if text_color not in (None, COLOR_SYSTEM_DEFAULT):
@ -912,22 +934,9 @@ class Spin(Element):
def Update(self, value=None, values=None, disabled=None, background_color=None, text_color=None, font=None, visible=None):
if values != None:
self.Values = values
self.QT_Spinner.setStrings(values)
# self.QT_Spinner.setRange(self.Values[0], self.Values[1])
if value is not None:
# self.QT_Spinner.setValue(value)
try:
self.QT_Spinner.setValue(self.QT_Spinner.valueFromText(value))
self.DefaultValue = value
except:
pass
if disabled == True:
self.QT_Spinner.setDisabled(True)
elif disabled == False:
self.QT_Spinner.setDisabled(False)
super().Update(self.QT_Spinner, background_color=background_color, text_color=text_color, font=font, visible=visible)
self.Widget.set_value(value)
super().Update(self.Widget, background_color=background_color, text_color=text_color, font=font,visible=visible)
def Get(self):
return self.Widget.get_value()
@ -1076,7 +1085,7 @@ class MultilineOutput(Element):
self.CurrentValue = self.CurrentValue + '\n' + str(value)
self.Widget.set_value(self.CurrentValue)
app = self.ParentForm.App
app.execute_javascript("document.getElementById('%s').scrollTop=%s;" % (self.Widget.identifier, 9999)) # 9999 number of pixel to scroll
# app.execute_javascript("document.getElementById('%s').scrollTop=%s;" % (self.Widget.identifier, 9999)) # 9999 number of pixel to scroll
super().Update(self.Widget, background_color=background_color, text_color=text_color, font=font, visible=visible)
@ -1134,6 +1143,7 @@ class Text(Element):
pixelsize = size[0]*10, size[1]*20
self.BorderWidth = border_width if border_width is not None else DEFAULT_BORDER_WIDTH
self.Disabled = False
self.Widget = None #type: remi.gui.Label
super().__init__(ELEM_TYPE_TEXT, pixelsize, auto_size_text, background_color=bg, font=font if font else DEFAULT_FONT,
text_color=self.TextColor, pad=pad, key=key, tooltip=tooltip, size_px=size_px, visible=visible)
@ -1142,12 +1152,7 @@ class Text(Element):
def Update(self, value=None, background_color=None, text_color=None, font=None, visible=None):
if value is not None:
self.Widget.set_text(str(value))
# if background_color is not None:
# self.TKText.configure(background=background_color)
# if text_color is not None:
# self.TKText.configure(fg=text_color)
# if font is not None:
# self.TKText.configure(font=font)
super().Update(self.Widget, background_color=background_color, text_color=text_color, font=font, visible=visible)
def __del__(self):
super().__del__()
@ -1517,28 +1522,8 @@ class Button(Element):
def Update(self, text=None, button_color=(None, None), disabled=None, image_data=None, image_filename=None, font=None, visible=None):
if text is not None:
self.Widget.set_text(text)
if self.ParentForm.Font and (self.Font == DEFAULT_FONT or not self.Font):
font = self.ParentForm.Font
elif self.Font is not None:
font = self.Font
else:
font = DEFAULT_FONT
fg = bg = None
if button_color != (None, None):
self.ButtonColor = button_color
fg, bg = button_color
if self.Disabled != disabled and disabled is not None:
if not disabled: # if enabling buttons, set the color
fg, bg = self.ButtonColor
self.Disabled = disabled
if disabled:
self.QT_QPushButton.setDisabled(True)
else:
self.QT_QPushButton.setDisabled(False)
# fg, bg = self.ButtonColor
# print(f'Button update fg, bg {fg}, {bg}')
super().Update(self.Widget, background_color=bg, text_color=fg, font=font, visible=visible)
fg, bg = button_color
super().Update(self.Widget, background_color=bg, text_color=fg, disabled=disabled, font=font, visible=visible)
def GetText(self):
@ -1615,7 +1600,7 @@ class ProgressBar(Element):
# ---------------------------------------------------------------------- #
class Image(Element):
def __init__(self, filename=None, data=None, background_color=None, size=(None, None), pad=None, key=None,
tooltip=None):
tooltip=None, right_click_menu=None, visible=True, enable_events=False):
'''
Image Element
:param filename:
@ -1626,32 +1611,27 @@ class Image(Element):
:param key:
:param tooltip:
'''
self.Filename = filename
self.Filename = '/'+filename if filename else None # note that Remi expects a / at the front of resource files
self.Data = data
self.tktext_label = None
self.BackgroundColor = background_color
self.Disabled = False
self.EnableEvents = enable_events
sz = (0,0) if size == (None, None) else size
self.Widget = None #type: remi.gui.Image
if data is None and filename is None:
print('* Warning... no image specified in Image Element! *')
super().__init__(ELEM_TYPE_IMAGE, size=size, background_color=background_color, pad=pad, key=key,
tooltip=tooltip)
super().__init__(ELEM_TYPE_IMAGE, size=sz, background_color=background_color, pad=pad, key=key,
tooltip=tooltip, visible=visible)
return
def Update(self, filename=None, data=None, size=(None, None)):
def Update(self, filename=None, data=None, size=(None,None), visible=None):
if filename is not None:
image = tk.PhotoImage(file=filename)
elif data is not None:
# if type(data) is bytes:
try:
image = tk.PhotoImage(data=data)
except:
return # an error likely means the window has closed so exit
# else:
# image = data
else:
return
width, height = size[0] or image.width(), size[1] or image.height()
self.tktext_label.configure(image=image, width=width, height=height)
self.tktext_label.image = image
self.Widget.set_image(filename=filename)
if size != (None, None):
self.Widget.style['height'] = '{}px'.format(size[1])
self.Widget.style['width'] = '{}px'.format(size[0])
super().Update(self.Widget, visible=visible)
def __del__(self):
super().__del__()
@ -2205,19 +2185,14 @@ class Slider(Element):
text_color=text_color, key=key, pad=pad, tooltip=tooltip, visible=visible, size_px=size_px)
return
def Update(self, value=None, range=(None, None), disabled=None):
def Update(self, value=None, range=(None, None), disabled=None, visible=None):
if value is not None:
try:
self.TKIntVar.set(value)
if range != (None, None):
self.TKScale.config(from_=range[0], to_=range[1])
except:
pass
self.Widget.set_value(value)
self.DefaultValue = value
if disabled == True:
self.TKScale['state'] = 'disabled'
elif disabled == False:
self.TKScale['state'] = 'normal'
if range != (None, None):
self.Widget.style['min'] = '{}'.format(range[0])
self.Widget.style['max'] = '{}'.format(range[1])
super().Update(self.Widget, disabled=disabled, visible=visible)
def SliderCallback(self, widget:remi.Widget, value):
self.ParentForm.LastButtonClicked = self.Key if self.Key is not None else ''
@ -3207,11 +3182,13 @@ class Window:
userdata = args[-1].userdata
self.window = userdata[0] # type: Window
else:
self.window = userdata2
self.window = userdata2 # type: Window
self.window.App = self
self.master_widget = None
if userdata2 is None:
super(Window.MyApp, self).__init__(*args)
res_path = os.path.dirname(os.path.abspath(__file__))
# print('res path', res_path)
super(Window.MyApp, self).__init__(*args, static_file_path={'C':'c:','c':'c:','D':'d:', 'd':'d:', 'E':'e:', 'e':'e:', 'dot':'.', '.':'.'})
def main(self, name='world'):
# margin 0px auto allows to center the app to the screen
@ -3226,6 +3203,10 @@ class Window:
print('* ERROR PACKING FORM *')
print(traceback.format_exc())
if self.window.BackgroundImage:
self.master_widget.attributes['background-image'] = "url('{}')".format(self.window.BackgroundImage)
# print(f'background info',self.master_widget.attributes['background-image'] )
# add the following 3 lines to your app and the on_window_close method to make the console close automatically
tag = remi.gui.Tag(_type='script')
tag.add_child("javascript", """window.onunload=function(e){sendCallback('%s','%s');return "close?";};""" % (
@ -3982,10 +3963,10 @@ def PackFormIntoFrame(form, containing_frame, toplevel_form):
if element.TextColor not in (None, COLOR_SYSTEM_DEFAULT):
widget.style['color'] = element.TextColor
widget.style['font-size'] = '{}px'.format(font_info[1])
size = convert_tkinter_size_to_Wx(element_size)
# if not auto_size_text:
widget.style['height'] = '{}px'.format(size[1])
widget.style['width'] = '{}px'.format(size[0])
if element_size[0]: # if size is zero, don't set any sizes
size = convert_tkinter_size_to_Wx(element_size)
widget.style['height'] = '{}px'.format(size[1])
widget.style['width'] = '{}px'.format(size[0])
widget.style['margin'] = '{}px {}px {}px {}px'.format(*full_element_pad)
if element.Disabled:
widget.set_enabled(False)
@ -4428,10 +4409,10 @@ def PackFormIntoFrame(form, containing_frame, toplevel_form):
# ------------------------- IMAGE element ------------------------- #
elif element_type == ELEM_TYPE_IMAGE:
element = element # type: Image
element.Widget = remi.gui.Image(filename=element.Filename)
element.Widget = remi.gui.Image(element.Filename)
do_font_and_color(element.Widget)
if element.ChangeSubmits:
element.Widget.onchange.connect(element.ChangedCallback)
if element.EnableEvents:
element.Widget.onclick.connect(element.ChangedCallback)
tk_row_frame.append(element.Widget)
# if element.Filename is not None:
# photo = tk.PhotoImage(file=element.Filename)
@ -4616,7 +4597,8 @@ def PackFormIntoFrame(form, containing_frame, toplevel_form):
# ------------------------- SLIDER element ------------------------- #
elif element_type == ELEM_TYPE_INPUT_SLIDER:
element = element # type: Slider
element.Widget = remi.gui.Slider(layout_orientation = remi.gui.Widget.LAYOUT_HORIZONTAL, default_value=element.DefaultValue, min=element.Range[0], max=element.Range[1],step=element.Resolution)
orient = remi.gui.Widget.LAYOUT_HORIZONTAL if element.Orientation.lower().startswith('h') else remi.gui.Widget.LAYOUT_VERTICAL
element.Widget = remi.gui.Slider(layout_orientation = orient, default_value=element.DefaultValue, min=element.Range[0], max=element.Range[1],step=element.Resolution)
if element.DefaultValue:
element.Widget.set_value(element.DefaultValue)
# if element.Orientation.startswith('v'):
@ -6453,7 +6435,7 @@ def main():
[Combo(values=['Combo 1', 'Combo 2', 'Combo 3'], default_value='Combo 2', key='_COMBO_', enable_events=True,
readonly=False, tooltip='Combo box', disabled=False, size=(12, 1))],
[Listbox(values=('Listbox 1', 'Listbox 2', 'Listbox 3'), enable_events =True, size=(10, 3), key='_LIST_')],
[Slider((1, 100), default_value=80, key='_SLIDER_', visible=True, enable_events=True)],
[Slider((1, 100), default_value=80, key='_SLIDER_', visible=True, enable_events=True, orientation='v')],
[Spin(values=(1, 2, 3), initial_value='2', size=(4, 1), key='_SPIN_', enable_events=True)],
[OK(), Button('Hidden', visible=False, key='_HIDDEN_'), Button('Values'), Button('Exit', button_color=('white', 'red')), Button('UnHide')]
]

View File

@ -8,7 +8,7 @@
![Python Version](https://img.shields.io/badge/Python-3.x-yellow.svg)
![Python Version](https://img.shields.io/badge/PySimpleGUIWeb_-0.9.0-orange.svg?longCache=true&style=for-the-badge)
![Python Version](https://img.shields.io/badge/PySimpleGUIWeb_-0.10.0-orange.svg?longCache=true&style=for-the-badge)
@ -31,7 +31,7 @@ This Readme is for information ***specific to*** the Web port of PySimpleGUI.
PySimpleGUIWeb enables you to run your PySimpleGUI programs in your web browser. It utilizes a package called Remi to achieve this amazing package.
## Engineering Pre-Release Version 0.9.0
## Engineering Pre-Release Version 0.10.0
[Announcements of Latest Developments](https://github.com/MikeTheWatchGuy/PySimpleGUI/issues/142)
@ -79,13 +79,14 @@ PySimpleGUIWeb runs only on Python 3. Legacy Python (2.7) is not supported.
* Listbox Element
* Spinner Element (sorta... numbers 0 to 100 only now)
* Column Element
* Image Element
* Window background color
* Element padding
* Read with timeout
* Read with timeout = 0
* Popup Windows
* Multiple windows
* Update methods for many of the elements (Text is 100% complete), others have some of their parameters working.
# Running online using repl.it
@ -186,6 +187,26 @@ New features
* Support for Window.Hide, Window.UnHide (better multi-window support)
## 0.9.1 PySimpleGUIWeb
* Emergency release due to some code to do scrolling of multiline not being right and sometimes crashed programs
## 0.10.0 PySimpleGUIWeb 16-Feb-2019
* Completed Text.Update method. Can now change:
* Text
* Font family & size
* Background color
* Text Color
* Visibility
* Completed Button.Update with exception of images
* Completed Spin.Update with except of range. This element still pretty crippled
* Completed Slider.Update - Can update value, visibility, disabled, but not the range
* Image Element!
* Events for Image Element
* Image.Update to change image
# Design
# Author
@ -197,6 +218,6 @@ New features
# Acknowledgments
<!--stackedit_data:
eyJoaXN0b3J5IjpbNDc1ODY1Njc2LC0xMDU3MTAzNjQzLDEyMT
MzNTI2MzYsLTExNjA2ODQzMzldfQ==
eyJoaXN0b3J5IjpbLTExNjY3MTk5MTcsNDc1ODY1Njc2LC0xMD
U3MTAzNjQzLDEyMTMzNTI2MzYsLTExNjA2ODQzMzldfQ==
-->

View File

@ -1,6 +1,4 @@
#!/usr/bin/python3
#!/usr/bin/python3
#!/usr/bin/python3
import sys
import wx
@ -15,12 +13,30 @@ import pickle
import os
import time
###### ##### ##### # # ### # #
# # # # # # # # # ##### # ###### # # # # # # # # # #
# # # # # # ## ## # # # # # # # # # # # # #
###### # ##### # # ## # # # # ##### # #### # # # # # # ##
# # # # # # ##### # # # # # # # # # # ##
# # # # # # # # # # # # # # # # # # # #
# # ##### # # # # ###### ###### ##### ##### ### ## ## # #
"""
21-Dec-2018
Welcome to the "core" PySimpleGUIWx port!
'##:::::'##:'##::::'##:'########::'##:::'##:'########:'##::::'##::'#######::'##::: ##:
##:'##: ##:. ##::'##:: ##.... ##:. ##:'##::... ##..:: ##:::: ##:'##.... ##: ###:: ##:
##: ##: ##::. ##'##::: ##:::: ##::. ####:::::: ##:::: ##:::: ##: ##:::: ##: ####: ##:
##: ##: ##:::. ###:::: ########::::. ##::::::: ##:::: #########: ##:::: ##: ## ## ##:
##: ##: ##::: ## ##::: ##.....:::::: ##::::::: ##:::: ##.... ##: ##:::: ##: ##. ####:
##: ##: ##:: ##:. ##:: ##::::::::::: ##::::::: ##:::: ##:::: ##: ##:::: ##: ##:. ###:
. ###. ###:: ##:::. ##: ##::::::::::: ##::::::: ##:::: ##:::: ##:. #######:: ##::. ##:
:...::...:::..:::::..::..::::::::::::..::::::::..:::::..:::::..:::.......:::..::::..::
This marks the 3rd port of the PySimpleGUI GUI SDK. Each port gets a little better than
the previous.
the previous, in theory.
It will take a while for this Wx port to be completed, but should be running with a fully selection
of widgets fairly quickly. The Qt port required 1 week to get to "Alpha" condition
@ -1186,8 +1202,8 @@ class Text(Element):
if self.ParentForm.TKrootDestroyed:
return
if value is not None:
self.WxStaticText.SetLabel(value)
self.DisplayText = value
self.WxStaticText.SetLabel(str(value))
self.DisplayText = str(value)
if background_color is not None:
self.WxStaticText.SetBackgroundColour(background_color)
if text_color is not None:
@ -4254,9 +4270,18 @@ else:
i += 1
# # ######
# # # # # # # # # ##### # # #### # #
# # # # # # # # # # # # # # ## #
# # # ## ###### # # ###### # # # # #
# # # ## # # # # # # # # # #
# # # # # # # # # # # # # ##
## ## # # # # # # # #### # #
# ------------------------------------------------------------------------------------------------------------------ #
# ------------------------------------------------------------------------------------------------------------------ #
# ===================================== TK CODE STARTS HERE ====================================================== #
# ===================================== WxPython CODE STARTS HERE ================================================ #
# ------------------------------------------------------------------------------------------------------------------ #
# ------------------------------------------------------------------------------------------------------------------ #
@ -5479,7 +5504,7 @@ class QuickMeter(object):
layout = []
if self.orientation.lower().startswith('h'):
col = []
col += [[T(arg)] for arg in args]
col += [[T(''.join(map(lambda x: str(x)+'\n',args)),key='_OPTMSG_')]] ### convert all *args into one string that can be updated
col += [[T('', size=(25,8), key='_STATS_')],
[ProgressBar(max_value=self.max_value, orientation='h', key='_PROG_', size=self.size)],
[Cancel(button_color=self.button_color), Stretch()]]
@ -5487,7 +5512,7 @@ class QuickMeter(object):
else:
col = [[ProgressBar(max_value=self.max_value, orientation='v', key='_PROG_', size=self.size)]]
col2 = []
col2 += [[T(arg)] for arg in args]
col2 += [[T(''.join(map(lambda x: str(x)+'\n',args)),key='_OPTMSG_')]] ### convert all *args into one string that can be updated
col2 += [[T('', size=(25,8), key='_STATS_')],
[Cancel(button_color=self.button_color), Stretch()]]
layout = [Column(col), Column(col2)]
@ -5496,11 +5521,12 @@ class QuickMeter(object):
return self.window
def UpdateMeter(self, current_value, max_value):
def UpdateMeter(self, current_value, max_value, *args):
self.current_value = current_value
self.max_value = max_value
self.window.Element('_PROG_').UpdateBar(self.current_value, self.max_value)
self.window.Element('_STATS_').Update('\n'.join(self.ComputeProgressStats()))
self.window.Element('_OPTMSG_').Update(value=''.join(map(lambda x: str(x)+'\n',args))) ### update the string with the args
event, values = self.window.Read(timeout=0)
if event in('Cancel', None) or current_value >= max_value:
self.window.Close()
@ -5548,7 +5574,7 @@ def OneLineProgressMeter(title, current_value, max_value, key, *args, orientatio
else:
meter = QuickMeter.active_meters[key]
rc = meter.UpdateMeter(current_value, max_value)
rc = meter.UpdateMeter(current_value, max_value, *args)
OneLineProgressMeter.exit_reasons = getattr(OneLineProgressMeter,'exit_reasons', QuickMeter.exit_reasons)
return rc == METER_OK
@ -6219,6 +6245,16 @@ def ObjToString(obj, extra=' '):
# Pre-built dialog boxes for all your needs These are the "high level API calls #
# ------------------------------------------------------------------------------------------------------------------ #
######
# # #### ##### # # ##### ####
# # # # # # # # # # #
###### # # # # # # # # ####
# # # ##### # # ##### #
# # # # # # # # #
# #### # #### # ####
# ----------------------------------- The mighty Popup! ------------------------------------------------------------ #
@ -6827,6 +6863,19 @@ def PopupGetText(message, title=None, default_text='', password_char='', size=(N
return input_values[0]
"""
d8b
Y8P
88888b.d88b. 8888b. 888 88888b.
888 "888 "88b "88b 888 888 "88b
888 888 888 .d888888 888 888 888
888 888 888 888 888 888 888 888
888 888 888 "Y888888 888 888 888
"""
def main():
ChangeLookAndFeel('GreenTan')
layout = [

View File

@ -8,11 +8,11 @@
![pysimplegui_logo](https://user-images.githubusercontent.com/13696193/43165867-fe02e3b2-8f62-11e8-9fd0-cc7c86b11772.png)
[![Downloads](http://pepy.tech/badge/pysimplegui)](http://pepy.tech/project/pysimplegui)
[![Downloads ](https://pepy.tech/badge/pysimplegui27)](https://pepy.tech/project/pysimplegui27)
[![Downloads](https://pepy.tech/badge/pysimpleguiqt)](https://pepy.tech/project/pysimpleguiqt)
[![Downloads](https://pepy.tech/badge/pysimpleguiwx)](https://pepy.tech/project/pysimpleguiWx)
[![Downloads](https://pepy.tech/badge/pysimpleguiweb)](https://pepy.tech/project/pysimpleguiWeb)
[![Downloads](http://pepy.tech/badge/pysimplegui)](http://pepy.tech/project/pysimplegui) tkinter
[![Downloads ](https://pepy.tech/badge/pysimplegui27)](https://pepy.tech/project/pysimplegui27) tkinter 2.7
[![Downloads](https://pepy.tech/badge/pysimpleguiqt)](https://pepy.tech/project/pysimpleguiqt) Qt
[![Downloads](https://pepy.tech/badge/pysimpleguiwx)](https://pepy.tech/project/pysimpleguiWx) WxPython
[![Downloads](https://pepy.tech/badge/pysimpleguiweb)](https://pepy.tech/project/pysimpleguiWeb) Web (Remi)
![Documentation Status](https://readthedocs.org/projects/pysimplegui/badge/?version=latest)
![Awesome Meter](https://img.shields.io/badge/Awesome_meter-100-yellow.svg)
![Python Version](https://img.shields.io/badge/Python-2.7_3.x-yellow.svg)
@ -24,9 +24,12 @@
## Supports both Python 2.7 & 3 when using tkinter
## Supports both PySide2 and PyQt5 (limited support)
## PySimpleGUI source code can run either on Qt, tkinter, WxPython, Web (Remi) by changing only the import statement
## Supports both PySide2 and PyQt5 (limited support)
## Effortlessly move across tkinter, Qt, WxPython, and the Web (Remi) by changing only the import statement
## The *only* way to write both desktop and web based GUIs at the same time
@ -38,7 +41,7 @@
![Python Version](https://img.shields.io/badge/PySimpleGUIWx_version-0.3.0-orange.svg?longCache=true&style=for-the-badge)
![Python Version](https://img.shields.io/badge/PySimpleGUIWeb_Version-0.2.2-orange.svg?longCache=true&style=for-the-badge)
![Python Version](https://img.shields.io/badge/PySimpleGUIWeb_Version-0.10.0-orange.svg?longCache=true&style=for-the-badge)
[Announcements of Latest Developments](https://github.com/MikeTheWatchGuy/PySimpleGUI/issues/142)
@ -52,7 +55,7 @@
[Docs in PDF Format](https://github.com/MikeTheWatchGuy/PySimpleGUI/tree/master/docs)
[Run live in a web browser using repl.it!](https://repl.it/@PySimpleGUI/PySimpleGUIWeb-Demos)
[Repl.it Home for PySimpleGUI](https://repl.it/@PySimpleGUI)
Super-simple GUI to use... Powerfully customizable
@ -4973,9 +4976,9 @@ GNU Lesser General Public License (LGPL 3) +
* [GRADESK](https://github.com/sidbmw/ICS4U) - Created by a couple of young talented programmers, this classroom management software combines SQL and a GUI to provide a much improved interface for Ottawa teachers.
<!--stackedit_data:
eyJoaXN0b3J5IjpbLTE1Nzg3NDY1ODgsMjYwNTg0ODE0LDExMD
IwODgzMzMsMTY3OTg1MDk5MiwtMTQ2MTQyODEsLTYwNjM3MTE4
LC01MDkzNTkxMjMsLTI0ODk3NjI5LDEzMDc2OTI1OSwtMjk2Nz
gzNTUsLTc3NDA3NDIzMCwyNjYzNjQ0MTcsNDQ5NDMzMjQzLC0x
MTQ4NDkwNjIzXX0=
eyJoaXN0b3J5IjpbMjA1MzEyNTE0OSwtMTU3ODc0NjU4OCwyNj
A1ODQ4MTQsMTEwMjA4ODMzMywxNjc5ODUwOTkyLC0xNDYxNDI4
MSwtNjA2MzcxMTgsLTUwOTM1OTEyMywtMjQ4OTc2MjksMTMwNz
Y5MjU5LC0yOTY3ODM1NSwtNzc0MDc0MjMwLDI2NjM2NDQxNyw0
NDk0MzMyNDMsLTExNDg0OTA2MjNdfQ==
-->