Merge pull request #2119 from PySimpleGUI/Dev-latest

Dev latest
This commit is contained in:
PySimpleGUI 2019-10-30 14:37:57 -04:00 committed by GitHub
commit 15950539ac
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 481 additions and 298 deletions

View File

@ -0,0 +1,68 @@
"""
Bare Bones Media Player Demo with Playlist. Adapeted from media player located at https://github.com/israel-dryer/Media-Player
Original Author : Israel Dryer
Modified to be a PySimpleGUI Demo Program
A very simple media player ready for you to customize. Uses the VLC player to playback local files and YouTube streams. You will need to install the Python bindings for VLC as well as the VLC player itself.
You will need to pip install:
pip install python-vlc
pip install youtube-dl
"""
import PySimpleGUI as sg
import vlc
#------- GUI definition & setup --------#
sg.change_look_and_feel('DarkBlue')
def btn(name): # a PySimpleGUI "User Defined Element" (see docs)
return sg. Button(name, size=(6, 1), pad=(1, 1))
layout = [[sg.Input(default_text='Video URL or Local Path:', size=(30, 1), key='-VIDEO_LOCATION-'), sg.Button('load')],
[sg.Image('', size=(300, 170), key='-VID_OUT-')],
[btn('previous'), btn('play'), btn('next'), btn('pause'), btn('stop')],
[sg.Text('Load media to start', key='-MESSAGE_AREA-')]]
window = sg.Window('Mini Player', layout, element_justification='center', finalize=True)
#------------ Media Player Setup ---------#
inst = vlc.Instance()
list_player = inst.media_list_player_new()
media_list = inst.media_list_new([])
list_player.set_media_list(media_list)
player = list_player.get_media_player()
player.set_hwnd(window['-VID_OUT-'].Widget.winfo_id())
#------------ The Event Loop ------------#
while True:
event, values = window.read(timeout=1000) # run with a timeout so that current location can be updated
if event is None:
break
if event == 'play':
list_player.play()
if event == 'pause':
list_player.pause()
if event == 'stop':
list_player.stop()
if event == 'next':
list_player.next()
list_player.play()
if event == 'previous':
list_player.previous() # first call causes current video to start over
list_player.previous() # second call moves back 1 video from current
list_player.play()
if event == 'load':
if not 'Video URL' in values['-VIDEO_LOCATION-']:
media_list.add_media(values['-VIDEO_LOCATION-'])
list_player.set_media_list(media_list)
window['-VIDEO_LOCATION-'].update('Video URL or Local Path:') # only add a legit submit
# update elapsed time if there is a video loaded and the player is playing
if player.is_playing():
window['-MESSAGE_AREA-'].update("{:02d}:{:02d} / {:02d}:{:02d}".format(*divmod(player.get_time()//1000, 60),
*divmod(player.get_length()//1000, 60)))
else:
window['-MESSAGE_AREA-'].update('Load media to start' if media_list.count() == 0 else 'Ready to play media' )
window.close()

View File

@ -1,5 +1,4 @@
# import PySimpleGUIWeb as sg
import PySimpleGUI as sg
import PySimpleGUIWeb as sg
import pymunk
import random
import socket
@ -10,17 +9,20 @@ import socket
Note this exact same demo runs with PySimpleGUIWeb by changing the import statement
"""
class Ball():
def __init__(self, x, y, r, *args, **kwargs):
mass = 10
self.body = pymunk.Body(mass,
pymunk.moment_for_circle(mass, 0, r, (0, 0))) # Create a Body with mass and moment
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.friction = 0.8
self.gui_circle_figure = None
class Playfield():
def __init__(self):
self.space = pymunk.Space()
@ -30,7 +32,7 @@ class Playfield():
self.add_wall(self.space, (600, 0), (600, 400)) # right side
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.friction = 0.8
ground_shape.elasticity = .99
@ -45,24 +47,25 @@ class Playfield():
ball = Ball(x, y, r)
self.arena_balls.append(ball)
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 -------------------
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],
[sg.B('Kick'), sg.Button('Exit')]]
window = sg.Window('Window Title', layout, ).Finalize()
[sg.Button('Kick'), sg.Button('Exit')]]
window = sg.Window('Window Title', layout, finalize=True)
area = Playfield()
area.add_balls()
# ------------------- GUI Event Loop -------------------
while True: # Event Loop
event, values = window.Read(timeout=0)
event, values = window.read(timeout=0)
# print(event, values)
if event in (None, 'Exit'):
break
@ -70,7 +73,9 @@ while True: # Event Loop
for ball in area.arena_balls:
if event == 'Kick':
ball.body.position = ball.body.position[0], ball.body.position[1]-random.randint(1,200)
graph_elem.RelocateFigure(ball.gui_circle_figure, ball.body.position[0], ball.body.position[1])
ball.body.position = ball.body.position[0], ball.body.position[1]-random.randint(
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
import PySimpleGUIWeb as sg
# import PySimpleGUI as sg
"""
@ -669,25 +667,26 @@ color_map = {
def detailed_view(window):
layout2 = [[sg.Button(event, button_color=('white', color_map[event]), key=event, tooltip=color_map[color]),
sg.Button(event, button_color=('black', color_map[event]), key=event+'1', tooltip=color_map[color])],
[sg.Txt('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()
layout2 = [[sg.Button(event, button_color=('white', color_map[event]),
key=event, tooltip=color_map[color]),
sg.Button(event, button_color=('black', color_map[event]),
key=event+'1', tooltip=color_map[color])],
[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
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.',
text_color='blue',
font=('Hevletica', 20),
relief=sg.RELIEF_SUNKEN,
justification='center',
size=(90,2),
background_color='#90EE90',
pad=(0,0)),]]
text_color='blue', background_color='#90EE90',
font=('Hevletica', 20),
relief=sg.RELIEF_SUNKEN, justification='center',
size=(90, 2), pad=(0, 0))]]
# -- Create primary color viewer window by building rows and appending to layout --
color_list = [key for key in color_map]
@ -696,14 +695,16 @@ for rows in range(40):
for i in range(12):
try:
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:
pass
layout.append(row)
while True:
window = sg.Window('Color Viewer', layout, font=('any 12'), default_button_element_size=(12,1), element_padding=(0,0))
event, values = window.Read()
window = sg.Window('Color Viewer', layout, font=('any 12'),
default_button_element_size=(12, 1), element_padding=(0, 0))
event, values = window.read()
if event is None:
break
detailed_view(window)

View File

@ -1,5 +1,4 @@
#!/usr/bin/env python
import sys
import PySimpleGUIWeb as sg
"""
@ -12,7 +11,6 @@ import PySimpleGUIWeb as sg
"""
COLORS = ['snow', 'ghost white', 'white smoke', 'gainsboro', 'floral white', 'old lace',
'linen', 'antique white', 'papaya whip', 'blanched almond', 'bisque', 'peach puff',
'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']
sg.set_options(button_element_size=(12, 1),
element_padding=(0, 0), auto_size_buttons=False, border_width=0)
sg.SetOptions(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', 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 = []
layout = []
# -- Create primary color viewer window --
@ -117,13 +115,16 @@ for rows in range(40):
# layout.append(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 --
while True:
event, values = window.Read()
event, values = window.read()
if event is None:
break
# -- 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))]]
sg.Window('Buttons with white and black text', keep_on_top=True).Layout(layout2).Read(timeout=0)
layout2 = [[sg.DummyButton(event, button_color=('white', event)),
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
layout = [[sg.Spin([sz for sz in range(6, 172)], size=(6,1), 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')],]
layout = [
[sg.Spin([sz for sz in range(6, 172)], size=(6, 1),
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
event, values= window.Read()
event, values = window.read()
if event is None or event == 'Quit':
break
fontsize = int(values['spin']) if int(values['spin']) != fontsize else int(values['slider'])
font = "Helvetica " + str(fontsize)
window.FindElement('text').Update(font=font)
window.FindElement('slider').Update(fontsize, range=(10,20))
window.FindElement('spin').Update(fontsize)
window.Close()
if int(values['spin']) != fontsize:
fontsize = int(values['spin'])
else:
fontsize = int(values['slider'])
window['text'].update(font="Helvetica " + str(fontsize))
window['slider'].update(fontsize, range=(10, 20))
window['spin'].update(fontsize)
window.close()
print("Done.")

View File

@ -1,16 +1,11 @@
#!/usr/bin/env python
import sys
import PySimpleGUIWeb as sg
import subprocess
import howdoi
# Test this command in a dos window if you are having trouble.
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():
'''
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
'''
# ------- 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 = [
[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.Checkbox('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.Multiline(size=(85, 5), enter_submits=True, key='query', do_not_clear=False),
[ sg.CBox('Display Full Text', key='full text', font='Helvetica 15'),
sg.Text('Command History', font='Helvetica 15'), sg.Text('', size=(40,3), text_color=sg.BLUES[0], key='history')],
[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.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.Layout(layout)
window = sg.Window('How Do I?', layout, default_element_size=(30,1),
font=('Helvetica',' 17'), default_button_element_size=(8,2),
return_keyboard_events=False)
# ---===--- Loop taking in user input and using it to query HowDoI --- #
command_history = []
history_offset = 0
while True:
event, values = window.Read()
# print(event, values)
if type(event) is int:
event = str(event)
if event == 'SEND':
query = values['query'].rstrip()
window.Element('_OUTPUT_').Update(query, append=True)
window['_OUTPUT_'].update(query, append=True)
print(query)
QueryHowDoI(query, 1, values['full text'], window) # send the string to HowDoI
command_history.append(query)
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):
'''
@ -78,9 +90,9 @@ def QueryHowDoI(Query, num_answers, full_text, window:sg.Window):
full_text_option = ' -a' if full_text else ''
t = subprocess.Popen(howdoi_command + ' \"'+ Query + '\" -n ' + str(num_answers)+full_text_option, stdout=subprocess.PIPE)
(output, err) = t.communicate()
window.Element('_OUTPUT_').Update('{:^88}'.format(Query.rstrip()), append=True)
window.Element('_OUTPUT_').Update('_'*60, append=True)
window.Element('_OUTPUT_').Update(output.decode("utf-8"), append=True)
window['_OUTPUT_'].update('{:^88}'.format(Query.rstrip()), append=True)
window['_OUTPUT_'].update('_'*60, append=True)
window['_OUTPUT_'].update(output.decode("utf-8"), append=True)
exit_code = t.wait()
if __name__ == '__main__':

View File

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

View File

@ -16,19 +16,20 @@ print('Starting up...')
layout = [
[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')]
]
window = sg.Window('Window Title').Layout(layout)
window = sg.Window('Window Title', layout)
while True: # Event Loop
print('in event loop')
event, values = window.Read()
event, values = window.read()
print(event, values)
if event is None or event == 'Exit':
if event in (None, 'Exit'):
break
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
# Basic example of PSGWeb
def main():
layout = [
[sg.Text('This is a text element')],
[sg.Input()],
[sg.Combo(['Combo 1'])],
[sg.Text('If you close the browser tab, the app will exit gracefully')],
[sg.InputText('Source', do_not_clear=True)],
[sg.InputText('Dest', do_not_clear=True)],
[sg.Ok(), sg.Cancel()]
]
[sg.Text('This is a text element')],
[sg.Input()],
[sg.Combo(['Combo 1'])],
[sg.Text('If you close the browser tab, the app will exit gracefully')],
[sg.InputText('Source')],
[sg.InputText('Dest')],
[sg.Ok(), sg.Cancel()]
]
window = sg.Window('Demo window..').Layout(layout)
window = sg.Window('Demo window..', layout)
i = 0
while True:
event, values = window.Read(timeout=1)
event, values = window.read(timeout=1)
if event != sg.TIMEOUT_KEY:
print(event, values)
if event is None:
break
i += 1
window.Close()
window.close()
main()
print('Program terminating normally')
print('Program terminating normally')

View File

@ -2,69 +2,42 @@ import PySimpleGUIWeb as sg
import random
import string
"""
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'
oooooooooooo oooo .
`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"
"""
# Example with Table element
def word():
return ''.join(random.choice(string.ascii_lowercase) for i in range(10))
# ------------------ 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 number(max_val=1000):
return random.randint(0,max_val)
def make_table(num_rows, num_cols):
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):
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
table_data = make_table(num_rows=15, num_cols=6)
# ------------------ Create a window layout ------------------
layout = [[sg.Table(values=table_data,
enable_events=True,
display_row_numbers=True,
font='Courier 14',
row_header_text='Row #',
key='_table_',
text_color='red')],
layout = [[sg.Table(values=table_data, enable_events=True,
display_row_numbers=True, font='Courier 14',
row_header_text='Row #', key='_table_', text_color='red')],
[sg.Button('Exit')],
[sg.T('Selected rows = '), sg.T('', size=(30,1), key='_selected_rows_')],
[sg.T('Selected value = '), sg.T('', size=(30,1), key='_selected_value_')]]
[sg.Text('Selected rows = '), sg.Text('', size=(30,1), key='_selected_rows_')],
[sg.Text('Selected value = '), sg.Text('', size=(30,1), key='_selected_value_')]]
# ------------------ Create the window ------------------
window = sg.Window('Table Element Example').Layout(layout)
window = sg.Window('Table Element Example', layout)
# ------------------ The Event Loop ------------------
while True:
event, values = window.Read()
event, values = window.read()
print(event, values)
if event in (None, 'Exit'):
break
window.Element('_selected_rows_').Update(values['_table_'])
window.Element('_selected_value_').Update(window.Element('_table_').SelectedItem)
window['_selected_rows_'].update(values['_table_'])
window['_selected_value_'].update(window['_table_'].SelectedItem)
# ------------------ User closed window so exit ------------------
window.Close()
window.close()

View File

@ -1,57 +1,62 @@
#!/usr/bin/env python
import PySimpleGUIWeb as sg
import time
import sys
# ---------------- Create Form ----------------
layout = [
[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.Button('Pause', key='button', button_color=('white', '#001480')),
sg.Button('Reset', button_color=('white', '#007339'), key='Reset'),
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 ----------------
current_time = 0
paused = False
start_time = int(round(time.time() * 100))
while (True):
# --------- Read and update window --------
while True:
# --------- read and update window --------
if not paused:
event, values = window.Read(timeout=0)
event, values = window.read(timeout=0)
current_time = int(round(time.time() * 100)) - start_time
else:
event, values = window.Read()
event, values = window.read()
print(event, values) if event != sg.TIMEOUT_KEY else None
if event == 'button':
event = window.FindElement(event).GetText()
event = window[event].GetText()
# --------- Do Button Operations --------
if event in (None, 'Exit'): # ALWAYS give a way out of program
break
if event == 'Reset':
start_time = int(round(time.time() * 100))
current_time = 0
paused_time = start_time
elif event == 'Pause':
paused = True
paused_time = int(round(time.time() * 100))
element = window.FindElement('button')
element.Update(text='Run')
element = window['button']
element.update(text='Run')
elif event == 'Run':
paused = False
start_time = start_time + int(round(time.time() * 100)) - paused_time
element = window.FindElement('button')
element.Update(text='Pause')
element = window['button']
element.update(text='Pause')
# --------- Display timer in window --------
window.FindElement('text').Update('{:02d}:{:02d}.{:02d}'.format((current_time // 100) // 60,
(current_time // 100) % 60,
current_time % 100))
window['text'].update('{:02d}:{:02d}.{:02d}'.format((current_time // 100) // 60,
(current_time //
100) % 60,
current_time % 100))
# --------- After loop --------
window.Close()
print('after loop')
sys.exit()
window.close()

View File

@ -3,43 +3,48 @@ import datetime
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.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.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'))]
]
[sg.CBox('Checkbox 1', enable_events=True, key='_CB1_'),
sg.CBox('Checkbox 2', default=True,
enable_events=True, key='_CB2_')],
window = sg.Window('My PySimpleGUIWeb Window',
default_element_size=(30,1),
font='Helvetica 18',
background_image=r'dot:logo.jpg'
).Layout(layout)
[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', layout,
default_element_size=(30, 1), font='Helvetica 18')
start_time = datetime.datetime.now()
while True:
event, values = window.Read(timeout=10)
event, values = window.read(timeout=10)
if event != sg.TIMEOUT_KEY:
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'):
break
window.Element('_DATE_').Update(str(datetime.datetime.now()-start_time))
window.Close()
window['_DATE_'].update(str(datetime.datetime.now()-start_time))
window.close()

View File

@ -1,6 +1,4 @@
#!/usr/bin/env python
import sys
import sys
import PySimpleGUIWeb as sg
import os
import signal
@ -13,6 +11,7 @@ import operator
Based on psutil package that is easily installed using pip
"""
def kill_proc_tree(pid, sig=signal.SIGTERM, include_parent=True,
timeout=None, on_terminate=None):
"""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():
# ---------------- Create Form ----------------
# sg.ChangeLookAndFeel('Topanga')
layout = [[sg.Text('Process Killer - Choose one or more processes',
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_')],
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.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 % 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'))]]
window = sg.Window('Process Killer',
keep_on_top=True,
auto_size_buttons=False,
default_button_element_size=(12,1),
return_keyboard_events=True,
).Layout(layout)
window = sg.Window('Process Killer', layout,
keep_on_top=True, auto_size_buttons=False,
default_button_element_size=(12, 1), return_keyboard_events=True)
display_list = None
# ---------------- main loop ----------------
while (True):
while True:
# --------- Read and update window --------
event, values = window.Read()
if event is None or event == 'Exit':
if event in (None, 'Exit'):
break
# skip mouse, control key and shift key events entirely
@ -71,40 +69,46 @@ def main():
if event == 'Sort by Name':
psutil.cpu_percent(interval=.1)
procs = psutil.process_iter()
all_procs = [[proc.cpu_percent(), proc.name(), proc.pid] for proc in procs]
sorted_by_cpu_procs = sorted(all_procs, key=operator.itemgetter(1), reverse=False)
all_procs = [[proc.cpu_percent(), proc.name(), proc.pid]
for proc in procs]
sorted_by_cpu_procs = sorted(
all_procs, key=operator.itemgetter(1), reverse=False)
display_list = []
for process in sorted_by_cpu_procs:
display_list.append('{:5d} {:5.2f} {}\n'.format(process[2], process[0]/10, process[1]))
window.FindElement('_processes_').Update(display_list)
display_list.append('{:5d} {:5.2f} {}\n'.format(
process[2], process[0]/10, process[1]))
window['_processes_'].update(display_list)
print(display_list)
elif event == 'Kill':
processes_to_kill = values['_processes_']
for proc in processes_to_kill:
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:
kill_proc_tree(pid=pid)
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':
psutil.cpu_percent(interval=.1)
procs = psutil.process_iter()
all_procs = [[proc.cpu_percent(), proc.name(), proc.pid] for proc in procs]
sorted_by_cpu_procs = sorted(all_procs, key=operator.itemgetter(0), reverse=True)
all_procs = [[proc.cpu_percent(), proc.name(), proc.pid]
for proc in procs]
sorted_by_cpu_procs = sorted(
all_procs, key=operator.itemgetter(0), reverse=True)
display_list = []
for process in sorted_by_cpu_procs:
display_list.append('{:5d} {:5.2f} {}\n'.format(process[2], process[0]/10, process[1]))
window.FindElement('_processes_').Update(display_list)
display_list.append('{:5d} {:5.2f} {}\n'.format(
process[2], process[0]/10, process[1]))
window['_processes_'].update(display_list)
else: # was a typed character
if display_list is not None:
new_output = []
for line in display_list:
if values['_filter_'] in line.lower():
new_output.append(line)
window.FindElement('_processes_').Update(new_output)
window['_processes_'].update(new_output)
window.close()
if __name__ == "__main__":
main()
sys.exit(0)

View File

@ -23,32 +23,39 @@ class MyApp(App):
def idle(self):
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):
# 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'})
subContainerLeft = gui.Widget(width=320, style={'display': 'block', 'overflow': 'auto', 'text-align': 'center'})
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'})
self.img = gui.Image('/res:logo.png', height=100, margin='10px')
self.img.onclick.connect(self.on_img_clicked)
self.table = gui.Table.new_from_list([('ID', 'First Name', 'Last Name'),
('101', 'Danny', 'Young'),
('102', 'Christine', 'Holand'),
('103', 'Lars', 'Gordon'),
('104', 'Roberto', 'Robitaille'),
('105', 'Maria', 'Papadopoulos')], width=300, height=200, margin='10px')
('101', 'Danny', 'Young'),
('102', 'Christine', 'Holand'),
('103', 'Lars', 'Gordon'),
('104', 'Roberto', 'Robitaille'),
('105', 'Maria', 'Papadopoulos')],
width=300, height=200, margin='10px')
self.table.on_table_row_click.connect(self.on_table_row_click)
# the arguments are width - height - layoutOrientationOrizontal
subContainerRight = gui.Widget(style={'width': '220px', 'display': 'block', 'overflow': 'auto', 'text-align': 'center'})
# the arguments are width - height - layoutOrientationOrizontal
subContainerRight = gui.Widget(
style={'width': '220px', 'display': 'block',
'overflow': 'auto', 'text-align': 'center'})
self.count = 0
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')
# setting the listener for the onclick event of the button
@ -63,46 +70,56 @@ class MyApp(App):
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.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.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.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.onfailed.connect(self.fileupload_on_failed)
items = ('Danny Young','Christine Holand','Lars Gordon','Roberto Robitaille')
self.listView = gui.ListView.new_from_list(items, width=300, height=120, margin='10px')
items = ('Danny Young', 'Christine Holand',
'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.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'),
width=200, height=20, margin='10px')
self.dropDown = gui.DropDown.new_from_list(
('DropDownItem 0', 'DropDownItem 1'), width=200, height=20, margin='10px')
self.dropDown.onchange.connect(self.drop_down_changed)
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.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.date = gui.Date('2015-04-13', width=200, height=20, margin='10px')
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['width'] = '100%'
self.video.attributes['height'] = '100%'
self.video.attributes['controls'] = 'true'
self.video.style['border'] = 'none'
self.tree = gui.TreeView(width='100%', height=300)
ti1 = gui.TreeItem("Item1")
ti2 = gui.TreeItem("Item2")
@ -117,16 +134,20 @@ class MyApp(App):
self.tree.append([ti1, ti2, ti3])
ti2.append([subti1, subti2, subti3, subti4])
subti4.append([subsubti1, subsubti2, subsubti3])
# 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
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([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
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])
@ -153,8 +174,8 @@ class MyApp(App):
verticalContainer.append([menubar, horizontalContainer])
#this flag will be used to stop the display_counter Timer
self.stop_flag = False
# this flag will be used to stop the display_counter Timer
self.stop_flag = False
# kick of regular display of counter
self.display_counter()
@ -168,20 +189,28 @@ class MyApp(App):
Timer(1, self.display_counter).start()
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.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.dialog.add_field_with_label('dcheck', 'Label Checkbox', self.dcheck)
values = ('Danny Young', 'Christine Holand', '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.dialog.add_field_with_label(
'dcheck', 'Label Checkbox', self.dcheck)
values = ('Danny Young', 'Christine Holand',
'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'),
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.set_value(50)
@ -193,7 +222,8 @@ class MyApp(App):
self.dcolor = gui.ColorPicker(width=200, height=20)
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.set_value('2000-01-01')
@ -249,8 +279,7 @@ class MyApp(App):
def open_input_dialog(self, widget):
self.inputDialog = gui.InputDialog('Input Dialog', 'Your name?',
initial_value='type here',
width=500, height=160)
initial_value='type here', width=500, height=160)
self.inputDialog.confirm_value.connect(
self.on_input_dialog_confirm)
@ -261,8 +290,8 @@ class MyApp(App):
self.lbl.set_text('Hello ' + value)
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.on_fileselection_dialog_confirm)
@ -275,14 +304,16 @@ class MyApp(App):
if len(filelist):
f = filelist[0]
# 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')
def list_view_on_selected(self, widget, selected_item_key):
""" The selection event of the listView, returns a key of the clicked event.
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):
self.lbl.set_text('New Combo value: ' + value)
@ -326,4 +357,5 @@ if __name__ == "__main__":
# 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)
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):
# headers = {'Content-type': self.mimetype if self.mimetype else 'application/octet-stream'}
# return [self.imagedata, headers]
class SuperImage(remi.gui.Image):
def __init__(self, file_path_name=None, **kwargs):
"""
@ -1493,6 +1495,68 @@ class SuperImage(remi.gui.Image):
if not image: return
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):
if type(file_path_name) is bytes or len(file_path_name) > 200:
try: