Fixed flicker problem!!! Updated all of the PySimpleGUIWeb demos

This commit is contained in:
PySimpleGUI 2019-10-30 14:35:01 -04:00
parent f0e1642437
commit a2443c63ad
14 changed files with 413 additions and 298 deletions

View File

@ -1,5 +1,4 @@
# import PySimpleGUIWeb as sg import PySimpleGUIWeb as sg
import PySimpleGUI as sg
import pymunk import pymunk
import random import random
import socket import socket
@ -10,17 +9,20 @@ import socket
Note this exact same demo runs with PySimpleGUIWeb by changing the import statement Note this exact same demo runs with PySimpleGUIWeb by changing the import statement
""" """
class Ball(): class Ball():
def __init__(self, x, y, r, *args, **kwargs): def __init__(self, x, y, r, *args, **kwargs):
mass = 10 mass = 10
self.body = pymunk.Body(mass, self.body = pymunk.Body(mass,
pymunk.moment_for_circle(mass, 0, r, (0, 0))) # Create a Body with mass and moment pymunk.moment_for_circle(mass, 0, r, (0, 0))) # Create a Body with mass and moment
self.body.position = x, y self.body.position = x, y
self.shape = pymunk.Circle(self.body, r, offset=(0, 0)) # Create a box shape and attach to body # Create a box shape and attach to body
self.shape = pymunk.Circle(self.body, r, offset=(0, 0))
self.shape.elasticity = 0.99999 self.shape.elasticity = 0.99999
self.shape.friction = 0.8 self.shape.friction = 0.8
self.gui_circle_figure = None self.gui_circle_figure = None
class Playfield(): class Playfield():
def __init__(self): def __init__(self):
self.space = pymunk.Space() self.space = pymunk.Space()
@ -30,7 +32,7 @@ class Playfield():
self.add_wall(self.space, (600, 0), (600, 400)) # right side self.add_wall(self.space, (600, 0), (600, 400)) # right side
def add_wall(self, space, pt_from, pt_to): def add_wall(self, space, pt_from, pt_to):
body = pymunk.Body(body_type=pymunk.Body.STATIC) body = pymunk.Body(body_type=pymunk.Body.STATIC)
ground_shape = pymunk.Segment(body, pt_from, pt_to, 0.0) ground_shape = pymunk.Segment(body, pt_from, pt_to, 0.0)
ground_shape.friction = 0.8 ground_shape.friction = 0.8
ground_shape.elasticity = .99 ground_shape.elasticity = .99
@ -45,24 +47,25 @@ class Playfield():
ball = Ball(x, y, r) ball = Ball(x, y, r)
self.arena_balls.append(ball) self.arena_balls.append(ball)
area.space.add(ball.body, ball.shape) area.space.add(ball.body, ball.shape)
ball.gui_circle_figure = graph_elem.DrawCircle((x, y), r, fill_color='black', line_color='red') ball.gui_circle_figure = graph_elem.draw_circle(
(x, y), r, fill_color='black', line_color='red')
# ------------------- Build and show the GUI Window ------------------- # ------------------- Build and show the GUI Window -------------------
graph_elem = sg.Graph((600, 400), (0, 400), (600, 0), enable_events=True, key='_GRAPH_', background_color='lightblue') graph_elem = sg.Graph((600, 400), (0, 400), (600, 0),
enable_events=True, key='_GRAPH_', background_color='lightblue')
layout = [[sg.Text('Ball Test'), sg.T('My IP {}'.format(socket.gethostbyname(socket.gethostname())))], layout = [[sg.Text('Ball Test'), sg.Text('My IP {}'.format(socket.gethostbyname(socket.gethostname())))],
[graph_elem], [graph_elem],
[sg.B('Kick'), sg.Button('Exit')]] [sg.Button('Kick'), sg.Button('Exit')]]
window = sg.Window('Window Title', layout, ).Finalize()
window = sg.Window('Window Title', layout, finalize=True)
area = Playfield() area = Playfield()
area.add_balls() area.add_balls()
# ------------------- GUI Event Loop ------------------- # ------------------- GUI Event Loop -------------------
while True: # Event Loop while True: # Event Loop
event, values = window.Read(timeout=0) event, values = window.read(timeout=0)
# print(event, values) # print(event, values)
if event in (None, 'Exit'): if event in (None, 'Exit'):
break break
@ -70,7 +73,9 @@ while True: # Event Loop
for ball in area.arena_balls: for ball in area.arena_balls:
if event == 'Kick': if event == 'Kick':
ball.body.position = ball.body.position[0], ball.body.position[1]-random.randint(1,200) ball.body.position = ball.body.position[0], ball.body.position[1]-random.randint(
graph_elem.RelocateFigure(ball.gui_circle_figure, ball.body.position[0], ball.body.position[1]) 1, 200)
graph_elem.relocate_figure(
ball.gui_circle_figure, ball.body.position[0], ball.body.position[1])
window.Close() window.close()

View File

@ -1,7 +1,5 @@
#!/usr/bin/env python #!/usr/bin/env python
import PySimpleGUIWeb as sg import PySimpleGUIWeb as sg
# import PySimpleGUI as sg
""" """
@ -669,25 +667,26 @@ color_map = {
def detailed_view(window): def detailed_view(window):
layout2 = [[sg.Button(event, button_color=('white', color_map[event]), key=event, tooltip=color_map[color]), layout2 = [[sg.Button(event, button_color=('white', color_map[event]),
sg.Button(event, button_color=('black', color_map[event]), key=event+'1', tooltip=color_map[color])], key=event, tooltip=color_map[color]),
[sg.Txt('Hover over button to see color value. Click to clocse and return to main interface.')], ] sg.Button(event, button_color=('black', color_map[event]),
sg.Window('Buttons with white and black text', layout2, keep_on_top=True).Read() key=event+'1', tooltip=color_map[color])],
window.Close() [sg.Text('Hover over button to see color value. Click to clocse and return to main interface.')], ]
sg.Window('Buttons with white and black text',
layout2, keep_on_top=True).Read()
window.close()
return return
sg.SetOptions(button_element_size=(16,1), auto_size_buttons=False, border_width=0, tooltip_time=100) sg.set_options(button_element_size=(16, 1),
auto_size_buttons=False, border_width=0, tooltip_time=100)
#start layout with the tittle # start layout with the tittle
layout = [[sg.Text('Hover mouse to see RGB value. Click to see Button with White or Black text.', layout = [[sg.Text('Hover mouse to see RGB value. Click to see Button with White or Black text.',
text_color='blue', text_color='blue', background_color='#90EE90',
font=('Hevletica', 20), font=('Hevletica', 20),
relief=sg.RELIEF_SUNKEN, relief=sg.RELIEF_SUNKEN, justification='center',
justification='center', size=(90, 2), pad=(0, 0))]]
size=(90,2),
background_color='#90EE90',
pad=(0,0)),]]
# -- Create primary color viewer window by building rows and appending to layout -- # -- Create primary color viewer window by building rows and appending to layout --
color_list = [key for key in color_map] color_list = [key for key in color_map]
@ -696,14 +695,16 @@ for rows in range(40):
for i in range(12): for i in range(12):
try: try:
color = color_list[rows+40*i] color = color_list[rows+40*i]
row.append(sg.Button(color, button_color=('black', color_map[color]), key=color, tooltip=color_map[color]),) row.append(sg.Button(color,
button_color=('black', color_map[color]), key=color, tooltip=color_map[color]),)
except: except:
pass pass
layout.append(row) layout.append(row)
while True: while True:
window = sg.Window('Color Viewer', layout, font=('any 12'), default_button_element_size=(12,1), element_padding=(0,0)) window = sg.Window('Color Viewer', layout, font=('any 12'),
event, values = window.Read() default_button_element_size=(12, 1), element_padding=(0, 0))
event, values = window.read()
if event is None: if event is None:
break break
detailed_view(window) detailed_view(window)

View File

@ -1,5 +1,4 @@
#!/usr/bin/env python #!/usr/bin/env python
import sys
import PySimpleGUIWeb as sg import PySimpleGUIWeb as sg
""" """
@ -12,7 +11,6 @@ import PySimpleGUIWeb as sg
""" """
COLORS = ['snow', 'ghost white', 'white smoke', 'gainsboro', 'floral white', 'old lace', COLORS = ['snow', 'ghost white', 'white smoke', 'gainsboro', 'floral white', 'old lace',
'linen', 'antique white', 'papaya whip', 'blanched almond', 'bisque', 'peach puff', 'linen', 'antique white', 'papaya whip', 'blanched almond', 'bisque', 'peach puff',
'navajo white', 'lemon chiffon', 'mint cream', 'azure', 'alice blue', 'lavender', 'navajo white', 'lemon chiffon', 'mint cream', 'azure', 'alice blue', 'lavender',
@ -91,11 +89,11 @@ COLORS = ['snow', 'ghost white', 'white smoke', 'gainsboro', 'floral white', 'ol
'grey93', 'grey94', 'grey95', 'grey97', 'grey98', 'grey99'] 'grey93', 'grey94', 'grey95', 'grey97', 'grey98', 'grey99']
sg.set_options(button_element_size=(12, 1),
element_padding=(0, 0), auto_size_buttons=False, border_width=0)
layout = [[sg.Text('Click on a color square to see both white and black text on that color',
sg.SetOptions(button_element_size=(12,1), element_padding=(0,0), auto_size_buttons=False, border_width=0) text_color='blue', font='Any 15')]]
layout = [[sg.Text('Click on a color square to see both white and black text on that color', text_color='blue', font='Any 15')]]
row = [] row = []
layout = [] layout = []
# -- Create primary color viewer window -- # -- Create primary color viewer window --
@ -117,13 +115,16 @@ for rows in range(40):
# layout.append(row) # layout.append(row)
# row = [] # row = []
window = sg.Window('Color Viewer', grab_anywhere=False, font=('any 9')).Layout(layout) window = sg.Window('Color Viewer', layout,
grab_anywhere=False, font=('any 9'))
# -- Event loop -- # -- Event loop --
while True: while True:
event, values = window.Read() event, values = window.read()
if event is None: if event is None:
break break
# -- Create a secondary window that shows white and black text on chosen color # -- Create a secondary window that shows white and black text on chosen color
layout2 =[[sg.DummyButton(event, button_color=('white', event)), sg.DummyButton(event, button_color=('black', event))]] layout2 = [[sg.DummyButton(event, button_color=('white', event)),
sg.Window('Buttons with white and black text', keep_on_top=True).Layout(layout2).Read(timeout=0) sg.DummyButton(event, button_color=('black', event))]]
sg.Window('Buttons with white and black text',
layout2, keep_on_top=True).read(timeout=0)

View File

@ -9,21 +9,30 @@ In other words, the slider and the spinner are essentially connected together
fontsize = 12 # initial and smallest font size to show fontsize = 12 # initial and smallest font size to show
layout = [[sg.Spin([sz for sz in range(6, 172)], size=(6,1), font=('Helvetica 20'), initial_value=fontsize, change_submits=True, key='spin'), layout = [
sg.Slider(range=(6,172), orientation='h', size=(10,20), change_submits=True, key='slider', font=('Helvetica 20')), [sg.Spin([sz for sz in range(6, 172)], size=(6, 1),
sg.Text("Aa", size=(2, 1), font="Helvetica " + str(fontsize), key='text')],] font=('Helvetica 20'), initial_value=fontsize,
change_submits=True, key='spin'),
sg.Slider(range=(6, 172), orientation='h', size=(10, 20),
change_submits=True, key='slider', font=('Helvetica 20')),
sg.Text("Aa", size=(2, 1), font="Helvetica " + str(fontsize), key='text')]
]
window = sg.Window("Font size selector").Layout(layout) window = sg.Window("Font size selector", layout)
while True: # the event loop while True: # the event loop
event, values= window.Read() event, values = window.read()
if event is None or event == 'Quit': if event is None or event == 'Quit':
break break
fontsize = int(values['spin']) if int(values['spin']) != fontsize else int(values['slider'])
font = "Helvetica " + str(fontsize) if int(values['spin']) != fontsize:
window.FindElement('text').Update(font=font) fontsize = int(values['spin'])
window.FindElement('slider').Update(fontsize, range=(10,20)) else:
window.FindElement('spin').Update(fontsize) fontsize = int(values['slider'])
window.Close()
window['text'].update(font="Helvetica " + str(fontsize))
window['slider'].update(fontsize, range=(10, 20))
window['spin'].update(fontsize)
window.close()
print("Done.") print("Done.")

View File

@ -1,16 +1,11 @@
#!/usr/bin/env python #!/usr/bin/env python
import sys
import PySimpleGUIWeb as sg import PySimpleGUIWeb as sg
import subprocess import subprocess
import howdoi import howdoi
# Test this command in a dos window if you are having trouble. # Test this command in a dos window if you are having trouble.
HOW_DO_I_COMMAND = 'python -m howdoi.howdoi' HOW_DO_I_COMMAND = 'python -m howdoi.howdoi'
# if you want an icon on your taskbar for this gui, then change this line of code to point to the ICO file
DEFAULT_ICON = 'E:\\TheRealMyDocs\\Icons\\QuestionMark.ico'
def HowDoI(): def HowDoI():
''' '''
Make and show a window (PySimpleGUI form) that takes user input and sends to the HowDoI web oracle Make and show a window (PySimpleGUI form) that takes user input and sends to the HowDoI web oracle
@ -20,52 +15,69 @@ def HowDoI():
:return: never returns :return: never returns
''' '''
# ------- Make a new Window ------- # # ------- Make a new Window ------- #
sg.ChangeLookAndFeel('GreenTan') # give our form a spiffy set of colors sg.change_look_and_feel('GreenTan') # give our form a spiffy set of colors
layout = [ layout = [
[sg.Text('Ask and your answer will appear here....', size=(40, 1))], [sg.Text('Ask and your answer will appear here....', size=(40, 1))],
[sg.MultilineOutput(size_px=(980, 400),key='_OUTPUT_' )], [sg.MLineOutput(size_px=(980, 400),key='_OUTPUT_' )],
# [ sg.Spin(values=(1, 2, 3, 4), initial_value=1, size=(2, 1), key='Num Answers', font='Helvetica 15'), # [ sg.Spin(values=(1, 2, 3, 4), initial_value=1, size=(2, 1), key='Num Answers', font='Helvetica 15'),
[ sg.Checkbox('Display Full Text', key='full text', font='Helvetica 15'), [ sg.CBox('Display Full Text', key='full text', font='Helvetica 15'),
sg.T('Command History', font='Helvetica 15'), sg.T('', size=(40,3), text_color=sg.BLUES[0], key='history')], sg.Text('Command History', font='Helvetica 15'), sg.Text('', size=(40,3), text_color=sg.BLUES[0], key='history')],
[sg.Multiline(size=(85, 5), enter_submits=True, key='query', do_not_clear=False), [sg.MLine(size=(85, 5), enter_submits=True, key='query', do_not_clear=False),
sg.ReadButton('SEND', button_color=(sg.YELLOWS[0], sg.BLUES[0]), bind_return_key=True), sg.ReadButton('SEND', button_color=(sg.YELLOWS[0], sg.BLUES[0]), bind_return_key=True),
sg.Button('EXIT', button_color=(sg.YELLOWS[0], sg.GREENS[0]))] sg.Button('EXIT', button_color=(sg.YELLOWS[0], sg.GREENS[0]))]
] ]
window = sg.Window('How Do I ??', default_element_size=(30,1), icon=DEFAULT_ICON, font=('Helvetica',' 17'), default_button_element_size=(8,2), return_keyboard_events=False, ) window = sg.Window('How Do I?', layout, default_element_size=(30,1),
window.Layout(layout) font=('Helvetica',' 17'), default_button_element_size=(8,2),
return_keyboard_events=False)
# ---===--- Loop taking in user input and using it to query HowDoI --- # # ---===--- Loop taking in user input and using it to query HowDoI --- #
command_history = [] command_history = []
history_offset = 0 history_offset = 0
while True: while True:
event, values = window.Read() event, values = window.Read()
# print(event, values) # print(event, values)
if type(event) is int: if type(event) is int:
event = str(event) event = str(event)
if event == 'SEND': if event == 'SEND':
query = values['query'].rstrip() query = values['query'].rstrip()
window.Element('_OUTPUT_').Update(query, append=True) window['_OUTPUT_'].update(query, append=True)
print(query) print(query)
QueryHowDoI(query, 1, values['full text'], window) # send the string to HowDoI QueryHowDoI(query, 1, values['full text'], window) # send the string to HowDoI
command_history.append(query) command_history.append(query)
history_offset = len(command_history)-1 history_offset = len(command_history)-1
window.FindElement('query').Update('') # manually clear input because keyboard events blocks clear
window.FindElement('history').Update('\n'.join(command_history[-3:]))
elif event == None or event == 'EXIT': # if exit button or closed using X
break
elif 'Up' in event and len(command_history): # scroll back in history
command = command_history[history_offset]
history_offset -= 1 * (history_offset > 0) # decrement is not zero
window.FindElement('query').Update(command)
elif 'Down' in event and len(command_history): # scroll forward in history
history_offset += 1 * (history_offset < len(command_history)-1) # increment up to end of list
command = command_history[history_offset]
window.FindElement('query').Update(command)
elif 'Escape' in event: # clear currently line
window.FindElement('query').Update('')
window.Close() # manually clear input because keyboard events blocks clear
window['query'].update('')
window['history'].update('\n'.join(command_history[-3:]))
# if exit button or closed using X
elif event == None or event == 'EXIT':
break
# scroll back in history
elif 'Up' in event and len(command_history):
command = command_history[history_offset]
# decrement is not zero
history_offset -= 1 * (history_offset > 0)
window['query'].update(command)
# scroll forward in history
elif 'Down' in event and len(command_history):
# increment up to end of list
history_offset += 1 * (history_offset < len(command_history)-1)
command = command_history[history_offset]
window['query'].update(command)
# clear currently line
elif 'Escape' in event:
window['query'].update('')
window.close()
def QueryHowDoI(Query, num_answers, full_text, window:sg.Window): def QueryHowDoI(Query, num_answers, full_text, window:sg.Window):
''' '''
@ -78,9 +90,9 @@ def QueryHowDoI(Query, num_answers, full_text, window:sg.Window):
full_text_option = ' -a' if full_text else '' full_text_option = ' -a' if full_text else ''
t = subprocess.Popen(howdoi_command + ' \"'+ Query + '\" -n ' + str(num_answers)+full_text_option, stdout=subprocess.PIPE) t = subprocess.Popen(howdoi_command + ' \"'+ Query + '\" -n ' + str(num_answers)+full_text_option, stdout=subprocess.PIPE)
(output, err) = t.communicate() (output, err) = t.communicate()
window.Element('_OUTPUT_').Update('{:^88}'.format(Query.rstrip()), append=True) window['_OUTPUT_'].update('{:^88}'.format(Query.rstrip()), append=True)
window.Element('_OUTPUT_').Update('_'*60, append=True) window['_OUTPUT_'].update('_'*60, append=True)
window.Element('_OUTPUT_').Update(output.decode("utf-8"), append=True) window['_OUTPUT_'].update(output.decode("utf-8"), append=True)
exit_code = t.wait() exit_code = t.wait()
if __name__ == '__main__': if __name__ == '__main__':

View File

@ -1,6 +1,4 @@
#!/usr/bin/env python #!/usr/bin/env python
import sys
import sys
import PySimpleGUIWeb as sg import PySimpleGUIWeb as sg
import psutil import psutil
import time import time
@ -26,6 +24,7 @@ g_cpu_percent = 0
g_procs = None g_procs = None
g_exit = False g_exit = False
def CPU_thread(args): def CPU_thread(args):
global g_interval, g_cpu_percent, g_procs, g_exit global g_interval, g_cpu_percent, g_procs, g_exit
@ -41,30 +40,30 @@ def main():
global g_interval, g_procs, g_exit global g_interval, g_procs, g_exit
# ---------------- Create Form ---------------- # ---------------- Create Form ----------------
sg.ChangeLookAndFeel('Black') sg.change_look_and_feel('Black')
layout = [[sg.Text('', size=(8,1), font=('Helvetica', 20),text_color=sg.YELLOWS[0], layout = [[sg.Text('', size=(8, 1), font=('Helvetica', 20), text_color=sg.YELLOWS[0],
justification='center', key='text')], justification='center', key='text')],
[sg.Text('', size=(30, 8), font=('Courier New', 12),text_color='white', justification='left', key='processes')], [sg.Text('', size=(30, 8), font=('Courier New', 12),
[sg.Exit(button_color=('white', 'firebrick4'), pad=((15,0), 0), size=(9,1)),] text_color='white', justification='left', key='processes')],
] [sg.Exit(button_color=('white', 'firebrick4'),
pad=((15, 0), 0), size=(9, 1)), ]
]
window = sg.Window('CPU Utilization', window = sg.Window('CPU Utilization', layout,
no_titlebar=True, no_titlebar=True, keep_on_top=True, alpha_channel=.8, grab_anywhere=True)
keep_on_top=True,
alpha_channel=.8,
grab_anywhere=True).Layout(layout)
# start cpu measurement thread # start cpu measurement thread
thread = Thread(target=CPU_thread,args=(None,), daemon=True) thread = Thread(target=CPU_thread, args=(None,), daemon=True)
thread.start() thread.start()
timeout_value = 1 # make first read really quick timeout_value = 1 # make first read really quick
g_interval = 1 g_interval = 1
# ---------------- main loop ---------------- # ---------------- main loop ----------------
while (True): while True:
# --------- Read and update window -------- # --------- Read and update window --------
event, values = window.Read(timeout=timeout_value, timeout_key='Timeout') event, values = window.read(
timeout=timeout_value, timeout_key='Timeout')
# --------- Do Button Operations -------- # --------- Do Button Operations --------
if event is None or event == 'Exit': if event in (None, 'Exit'):
break break
timeout_value = 1000 timeout_value = 1000
@ -74,11 +73,12 @@ def main():
if g_procs: if g_procs:
# --------- Create list of top % CPU porocesses -------- # --------- Create list of top % CPU porocesses --------
try: try:
top = {proc.name() : proc.cpu_percent() for proc in g_procs} top = {proc.name(): proc.cpu_percent() for proc in g_procs}
except: pass except:
pass
top_sorted = sorted(
top_sorted = sorted(top.items(), key=operator.itemgetter(1), reverse=True) top.items(), key=operator.itemgetter(1), reverse=True)
if top_sorted: if top_sorted:
top_sorted.pop(0) top_sorted.pop(0)
display_string = '' display_string = ''
@ -86,10 +86,11 @@ def main():
display_string += '{:2.2f} {}\n'.format(cpu/10, proc) display_string += '{:2.2f} {}\n'.format(cpu/10, proc)
# --------- Display timer and proceses in window -------- # --------- Display timer and proceses in window --------
window.FindElement('text').Update('CPU {}'.format(cpu_percent)) window['text'].update('CPU {}'.format(cpu_percent))
window.FindElement('processes').Update(display_string) window['processes'].update(display_string)
window.close()
window.Close()
if __name__ == "__main__": if __name__ == "__main__":
main() main()

View File

@ -16,19 +16,20 @@ print('Starting up...')
layout = [ layout = [
[sg.Text('Your typed chars appear here:'), sg.Text('', key='_OUTPUT_')], [sg.Text('Your typed chars appear here:'), sg.Text('', key='_OUTPUT_')],
[sg.Input(do_not_clear=True, key='_IN_')], [sg.Input('', key='_IN_')],
[sg.Button('Show'), sg.Button('Exit'), sg.Button('Blank')] [sg.Button('Show'), sg.Button('Exit'), sg.Button('Blank')]
] ]
window = sg.Window('Window Title').Layout(layout) window = sg.Window('Window Title', layout)
while True: # Event Loop while True: # Event Loop
print('in event loop') print('in event loop')
event, values = window.Read() event, values = window.read()
print(event, values) print(event, values)
if event is None or event == 'Exit': if event in (None, 'Exit'):
break break
if event == 'Show': if event == 'Show':
sg.Popup('A popup!', ' You typed ', values['_IN_']) sg.popup('A popup!', ' You typed ', values['_IN_'])
window.Close() window.close()

View File

@ -1,26 +1,28 @@
import PySimpleGUIWeb as sg import PySimpleGUIWeb as sg
# Basic example of PSGWeb
def main(): def main():
layout = [ layout = [
[sg.Text('This is a text element')], [sg.Text('This is a text element')],
[sg.Input()], [sg.Input()],
[sg.Combo(['Combo 1'])], [sg.Combo(['Combo 1'])],
[sg.Text('If you close the browser tab, the app will exit gracefully')], [sg.Text('If you close the browser tab, the app will exit gracefully')],
[sg.InputText('Source', do_not_clear=True)], [sg.InputText('Source')],
[sg.InputText('Dest', do_not_clear=True)], [sg.InputText('Dest')],
[sg.Ok(), sg.Cancel()] [sg.Ok(), sg.Cancel()]
] ]
window = sg.Window('Demo window..').Layout(layout) window = sg.Window('Demo window..', layout)
i = 0 i = 0
while True: while True:
event, values = window.Read(timeout=1) event, values = window.read(timeout=1)
if event != sg.TIMEOUT_KEY: if event != sg.TIMEOUT_KEY:
print(event, values) print(event, values)
if event is None: if event is None:
break break
i += 1 i += 1
window.Close() window.close()
main() main()
print('Program terminating normally') print('Program terminating normally')

View File

@ -2,69 +2,42 @@ import PySimpleGUIWeb as sg
import random import random
import string import string
""" # Example with Table element
ooooooooooooo .o8 oooo
8' 888 `8 "888 `888
888 .oooo. 888oooo. 888 .ooooo.
888 `P )88b d88' `88b 888 d88' `88b
888 .oP"888 888 888 888 888ooo888
888 d8( 888 888 888 888 888 .o
o888o `Y888""8o `Y8bod8P' o888o `Y8bod8P'
def word():
return ''.join(random.choice(string.ascii_lowercase) for i in range(10))
def number(max_val=1000):
oooooooooooo oooo . return random.randint(0,max_val)
`888' `8 `888 .o8
888 888 .ooooo. ooo. .oo. .oo. .ooooo. ooo. .oo. .o888oo
888oooo8 888 d88' `88b `888P"Y88bP"Y88b d88' `88b `888P"Y88b 888
888 " 888 888ooo888 888 888 888 888ooo888 888 888 888
888 o 888 888 .o 888 888 888 888 .o 888 888 888 .
o888ooooood8 o888o `Y8bod8P' o888o o888o o888o `Y8bod8P' o888o o888o "888"
"""
# ------------------ Create a fake table ------------------
class Fake():
@classmethod
def word(self):
return ''.join(random.choice(string.ascii_lowercase) for i in range(10))
@classmethod
def number(self, max=1000):
return random.randint(0,max)
def make_table(num_rows, num_cols): def make_table(num_rows, num_cols):
data = [[j for j in range(num_cols)] for i in range(num_rows)] data = [[j for j in range(num_cols)] for i in range(num_rows)]
data[0] = [Fake.word() for _ in range(num_cols)] data[0] = [word() for _ in range(num_cols)]
for i in range(1, num_rows): for i in range(1, num_rows):
data[i] = [Fake.word(), *[Fake.number() for i in range(num_cols - 1)]] data[i] = [word(), *[number() for i in range(num_cols - 1)]]
return data return data
table_data = make_table(num_rows=15, num_cols=6) table_data = make_table(num_rows=15, num_cols=6)
# ------------------ Create a window layout ------------------ # ------------------ Create a window layout ------------------
layout = [[sg.Table(values=table_data, layout = [[sg.Table(values=table_data, enable_events=True,
enable_events=True, display_row_numbers=True, font='Courier 14',
display_row_numbers=True, row_header_text='Row #', key='_table_', text_color='red')],
font='Courier 14',
row_header_text='Row #',
key='_table_',
text_color='red')],
[sg.Button('Exit')], [sg.Button('Exit')],
[sg.T('Selected rows = '), sg.T('', size=(30,1), key='_selected_rows_')], [sg.Text('Selected rows = '), sg.Text('', size=(30,1), key='_selected_rows_')],
[sg.T('Selected value = '), sg.T('', size=(30,1), key='_selected_value_')]] [sg.Text('Selected value = '), sg.Text('', size=(30,1), key='_selected_value_')]]
# ------------------ Create the window ------------------ # ------------------ Create the window ------------------
window = sg.Window('Table Element Example').Layout(layout) window = sg.Window('Table Element Example', layout)
# ------------------ The Event Loop ------------------ # ------------------ The Event Loop ------------------
while True: while True:
event, values = window.Read() event, values = window.read()
print(event, values) print(event, values)
if event in (None, 'Exit'): if event in (None, 'Exit'):
break break
window.Element('_selected_rows_').Update(values['_table_']) window['_selected_rows_'].update(values['_table_'])
window.Element('_selected_value_').Update(window.Element('_table_').SelectedItem) window['_selected_value_'].update(window['_table_'].SelectedItem)
# ------------------ User closed window so exit ------------------ # ------------------ User closed window so exit ------------------
window.Close() window.close()

View File

@ -1,57 +1,62 @@
#!/usr/bin/env python #!/usr/bin/env python
import PySimpleGUIWeb as sg import PySimpleGUIWeb as sg
import time import time
import sys
# ---------------- Create Form ---------------- # ---------------- Create Form ----------------
layout = [ layout = [
[sg.Text('', background_color='black')], [sg.Text('', background_color='black')],
[sg.Text('00:00', size=(30, 1), font=('Helvetica', 30), justification='center', text_color='white', key='text', background_color='black')], [sg.Text('00:00', size=(30, 1), font=('Helvetica', 30), justification='center',
text_color='white', key='text', background_color='black')],
[sg.Text('', background_color='black')], [sg.Text('', background_color='black')],
[sg.Button('Pause', key='button', button_color=('white', '#001480')), [sg.Button('Pause', key='button', button_color=('white', '#001480')),
sg.Button('Reset', button_color=('white', '#007339'), key='Reset'), sg.Button('Reset', button_color=('white', '#007339'), key='Reset'),
sg.Exit(button_color=('white', '#8B1A1A'), key='Exit', )], sg.Exit(button_color=('white', '#8B1A1A'), key='Exit', )],
] ]
window = sg.Window('Running Timer', background_color='black', font='Helvetica 18').Layout(layout) window = sg.Window('Running Timer', layout,
background_color='black', font='Helvetica 18')
# ---------------- main loop ---------------- # ---------------- main loop ----------------
current_time = 0 current_time = 0
paused = False paused = False
start_time = int(round(time.time() * 100)) start_time = int(round(time.time() * 100))
while (True): while True:
# --------- Read and update window -------- # --------- read and update window --------
if not paused: if not paused:
event, values = window.Read(timeout=0) event, values = window.read(timeout=0)
current_time = int(round(time.time() * 100)) - start_time current_time = int(round(time.time() * 100)) - start_time
else: else:
event, values = window.Read() event, values = window.read()
print(event, values) if event != sg.TIMEOUT_KEY else None print(event, values) if event != sg.TIMEOUT_KEY else None
if event == 'button': if event == 'button':
event = window.FindElement(event).GetText() event = window[event].GetText()
# --------- Do Button Operations -------- # --------- Do Button Operations --------
if event in (None, 'Exit'): # ALWAYS give a way out of program if event in (None, 'Exit'): # ALWAYS give a way out of program
break break
if event == 'Reset': if event == 'Reset':
start_time = int(round(time.time() * 100)) start_time = int(round(time.time() * 100))
current_time = 0 current_time = 0
paused_time = start_time paused_time = start_time
elif event == 'Pause': elif event == 'Pause':
paused = True paused = True
paused_time = int(round(time.time() * 100)) paused_time = int(round(time.time() * 100))
element = window.FindElement('button') element = window['button']
element.Update(text='Run') element.update(text='Run')
elif event == 'Run': elif event == 'Run':
paused = False paused = False
start_time = start_time + int(round(time.time() * 100)) - paused_time start_time = start_time + int(round(time.time() * 100)) - paused_time
element = window.FindElement('button') element = window['button']
element.Update(text='Pause') element.update(text='Pause')
# --------- Display timer in window -------- # --------- Display timer in window --------
window.FindElement('text').Update('{:02d}:{:02d}.{:02d}'.format((current_time // 100) // 60, window['text'].update('{:02d}:{:02d}.{:02d}'.format((current_time // 100) // 60,
(current_time // 100) % 60, (current_time //
current_time % 100)) 100) % 60,
current_time % 100))
# --------- After loop -------- # --------- After loop --------
window.Close() window.close()
print('after loop')
sys.exit()

View File

@ -3,43 +3,48 @@ import datetime
DEFAULT_BASE64_ICON = b'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' DEFAULT_BASE64_ICON = b'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'
layout = [
[sg.Text('PySimpleGUIWeb running on the web and in your browser!',
size=(60, 1), font=('Comic sans ms', 20), text_color='red')],
[sg.Text('This program has been running for... ', size=(30, 1)),
sg.Text('', size=(30, 1), key='_DATE_')],
sg.ChangeLookAndFeel('GreenTan') [sg.Text('', size=(30, 1), key='_TEXT_')],
[sg.Input('Single Line Input', enable_events=True, size=(30, 1))],
# [sg.MultiLine('Multiline Input', size=(40, 4), enable_events=True)],
# [sg.MultiLine('Multiline Output', size=(80, 8),
# key='_MULTIOUT_', font='Courier 12')],
layout = [ [sg.CBox('Checkbox 1', enable_events=True, key='_CB1_'),
[sg.Text('PySimpleGUIWeb running on the web and in your browser!', size=(60,1), font=('Comic sans ms', 20), text_color='red')], sg.CBox('Checkbox 2', default=True,
[sg.Text('This program has been running for... ', size=(30,1)),sg.Text('', size=(30,1), key='_DATE_')], enable_events=True, key='_CB2_')],
[sg.Text('', size=(30,1), key='_TEXT_')],
[sg.Input('Single Line Input', do_not_clear=True, enable_events=True, size=(30,1))],
[sg.Multiline('Multiline Input', do_not_clear=True, size=(40,4), enable_events=True)],
[sg.Multiline('Multiline Output', size=(80,8), key='_MULTIOUT_', font='Courier 12')],
[sg.Checkbox('Checkbox 1', enable_events=True, key='_CB1_'), sg.Checkbox('Checkbox 2', default=True, enable_events=True, key='_CB2_')],
[sg.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))],
[sg.Listbox(values=('Listbox 1', 'Listbox 2', 'Listbox 3'), size=(10,3))],
[sg.Slider((1,100), default_value=80, key='_SLIDER_', visible=True, enable_events=True, orientation='h')],
[sg.Spin(values=(1,2,3),initial_value=2, size=(4,1))],
[sg.Image(filename=r'dot:logo.jpg')],
[sg.OK(), sg.Button('Exit', button_color=('white', 'red'))]
]
window = sg.Window('My PySimpleGUIWeb Window', [sg.Combo(values=['Combo 1', 'Combo 2', 'Combo 3'], default_value='Combo 2', key='_COMBO_',
default_element_size=(30,1), enable_events=True, readonly=False, tooltip='Combo box', disabled=False, size=(12, 1))],
font='Helvetica 18',
background_image=r'dot:logo.jpg' [sg.Listbox(values=('Listbox 1', 'Listbox 2',
).Layout(layout) 'Listbox 3'), size=(10, 3))],
[sg.Slider((1, 100), default_value=80, key='_SLIDER_',
visible=True, enable_events=True, orientation='h')],
[sg.Spin(values=(1, 2, 3), initial_value=2, size=(4, 1))],
[sg.Image(filename=r'dot:logo.jpg')],
[sg.OK(), sg.Button('Exit', button_color=('white', 'red'))]
]
window = sg.Window('My PySimpleGUIWeb Window', layout,
default_element_size=(30, 1), font='Helvetica 18')
start_time = datetime.datetime.now() start_time = datetime.datetime.now()
while True: while True:
event, values = window.Read(timeout=10) event, values = window.read(timeout=10)
if event != sg.TIMEOUT_KEY: if event != sg.TIMEOUT_KEY:
print(event, values) print(event, values)
window.Element('_MULTIOUT_').Update(str(event) + '\n' + str(values), append=True) window['_MULTIOUT_'].update(
str(event) + '\n' + str(values), append=True)
if event in (None, 'Exit'): if event in (None, 'Exit'):
break break
window.Element('_DATE_').Update(str(datetime.datetime.now()-start_time)) window['_DATE_'].update(str(datetime.datetime.now()-start_time))
window.Close()
window.close()

