From 4ad786c27cbc1619059d017eb46bac55506378da Mon Sep 17 00:00:00 2001 From: MikeTheWatchGuy Date: Sun, 16 Sep 2018 17:08:26 -0400 Subject: [PATCH] New Graph Element ! Graph on a canvas using your own coordinate system. Demo program for Graph Element, Exception handling for CPU widget. Sometimes as getting error from psutil --- Demo_Desktop_Widget_CPU_Utilization.py | 12 ++++-- Demo_Graph__Element.py | 57 ++++++++++++++++++++++++++ PySimpleGUI.py | 57 +++++++++++++++++++++++--- 3 files changed, 117 insertions(+), 9 deletions(-) create mode 100644 Demo_Graph__Element.py diff --git a/Demo_Desktop_Widget_CPU_Utilization.py b/Demo_Desktop_Widget_CPU_Utilization.py index cdf6b850..69178101 100644 --- a/Demo_Desktop_Widget_CPU_Utilization.py +++ b/Demo_Desktop_Widget_CPU_Utilization.py @@ -27,8 +27,11 @@ def CPU_thread(args): global g_interval, g_cpu_percent, g_procs, g_exit while not g_exit: - g_cpu_percent = psutil.cpu_percent(interval=g_interval) - g_procs = psutil.process_iter() + try: + g_cpu_percent = psutil.cpu_percent(interval=g_interval) + g_procs = psutil.process_iter() + except: + pass def main(): @@ -67,7 +70,10 @@ def main(): display_string = '' if g_procs: # --------- Create list of top % CPU porocesses -------- - top = {proc.name() : proc.cpu_percent() for proc in g_procs} + try: + top = {proc.name() : proc.cpu_percent() for proc in g_procs} + except: pass + top_sorted = sorted(top.items(), key=operator.itemgetter(1), reverse=True) if top_sorted: diff --git a/Demo_Graph__Element.py b/Demo_Graph__Element.py new file mode 100644 index 00000000..21f85b9e --- /dev/null +++ b/Demo_Graph__Element.py @@ -0,0 +1,57 @@ +import ping +from threading import Thread +import time +import PySimpleGUI as sg + +# globale used to communicate with thread.. yea yea... it's working fine +g_exit = False +g_response_time = None +def ping_thread(args): + global g_exit, g_response_time + while not g_exit: + g_response_time = ping.quiet_ping('google.com', timeout=1000) + +def main(): + global g_exit, g_response_time + # start ping measurement thread + thread = Thread(target=ping_thread, args=(None,)) + thread.start() + + layout = [ [sg.T('Ping times to Google.com', font='Any 18')], + [sg.Graph((300,300), (0,0), (100,500),background_color='white', key='graph')], + [sg.Quit()]] + + form = sg.FlexForm('Canvas test', grab_anywhere=True) + form.Layout(layout) + + prev_response_time = None + i=0 + prev_x, prev_y = 0, 0 + while True: + time.sleep(.2) + + button, values = form.ReadNonBlocking() + if button == 'Quit' or values is None: + break + + if g_response_time is None or prev_response_time == g_response_time: + continue + new_x, new_y = i, g_response_time[0] + prev_response_time = g_response_time + form.FindElement('graph').DrawLine((prev_x, prev_y), (new_x, new_y), color='red') + # form.FindElement('graph').DrawPoint((new_x, new_y), color='red') + prev_x, prev_y = new_x, new_y + if i >= 100: + i = 0 + prev_x = prev_y = last_x = last_y = 0 + form.FindElement('graph').Erase() + else: i += 4 + + # tell thread we're done. wait for thread to exit + g_exit = True + thread.join() + + +if __name__ == '__main__': + main() + exit(69) \ No newline at end of file diff --git a/PySimpleGUI.py b/PySimpleGUI.py index 4223d6db..e06fe163 100644 --- a/PySimpleGUI.py +++ b/PySimpleGUI.py @@ -1106,11 +1106,55 @@ class Image(Element): class Canvas(Element): def __init__(self, canvas=None, background_color=None, scale=(None, None), size=(None, None), pad=None, key=None): self.BackgroundColor = background_color if background_color is not None else DEFAULT_BACKGROUND_COLOR - self.TKCanvas = canvas + self._TKCanvas = canvas super().__init__(ELEM_TYPE_CANVAS, background_color=background_color, scale=scale, size=size, pad=pad, key=key) return + @property + def TKCanvas(self): + return self._TKCanvas + + + def __del__(self): + super().__del__() + + + + +# ---------------------------------------------------------------------- # +# Graph # +# ---------------------------------------------------------------------- # +class Graph(Canvas): + def __init__(self, canvas_size, graph_bottom_left, graph_top_right, background_color=None, scale=(None, None), size=(None, None), pad=None, key=None): + + self.CanvasSize = canvas_size + self.BottomLeft = graph_bottom_left + self.TopRight = graph_top_right + + super().__init__(background_color=background_color, scale=scale, size=canvas_size, pad=pad, key=key) + return + + def _convert_xy_to_canvas_xy(self, x_in, y_in): + scale_x = (self.CanvasSize[0] - 0) / (self.TopRight[0] - self.BottomLeft[0]) + scale_y = (0 - self.CanvasSize[1]) / (self.TopRight[1] - self.BottomLeft[1]) + new_x = 0 + scale_x * (x_in - self.BottomLeft[0]) + new_y = self.CanvasSize[1] + scale_y * (y_in - self.BottomLeft[1]) + return new_x, new_y + + def DrawLine(self, point_from, point_to, color='black', width=1): + converted_point_from = self._convert_xy_to_canvas_xy(*point_from) + converted_point_to = self._convert_xy_to_canvas_xy(*point_to) + self.TKCanvas.create_line(converted_point_from, converted_point_to, width=width, fill=color) + + def DrawPoint(self, point, size=2, color='black'): + converted_point = self._convert_xy_to_canvas_xy(*point) + self.TKCanvas.create_oval(converted_point[0]-size, converted_point[1]-size, converted_point[0]+size, converted_point[1]+size, fill=color, outline=color ) + + def Erase(self): + self.TKCanvas.delete('all') + + def __del__(self): super().__del__() @@ -2611,13 +2655,13 @@ def PackFormIntoFrame(form, containing_frame, toplevel_form): # ------------------------- Canvas element ------------------------- # elif element_type == ELEM_TYPE_CANVAS: width, height = element_size - if element.TKCanvas is None: - element.TKCanvas = tk.Canvas(tk_row_frame, width=width, height=height, bd=border_depth) + if element._TKCanvas is None: + element._TKCanvas = tk.Canvas(tk_row_frame, width=width, height=height, bd=border_depth) else: - element.TKCanvas.master = tk_row_frame + element._TKCanvas.master = tk_row_frame if element.BackgroundColor is not None and element.BackgroundColor != COLOR_SYSTEM_DEFAULT: - element.TKCanvas.configure(background=element.BackgroundColor) - element.TKCanvas.pack(side=tk.LEFT, padx=element.Pad[0], pady=element.Pad[1]) + element._TKCanvas.configure(background=element.BackgroundColor) + element._TKCanvas.pack(side=tk.LEFT, padx=element.Pad[0], pady=element.Pad[1]) # ------------------------- MENUBAR element ------------------------- # elif element_type == ELEM_TYPE_MENUBAR: menu_def = (('File', ('Open', 'Save')), @@ -3078,6 +3122,7 @@ def EasyProgressMeter(title, current_value, max_value, *args, orientation=None, EasyProgressMeter.Data = getattr(EasyProgressMeter, 'Data', EasyProgressMeterDataClass()) # if no meter currently running if EasyProgressMeter.Data.MeterID is None: # Starting a new meter + print("Please change your call of EasyProgressMeter to use OneLineProgressMeter. EasyProgressMeter will be removed soon") if int(current_value) >= int(max_value): return False del(EasyProgressMeter.Data)