Python Forum

Full Version: How to update the gui in a loop without blocking the gui mainloop
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
Hi
I´m trying to make a monitor that show when a host in my network goes offline, but I cant get it to loop the code and update the buttons in silence.
Now I has to exit and runt the script every time I want a update.
I want to put this up on a monitor that show it in real time, and maybe later I want some other information shown to.

#GUI
from tkinter import *


class Application(Frame):
    """ GUI """

    def __init__(self, master):
        """ Initialize the Frame"""
        Frame.__init__(self,master)
        self.grid()
        self.create_widgets()
        

    def create_widgets(self):
        """Create button. """
        import os
        import subprocess
        

        
        #Router
        self.button1 = Button(self)
        self.button1["text"] = "Router"
        self.button1["fg"] = "white"
        self.button1.grid(row=0,column=5,rowspan=1,columnspan=2)
        #Ping
        hostname = "192.168.0.1"
        response = os.system("ping -n 1 " + hostname)
        #response
        if response == 0:
            self.button1["bg"] = "green"
        else:
            self.button1["bg"] = "red"
root = Tk()
root.title("monitor")
root.geometry("500x500")

app = Application(root)

root.mainloop()
The code is only update when creating widgets is called.
Move the updating into its own method.
Use after to call the update method every n ms

# from tkinter import * # don't use star imports they flood the namespace
import os
import tkinter

UPDATE_RATE = 1000

class Application(tkinter.Frame):
    """ GUI """

    def __init__(self, master):
        """ Initialize the Frame"""
        tkinter.Frame.__init__(self, master)
        self.grid()
        self.create_widgets()
        self.updater()

    def create_widgets(self):
        """Create button. """
#         import os # import at top
#         import subprocess # doing nothing
        # Router
        self.button1 = tkinter.Button(self)
        self.button1["text"] = "Router"
        self.button1["fg"] = "white"
        self.button1.grid(row=0, column=5, rowspan=1, columnspan=2)

    def update_button1(self):
        # Ping
        hostname = "192.168.0.1"
        response = os.system("ping -n 1 " + hostname)
        # response
        if response == 0:
            self.button1["bg"] = "green"
        else:
            self.button1["bg"] = "red"

    def updater(self):
        self.update_button1()
        self.after(UPDATE_RATE, self.updater)

root = tkinter.Tk()
root.title("monitor")
root.geometry("500x500")
app = Application(root)
root.mainloop()
Note: if an update takes a long time the code will have to be organised in a way that does not block the mainloop by keeping the blocking part in a separate thread from the actual call to the gui methods.
This got the loop going, I tried to get the cmd in silcens so I don´t see the window. But don´t seems to find the right code.
Tested with a subprocess, but then the loop died.