-1

I have trying to loop this but fail everytime. It´s the def create_widgets I try to loop. So I got a GUI that show a red button/box as soon something goes offline.

This is the code I tried to use.

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
    #Router
    self.button1 = Button(self)
    self.button1["text"] = "Router"
    self.button1["fg"] = "white"
    self.button1.grid(padx=0,pady=5)
    #Ping
    hostname = "10.18.18.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()
Bryan Oakley
  • 370,779
  • 53
  • 539
  • 685

1 Answers1

2

You can attach it onto Tk's event loop using Tk's after method.

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

Then, this line goes anywhere between app = Application(root) and root.mainloop():

root.after(0, app.if_offline)

after attaches a process onto the Tk event loop. The first argument is how often the process should be repeated in milliseconds, and the second is the function object to be executed. Since the time we have specified is 0, it will constantly check and constantly update the button's background color. If that churns your CPU, or you don't want to be pinging that much, you can change the repeat time to something larger.

The function object passed in should be just that: a function object. It has the same rules as the command argument in a Button constructor. If you need to pass in arguments to the function, use a lambda like so:

root.after(0, lambda: function(argument))

This works because the lambda function returns a function object, which when executed will run function(argument).

Source

Community
  • 1
  • 1
Ecko
  • 1,030
  • 9
  • 30
  • Hi I´m new to programing so I don´t really understand why I get error when I write this. NameError: name 'root' is not defined root.after(0, if_offline) root.mainloop() – user6335058 May 14 '16 at 20:29
  • Try adding one indent to everything within the class. – Ecko May 14 '16 at 20:44
  • My mistake. It needs to be `app.if_offline` not `if_offline`. I edited the answer to include that. – Ecko May 14 '16 at 20:46
  • I get no errors now, but it still doest loop. 'def if_offline(self):' import os #Router Ping hostname = "182.83.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.after(0,if_offline) root.mainloop() – user6335058 May 15 '16 at 15:50
  • @user6335058 I'm not sure about your specific example. There may be other problems with it unrelated to the looping, but those are yours to find. All I can tell you is that using `after` will attach a certain function to the `Tk` event loop and it will repeat over and over, depending on the first argument you give to `after`. – Ecko May 15 '16 at 17:04
  • @user6335058 In the meantime if my answer helped, please accept and upvote it :3 – Ecko May 16 '16 at 18:09