View File

@ -1,6 +1,4 @@
#!/usr/bin/env python #!/usr/bin/env python
import sys
import sys
import PySimpleGUIWeb as sg import PySimpleGUIWeb as sg
import os import os
import signal import signal
@ -13,6 +11,7 @@ import operator
Based on psutil package that is easily installed using pip Based on psutil package that is easily installed using pip
""" """
def kill_proc_tree(pid, sig=signal.SIGTERM, include_parent=True, def kill_proc_tree(pid, sig=signal.SIGTERM, include_parent=True,
timeout=None, on_terminate=None): timeout=None, on_terminate=None):
"""Kill a process tree (including grandchildren) with signal """Kill a process tree (including grandchildren) with signal
@ -35,32 +34,31 @@ def kill_proc_tree(pid, sig=signal.SIGTERM, include_parent=True,
def main(): def main():
# ---------------- Create Form ----------------
# sg.ChangeLookAndFeel('Topanga')
layout = [[sg.Text('Process Killer - Choose one or more processes', layout = [[sg.Text('Process Killer - Choose one or more processes',
size=(45,1), font=('Helvetica', 15), text_color='red')], size=(45, 1), font=('Helvetica', 15), text_color='red')],
[sg.Listbox(values=[' '], size=(50, 30), select_mode=sg.SELECT_MODE_EXTENDED, font=('Courier', 12), key='_processes_')],
[sg.Listbox(values=[' '], size=(50, 30),
select_mode=sg.SELECT_MODE_EXTENDED, font=('Courier', 12), key='_processes_')],
[sg.Text('Click refresh once or twice.. once for list, second to get CPU usage')], [sg.Text('Click refresh once or twice.. once for list, second to get CPU usage')],
[sg.T('Filter by typing name', font='ANY 14'), sg.In(size=(15,1), font='any 14', key='_filter_')], [sg.Text('Filter by typing name', font='ANY 14'), sg.Input(
size=(15, 1), font='any 14', key='_filter_')],
[sg.Button('Sort by Name', ), [sg.Button('Sort by Name', ),
sg.Button('Sort by % CPU', button_color=('white', 'DarkOrange2')), sg.Button('Sort by % CPU', button_color=('white', 'DarkOrange2')),
sg.Button('Kill', button_color=('white','red'), bind_return_key=True), sg.Button('Kill', button_color=('white', 'red'), bind_return_key=True),
sg.Exit(button_color=('white', 'sea green'))]] sg.Exit(button_color=('white', 'sea green'))]]
window = sg.Window('Process Killer', window = sg.Window('Process Killer', layout,
keep_on_top=True, keep_on_top=True, auto_size_buttons=False,
auto_size_buttons=False, default_button_element_size=(12, 1), return_keyboard_events=True)
default_button_element_size=(12,1),
return_keyboard_events=True,
).Layout(layout)
display_list = None display_list = None
# ---------------- main loop ---------------- # ---------------- main loop ----------------
while (True): while True:
# --------- Read and update window -------- # --------- Read and update window --------
event, values = window.Read() event, values = window.Read()
if event is None or event == 'Exit': if event in (None, 'Exit'):
break break
# skip mouse, control key and shift key events entirely # skip mouse, control key and shift key events entirely
@ -71,40 +69,46 @@ def main():
if event == 'Sort by Name': if event == 'Sort by Name':
psutil.cpu_percent(interval=.1) psutil.cpu_percent(interval=.1)
procs = psutil.process_iter() procs = psutil.process_iter()
all_procs = [[proc.cpu_percent(), proc.name(), proc.pid] for proc in procs] all_procs = [[proc.cpu_percent(), proc.name(), proc.pid]
sorted_by_cpu_procs = sorted(all_procs, key=operator.itemgetter(1), reverse=False) for proc in procs]
sorted_by_cpu_procs = sorted(
all_procs, key=operator.itemgetter(1), reverse=False)
display_list = [] display_list = []
for process in sorted_by_cpu_procs: for process in sorted_by_cpu_procs:
display_list.append('{:5d} {:5.2f} {}\n'.format(process[2], process[0]/10, process[1])) display_list.append('{:5d} {:5.2f} {}\n'.format(
window.FindElement('_processes_').Update(display_list) process[2], process[0]/10, process[1]))
window['_processes_'].update(display_list)
print(display_list) print(display_list)
elif event == 'Kill': elif event == 'Kill':
processes_to_kill = values['_processes_'] processes_to_kill = values['_processes_']
for proc in processes_to_kill: for proc in processes_to_kill:
pid = int(proc[0:5]) pid = int(proc[0:5])
# if sg.PopupYesNo('About to kill {} {}'.format(pid, proc[12:]), keep_on_top=True) == 'Yes': # if sg.popupYesNo('About to kill {} {}'.format(pid, proc[12:]), keep_on_top=True) == 'Yes':
try: try:
kill_proc_tree(pid=pid) kill_proc_tree(pid=pid)
except: except:
sg.PopupAutoClose('Error killing process', auto_close_duration=1) sg.popup_auto_close(
'Error killing process', auto_close_duration=1)
elif event == 'Sort by % CPU': elif event == 'Sort by % CPU':
psutil.cpu_percent(interval=.1) psutil.cpu_percent(interval=.1)
procs = psutil.process_iter() procs = psutil.process_iter()
all_procs = [[proc.cpu_percent(), proc.name(), proc.pid] for proc in procs] all_procs = [[proc.cpu_percent(), proc.name(), proc.pid]
sorted_by_cpu_procs = sorted(all_procs, key=operator.itemgetter(0), reverse=True) for proc in procs]
sorted_by_cpu_procs = sorted(
all_procs, key=operator.itemgetter(0), reverse=True)
display_list = [] display_list = []
for process in sorted_by_cpu_procs: for process in sorted_by_cpu_procs:
display_list.append('{:5d} {:5.2f} {}\n'.format(process[2], process[0]/10, process[1])) display_list.append('{:5d} {:5.2f} {}\n'.format(
window.FindElement('_processes_').Update(display_list) process[2], process[0]/10, process[1]))
window['_processes_'].update(display_list)
else: # was a typed character else: # was a typed character
if display_list is not None: if display_list is not None:
new_output = [] new_output = []
for line in display_list: for line in display_list:
if values['_filter_'] in line.lower(): if values['_filter_'] in line.lower():
new_output.append(line) new_output.append(line)
window.FindElement('_processes_').Update(new_output) window['_processes_'].update(new_output)
window.close()
if __name__ == "__main__": if __name__ == "__main__":
main() main()
sys.exit(0)

View File

@ -23,32 +23,39 @@ class MyApp(App):
def idle(self): def idle(self):
self.counter.set_text('Running Time: ' + str(self.count)) self.counter.set_text('Running Time: ' + str(self.count))
self.progress.set_value(self.count%100) self.progress.set_value(self.count % 100)
def main(self): def main(self):
# the margin 0px auto centers the main container # the margin 0px auto centers the main container
verticalContainer = gui.Widget(width=540, margin='0px auto', style={'display': 'block', 'overflow': 'hidden'}) verticalContainer = gui.Widget(width=540, margin='0px auto', style={
'display': 'block', 'overflow': 'hidden'})
horizontalContainer = gui.Widget(width='100%', layout_orientation=gui.Widget.LAYOUT_HORIZONTAL, margin='0px', style={'display': 'block', 'overflow': 'auto'}) horizontalContainer = gui.Widget(width='100%', layout_orientation=gui.Widget.LAYOUT_HORIZONTAL,
margin='0px', style={'display': 'block', 'overflow': 'auto'})
subContainerLeft = gui.Widget(width=320, style={'display': 'block', 'overflow': 'auto', 'text-align': 'center'}) subContainerLeft = gui.Widget(width=320,
style={'display': 'block', 'overflow': 'auto', 'text-align': 'center'})
self.img = gui.Image('/res:logo.png', height=100, margin='10px') self.img = gui.Image('/res:logo.png', height=100, margin='10px')
self.img.onclick.connect(self.on_img_clicked) self.img.onclick.connect(self.on_img_clicked)
self.table = gui.Table.new_from_list([('ID', 'First Name', 'Last Name'), self.table = gui.Table.new_from_list([('ID', 'First Name', 'Last Name'),
('101', 'Danny', 'Young'), ('101', 'Danny', 'Young'),
('102', 'Christine', 'Holand'), ('102', 'Christine', 'Holand'),
('103', 'Lars', 'Gordon'), ('103', 'Lars', 'Gordon'),
('104', 'Roberto', 'Robitaille'), ('104', 'Roberto', 'Robitaille'),
('105', 'Maria', 'Papadopoulos')], width=300, height=200, margin='10px') ('105', 'Maria', 'Papadopoulos')],
width=300, height=200, margin='10px')
self.table.on_table_row_click.connect(self.on_table_row_click) self.table.on_table_row_click.connect(self.on_table_row_click)
# the arguments are width - height - layoutOrientationOrizontal # the arguments are width - height - layoutOrientationOrizontal
subContainerRight = gui.Widget(style={'width': '220px', 'display': 'block', 'overflow': 'auto', 'text-align': 'center'}) subContainerRight = gui.Widget(
style={'width': '220px', 'display': 'block',
'overflow': 'auto', 'text-align': 'center'})
self.count = 0 self.count = 0
self.counter = gui.Label('', width=200, height=30, margin='10px') self.counter = gui.Label('', width=200, height=30, margin='10px')
self.lbl = gui.Label('This is a LABEL!', width=200, height=30, margin='10px') self.lbl = gui.Label('This is a LABEL!', width=200,
height=30, margin='10px')
self.bt = gui.Button('Press me!', width=200, height=30, margin='10px') self.bt = gui.Button('Press me!', width=200, height=30, margin='10px')
# setting the listener for the onclick event of the button # setting the listener for the onclick event of the button
@ -63,40 +70,50 @@ class MyApp(App):
self.progress = gui.Progress(1, 100, width=200, height=5) self.progress = gui.Progress(1, 100, width=200, height=5)
self.check = gui.CheckBoxLabel('Label checkbox', True, width=200, height=30, margin='10px') self.check = gui.CheckBoxLabel(
'Label checkbox', True, width=200, height=30, margin='10px')
self.check.onchange.connect(self.on_check_change) self.check.onchange.connect(self.on_check_change)
self.btInputDiag = gui.Button('Open InputDialog', width=200, height=30, margin='10px') self.btInputDiag = gui.Button(
'Open InputDialog', width=200, height=30, margin='10px')
self.btInputDiag.onclick.connect(self.open_input_dialog) self.btInputDiag.onclick.connect(self.open_input_dialog)
self.btFileDiag = gui.Button('File Selection Dialog', width=200, height=30, margin='10px') self.btFileDiag = gui.Button(
'File Selection Dialog', width=200, height=30, margin='10px')
self.btFileDiag.onclick.connect(self.open_fileselection_dialog) self.btFileDiag.onclick.connect(self.open_fileselection_dialog)
self.btUploadFile = gui.FileUploader('./', width=200, height=30, margin='10px') self.btUploadFile = gui.FileUploader(
'./', width=200, height=30, margin='10px')
self.btUploadFile.onsuccess.connect(self.fileupload_on_success) self.btUploadFile.onsuccess.connect(self.fileupload_on_success)
self.btUploadFile.onfailed.connect(self.fileupload_on_failed) self.btUploadFile.onfailed.connect(self.fileupload_on_failed)
items = ('Danny Young','Christine Holand','Lars Gordon','Roberto Robitaille') items = ('Danny Young', 'Christine Holand',
self.listView = gui.ListView.new_from_list(items, width=300, height=120, margin='10px') 'Lars Gordon', 'Roberto Robitaille')
self.listView = gui.ListView.new_from_list(
items, width=300, height=120, margin='10px')
self.listView.onselection.connect(self.list_view_on_selected) self.listView.onselection.connect(self.list_view_on_selected)
self.link = gui.Link("http://localhost:8081", "A link to here", width=200, height=30, margin='10px') self.link = gui.Link("http://localhost:8081", "A link to here",
width=200, height=30, margin='10px')
self.dropDown = gui.DropDown.new_from_list(('DropDownItem 0', 'DropDownItem 1'), self.dropDown = gui.DropDown.new_from_list(
width=200, height=20, margin='10px') ('DropDownItem 0', 'DropDownItem 1'), width=200, height=20, margin='10px')
self.dropDown.onchange.connect(self.drop_down_changed) self.dropDown.onchange.connect(self.drop_down_changed)
self.dropDown.select_by_value('DropDownItem 0') self.dropDown.select_by_value('DropDownItem 0')
self.slider = gui.Slider(10, 0, 100, 5, width=200, height=20, margin='10px') self.slider = gui.Slider(
10, 0, 100, 5, width=200, height=20, margin='10px')
self.slider.onchange.connect(self.slider_changed) self.slider.onchange.connect(self.slider_changed)
self.colorPicker = gui.ColorPicker('#ffbb00', width=200, height=20, margin='10px') self.colorPicker = gui.ColorPicker(
'#ffbb00', width=200, height=20, margin='10px')
self.colorPicker.onchange.connect(self.color_picker_changed) self.colorPicker.onchange.connect(self.color_picker_changed)
self.date = gui.Date('2015-04-13', width=200, height=20, margin='10px') self.date = gui.Date('2015-04-13', width=200, height=20, margin='10px')
self.date.onchange.connect(self.date_changed) self.date.onchange.connect(self.date_changed)
self.video = gui.Widget( _type='iframe', width=290, height=200, margin='10px') self.video = gui.Widget(_type='iframe', width=290,
height=200, margin='10px')
self.video.attributes['src'] = "https://drive.google.com/file/d/0B0J9Lq_MRyn4UFRsblR3UTBZRHc/preview" self.video.attributes['src'] = "https://drive.google.com/file/d/0B0J9Lq_MRyn4UFRsblR3UTBZRHc/preview"
self.video.attributes['width'] = '100%' self.video.attributes['width'] = '100%'
self.video.attributes['height'] = '100%' self.video.attributes['height'] = '100%'
@ -119,14 +136,18 @@ class MyApp(App):
subti4.append([subsubti1, subsubti2, subsubti3]) subti4.append([subsubti1, subsubti2, subsubti3])
# appending a widget to another, the first argument is a string key # appending a widget to another, the first argument is a string key
subContainerRight.append([self.counter, self.lbl, self.bt, self.txt, self.spin, self.progress, self.check, self.btInputDiag, self.btFileDiag]) subContainerRight.append([self.counter, self.lbl, self.bt, self.txt,
self.spin, self.progress, self.check, self.btInputDiag, self.btFileDiag])
# use a defined key as we replace this widget later # use a defined key as we replace this widget later
fdownloader = gui.FileDownloader('download test', '../remi/res/logo.png', width=200, height=30, margin='10px') fdownloader = gui.FileDownloader(
'download test', '../remi/res/logo.png', width=200, height=30, margin='10px')
subContainerRight.append(fdownloader, key='file_downloader') subContainerRight.append(fdownloader, key='file_downloader')
subContainerRight.append([self.btUploadFile, self.dropDown, self.slider, self.colorPicker, self.date, self.tree]) subContainerRight.append(
[self.btUploadFile, self.dropDown, self.slider, self.colorPicker, self.date, self.tree])
self.subContainerRight = subContainerRight self.subContainerRight = subContainerRight
subContainerLeft.append([self.img, self.table, self.listView, self.link, self.video]) subContainerLeft.append(
[self.img, self.table, self.listView, self.link, self.video])
horizontalContainer.append([subContainerLeft, subContainerRight]) horizontalContainer.append([subContainerLeft, subContainerRight])
@ -153,7 +174,7 @@ class MyApp(App):
verticalContainer.append([menubar, horizontalContainer]) verticalContainer.append([menubar, horizontalContainer])
#this flag will be used to stop the display_counter Timer # this flag will be used to stop the display_counter Timer
self.stop_flag = False self.stop_flag = False
# kick of regular display of counter # kick of regular display of counter
@ -168,20 +189,28 @@ class MyApp(App):
Timer(1, self.display_counter).start() Timer(1, self.display_counter).start()
def menu_dialog_clicked(self, widget): def menu_dialog_clicked(self, widget):
self.dialog = gui.GenericDialog(title='Dialog Box', message='Click Ok to transfer content to main page', width='500px') self.dialog = gui.GenericDialog(
title='Dialog Box',
message='Click Ok to transfer content to main page', width='500px')
self.dtextinput = gui.TextInput(width=200, height=30) self.dtextinput = gui.TextInput(width=200, height=30)
self.dtextinput.set_value('Initial Text') self.dtextinput.set_value('Initial Text')
self.dialog.add_field_with_label('dtextinput', 'Text Input', self.dtextinput) self.dialog.add_field_with_label(
'dtextinput', 'Text Input', self.dtextinput)
self.dcheck = gui.CheckBox(False, width=200, height=30) self.dcheck = gui.CheckBox(False, width=200, height=30)
self.dialog.add_field_with_label('dcheck', 'Label Checkbox', self.dcheck) self.dialog.add_field_with_label(
values = ('Danny Young', 'Christine Holand', 'Lars Gordon', 'Roberto Robitaille') 'dcheck', 'Label Checkbox', self.dcheck)
self.dlistView = gui.ListView.new_from_list(values, width=200, height=120) values = ('Danny Young', 'Christine Holand',
self.dialog.add_field_with_label('dlistView', 'Listview', self.dlistView) 'Lars Gordon', 'Roberto Robitaille')
self.dlistView = gui.ListView.new_from_list(
values, width=200, height=120)
self.dialog.add_field_with_label(
'dlistView', 'Listview', self.dlistView)
self.ddropdown = gui.DropDown.new_from_list(('DropDownItem 0', 'DropDownItem 1'), self.ddropdown = gui.DropDown.new_from_list(('DropDownItem 0', 'DropDownItem 1'),
width=200, height=20) width=200, height=20)
self.dialog.add_field_with_label('ddropdown', 'Dropdown', self.ddropdown) self.dialog.add_field_with_label(
'ddropdown', 'Dropdown', self.ddropdown)
self.dspinbox = gui.SpinBox(min=0, max=5000, width=200, height=20) self.dspinbox = gui.SpinBox(min=0, max=5000, width=200, height=20)
self.dspinbox.set_value(50) self.dspinbox.set_value(50)
@ -193,7 +222,8 @@ class MyApp(App):
self.dcolor = gui.ColorPicker(width=200, height=20) self.dcolor = gui.ColorPicker(width=200, height=20)
self.dcolor.set_value('#ffff00') self.dcolor.set_value('#ffff00')
self.dialog.add_field_with_label('dcolor', 'Colour Picker', self.dcolor) self.dialog.add_field_with_label(
'dcolor', 'Colour Picker', self.dcolor)
self.ddate = gui.Date(width=200, height=20) self.ddate = gui.Date(width=200, height=20)
self.ddate.set_value('2000-01-01') self.ddate.set_value('2000-01-01')
@ -249,8 +279,7 @@ class MyApp(App):
def open_input_dialog(self, widget): def open_input_dialog(self, widget):
self.inputDialog = gui.InputDialog('Input Dialog', 'Your name?', self.inputDialog = gui.InputDialog('Input Dialog', 'Your name?',
initial_value='type here', initial_value='type here', width=500, height=160)
width=500, height=160)
self.inputDialog.confirm_value.connect( self.inputDialog.confirm_value.connect(
self.on_input_dialog_confirm) self.on_input_dialog_confirm)
@ -261,8 +290,8 @@ class MyApp(App):
self.lbl.set_text('Hello ' + value) self.lbl.set_text('Hello ' + value)
def open_fileselection_dialog(self, widget): def open_fileselection_dialog(self, widget):
self.fileselectionDialog = gui.FileSelectionDialog('File Selection Dialog', 'Select files and folders', False, self.fileselectionDialog = gui.FileSelectionDialog('File Selection Dialog',
'.') 'Select files and folders', False, '.')
self.fileselectionDialog.confirm_value.connect( self.fileselectionDialog.confirm_value.connect(
self.on_fileselection_dialog_confirm) self.on_fileselection_dialog_confirm)
@ -275,14 +304,16 @@ class MyApp(App):
if len(filelist): if len(filelist):
f = filelist[0] f = filelist[0]
# replace the last download link # replace the last download link
fdownloader = gui.FileDownloader("download selected", f, width=200, height=30) fdownloader = gui.FileDownloader(
"download selected", f, width=200, height=30)
self.subContainerRight.append(fdownloader, key='file_downloader') self.subContainerRight.append(fdownloader, key='file_downloader')
def list_view_on_selected(self, widget, selected_item_key): def list_view_on_selected(self, widget, selected_item_key):
""" The selection event of the listView, returns a key of the clicked event. """ The selection event of the listView, returns a key of the clicked event.
You can retrieve the item rapidly You can retrieve the item rapidly
""" """
self.lbl.set_text('List selection: ' + self.listView.children[selected_item_key].get_text()) self.lbl.set_text('List selection: ' +
self.listView.children[selected_item_key].get_text())
def drop_down_changed(self, widget, value): def drop_down_changed(self, widget, value):
self.lbl.set_text('New Combo value: ' + value) self.lbl.set_text('New Combo value: ' + value)
@ -326,4 +357,5 @@ if __name__ == "__main__":
# optional parameters # optional parameters
# start(MyApp,address='127.0.0.1', port=8081, multiple_instance=False,enable_file_cache=True, update_interval=0.1, start_browser=True) # start(MyApp,address='127.0.0.1', port=8081, multiple_instance=False,enable_file_cache=True, update_interval=0.1, start_browser=True)
import ssl import ssl
start(MyApp, debug=True, address='0.0.0.0', port=8081, start_browser=True, multiple_instance=True) start(MyApp, debug=True, address='0.0.0.0', port=8081,
start_browser=True, multiple_instance=True)

View File

@ -1474,6 +1474,8 @@ class Image(Element):
# def get_image_data(self, update_index): # def get_image_data(self, update_index):
# headers = {'Content-type': self.mimetype if self.mimetype else 'application/octet-stream'} # headers = {'Content-type': self.mimetype if self.mimetype else 'application/octet-stream'}
# return [self.imagedata, headers] # return [self.imagedata, headers]
class SuperImage(remi.gui.Image): class SuperImage(remi.gui.Image):
def __init__(self, file_path_name=None, **kwargs): def __init__(self, file_path_name=None, **kwargs):
""" """
@ -1493,6 +1495,68 @@ class SuperImage(remi.gui.Image):
if not image: return if not image: return
self.load(image) self.load(image)
def load(self, file_path_name):
if type(file_path_name) is bytes or len(file_path_name) > 200:
try:
#here a base64 image is received
self.imagedata = base64.b64decode(file_path_name, validate=True)
self.attributes['src'] = "/%s/get_image_data?update_index=%s" % (id(self), str(time.time()))
except binascii.Error:
#here an image data is received (opencv image)
self.imagedata = file_path_name
self.refresh()
self.refresh()
else:
#here a filename is received
self.attributes['src'] = remi.gui.load_resource(file_path_name)
"""print(f'***** Loading file = {file_path_name}')
self.mimetype, self.encoding = mimetypes.guess_type(file_path_name)
with open(file_path_name, 'rb') as f:
self.imagedata = f.read()"""
self.refresh()
def refresh(self):
i = int(time.time() * 1e6)
# self.app_instance.execute_javascript("""
if Window.App is not None:
Window.App.execute_javascript("""
var url = '/%(id)s/get_image_data?update_index=%(frame_index)s';
var xhr = new XMLHttpRequest();
xhr.open('GET', url, true);
xhr.responseType = 'blob'
xhr.onload = function(e){
var urlCreator = window.URL || window.webkitURL;
var imageUrl = urlCreator.createObjectURL(this.response);
document.getElementById('%(id)s').src = imageUrl;
}
xhr.send();
""" % {'id': id(self), 'frame_index':i})
def get_image_data(self, update_index):
headers = {'Content-type': self.mimetype if self.mimetype else 'application/octet-stream'}
return [self.imagedata, headers]
class SuperImage_OLD(remi.gui.Image):
def __init__(self, file_path_name=None, **kwargs):
"""
This new app_instance variable is causing lots of problems. I do not know the value of the App
when I create this image.
:param app_instance:
:param file_path_name:
:param kwargs:
"""
# self.app_instance = app_instance
image = file_path_name
super(SuperImage, self).__init__(image, **kwargs)
self.imagedata = None
self.mimetype = None
self.encoding = None
if not image: return
self.load(image)
def load(self, file_path_name): def load(self, file_path_name):
if type(file_path_name) is bytes or len(file_path_name) > 200: if type(file_path_name) is bytes or len(file_path_name) > 200:
try: try: