0

I have just started learning Python and I couldn't figure this one out, Basically I want to monitor my network traffic, and running this code below will only show the results which were captured at the moment but it doesn't update

from tkinter import*
import psutil,os
from psutil._common import bytes2human
from threading import Timer
import time

netmon = Tk()
netmon.title("NetMonitor")
netmon.geometry("200x80")

def getresults():
    total_before = psutil.net_io_counters()
    time.sleep(1)
    total_after = psutil.net_io_counters()
    download_rate = "Download : " + bytes2human(total_after.bytes_recv - total_before.bytes_recv) + " KB/S"
    upload_rate = "Upload : " + bytes2human(total_after.bytes_sent - total_before.bytes_sent) + " KB/S"
    text = Label(netmon, text = "\n" + download_rate + "\n\n" + upload_rate, anchor = NW)
    text.pack()
    #Timer(5, getresults).start

getresults()

netmon.mainloop()

I have tried with while loop :

.
.
.
while True:
   getresults()

netmon.mainloop()

and I have tried the Timer from Threading but in both cases the "program" wont even launch till I revert to the first code I mentioned above, can anyone tell me how to make it update every second for example?

Yusef Maali
  • 2,201
  • 2
  • 23
  • 29
J.Dao
  • 13
  • 3
  • add this `netmon.after(ms, getresults)` at the end of the function. Where Ms is time to wait in Milliseconds – Isaac Frank Jun 19 '20 at 17:22
  • Almost there, by doing this it adds new lines instead of updating the already shown ones with updated results, till I stop the program, basically each time it repeats it makes a new label now – J.Dao Jun 19 '20 at 17:30
  • Does this answer your question? [tkinter: how to use after method](https://stackoverflow.com/a/25753719/7414759) and [making-python-tkinter-label-widget-update](https://stackoverflow.com/questions/1918005) – stovfl Jun 19 '20 at 17:32
  • Thanks, that definitely gave me more knowledge ! – J.Dao Jun 19 '20 at 17:41

2 Answers2

1

A simpler method would be to implement a solution via the APScheduler's BackgroundScheduler:

from apscheduler.schedulers.background import BackgroundScheduler
backgroundScheduler = BackgroundScheduler(daemon=True)

backgroundScheduler.add_job(lambda : backgroundScheduler.print_jobs(),'interval',seconds=4)
backgroundScheduler.start()

... and then when complete

backgroundScheduler.shutdown()
FisheyJay
  • 442
  • 4
  • 10
0

You're on the right track that you need to use a while loop. I put it into its own thread (and passed the text as a constructor argument to the thread class).

from tkinter import*
import psutil,os
from psutil._common import bytes2human
from threading import Timer
import time
import threading

netmon = Tk()
netmon.title("NetMonitor")
netmon.geometry("200x80")

text = Label(netmon, text = "\n" + 'Download : TBD' + "\n\n" + 'Upload : TBD', anchor = NW)
text.pack()

class GetUpdates(threading.Thread):
    def __init__(self, text):
        threading.Thread.__init__(self)
        self._stop_event = threading.Event()
        self._text = text

    def stop(self):
        self._stop_event.set()

    def run(self):
        while not self._stop_event.is_set():
            total_before = psutil.net_io_counters()
            time.sleep(1)
            total_after = psutil.net_io_counters()
            download_rate = "Download : " + bytes2human(total_after.bytes_recv - total_before.bytes_recv) + " KB/S"
            upload_rate = "Upload : " + bytes2human(total_after.bytes_sent - total_before.bytes_sent) + " KB/S"
            self._text['text'] = "\n" + download_rate + "\n\n" + upload_rate


getupdates = GetUpdates(text)
getupdates.start()


netmon.mainloop()
Rusty Widebottom
  • 985
  • 2
  • 5
  • 14