0

I wrote a little script to track the battery capacity of my device. Mostly for learning Python.

I decided to use a loop to recognize low capacity. So far it is okay, but when I use a tkinter messagebox, the window does not disappear after I confirm the warning.

import os
from time import sleep
import tkinter as tk 
from tkinter import *
from tkinter import messagebox

stat = "/sys_vars/status"
plugged = "PLUGGED"
unplugged = "UNPLUGGED"
batfile = "/sys_vars/capa"

root = tk.Tk() 
root.withdraw() 

def read(sysfile):
    with open(sysfile, "r") as f:
        return f.read()

def loopcheck():
    plug = str(read(stat).strip())
    bat = int(read(batfile))
    if plug == plugged:
        sleep(2)
    if plug == unplugged and 6 <= bat <= 15:
        messagebox.showwarning("Alert!","Battery Low!\nCharging  Required!")
        sleep(2)
    if plug == unplugged and bat <= 5:
        messagebox.showwarning("ALERT!","Battery ULTRA Low!\nCharging  Required!")
        sleep(2)

if __name__ == "__main__":
    messagebox.showinfo("Running!","Battry Status Tracker is now running on machine")
    while True: 
        loopcheck()

I expect that I confirm the warning and then the message show after the amount of seconds.

The variables and the short sleep-timer in the example are there for tests.

rassar
  • 5,412
  • 3
  • 25
  • 41
FlashGGG
  • 5
  • 2
  • Read [While Loop Locks Application](https://stackoverflow.com/questions/28639228/python-while-loop-locks-application) and [Tkinter understanding mainloop](https://stackoverflow.com/questions/29158220/tkinter-understanding-mainloop) – stovfl Oct 31 '19 at 21:04
  • you should use `root.after(milliseconds , function_name)` to run with delay and this way you don't block `root.mainloop()` which you should run. – furas Oct 31 '19 at 21:18
  • thank you very much for the hints @stovfl and @furas! i dont know that i need the `mainlopp` function even when i have just a messagebox and the `after` function is completly new for me. I'll read something about it! – FlashGGG Oct 31 '19 at 21:53

1 Answers1

1

Instead of while True and sleep(2) you should use root.after(2000, loopcheck) to run function in delay. It will not block root.mainloop() which has to run all time to get key/mouse events from system, send events to widgets and redraw windows/widgets.

I don't have these /sys_vars to test it but it could be something like this:

import tkinter as tk 
from tkinter import messagebox

stat = "/sys_vars/status"
plugged = "PLUGGED"
unplugged = "UNPLUGGED"
batfile = "/sys_vars/capa"

def read(sysfile):
    with open(sysfile, "r") as f:
         return f.read()

def loopcheck():
    plug = str(read(stat).strip())
    bat  = int(read(batfile))

    if plug == unplugged:
        if 6 <= bat <= 15:
            messagebox.showwarning("Alert!","Battery Low!\nCharging  Required!")
        elif bat <= 5:
            messagebox.showwarning("ALERT!","Battery ULTRA Low!\nCharging  Required!")

    root.after(2000, loopcheck)

if __name__ == "__main__":

    root = tk.Tk() 
    root.withdraw() 

    messagebox.showinfo("Running!","Battry Status Tracker is now running on machine")
    root.after(2000, loopcheck)

    root.mainloop()
furas
  • 134,197
  • 12
  • 106
  • 148
  • Thank you, it works perfekt! I will deal more with tkinter. especially with the `mainloop` and `after` functions. – FlashGGG Oct 31 '19 at 21:55