simple tkinter battery monitor

leonix.power at gmail.com leonix.power at gmail.com
Tue Jan 29 22:02:56 EST 2013


Thank you very much! fixed with w.after
Here is the code, works under Linux for those who have acpi.
My output of "acpi -V" is the following, the code is parsing the first line of the output. Any improvements are appreciated.

> $ acpi -V
> Battery 0: Discharging, 12%, 00:10:59 remaining
> Battery 0: design capacity 2200 mAh, last full capacity 1349 mAh = 61%
> Adapter 0: off-line
> Thermal 0: ok, 40.0 degrees C
> Thermal 0: trip point 0 switches to mode critical at temperature 98.0 degrees C
> Thermal 0: trip point 1 switches to mode passive at temperature 93.0 degrees C
> Cooling 0: Processor 0 of 10
> Cooling 1: Processor 0 of 10
> Cooling 2: Processor 0 of 10
> Cooling 3: Processor 0 of 10
> Cooling 4: LCD 0 of 9


----------------------------------------------------------
----------------------------------------------------------
----------------------------------------------------------


#!/usr/bin/python3.2

from re import findall, search
from threading import Thread
from time import sleep
from subprocess import Popen, call, PIPE, STDOUT
from tkinter import Tk, Label, StringVar



def runProcess(exe):
        p=Popen(exe, stdout=PIPE, stderr=STDOUT)
        while True:
                retcode=p.poll()
                line=p.stdout.readline()
                yield line
                if retcode is not None:
                        break


class BatteryMonitor:

        def __init__(self):
                root = Tk()
                root.configure(padx=1, pady=1, bg="#555753")
                root.geometry("-0+0")
                root.overrideredirect(True)
                root.wm_attributes("-topmost", True)
                self.batteryExtendedStringVar = StringVar()
                self.batteryPercentStringVar = StringVar()
                self.batteryExtendedLabel = Label(root, textvariable=self.batteryExtendedStringVar, font=("fixed", 9), bg="#3e4446", fg="#d3d7cf", padx=10, pady=-1)
                self.batteryPercentLabel = Label(root, textvariable=self.batteryPercentStringVar, font=("fixed", 9), width=4, bg="#3e4446", fg="#d3d7cf", padx=-1, pady=-1)
                self.batteryPercentLabel.grid()
                t = Thread(target=self.update_battery_level_loop)
                t.start()
                root.bind("<Button-1>", self.display_details)
                self.root = root
                root.mainloop()
       
        def display_details(self, event):
                # displays a message about details of battery status
                # i.e. "on-line" or "charging, 20 min left" and so on
                self.batteryPercentLabel.grid_remove()
                self.batteryExtendedLabel.grid()
                self.batteryExtendedLabel.after(1000, self.batteryExtendedLabel.grid_remove)
                self.batteryPercentLabel.after(1000, self.batteryPercentLabel.grid)
       
        def read_battery_level(self):
                # dummy function used just to test the GUI
                for line in runProcess(["acpi", "-V"]):
                        if line[11:-1]!=b"on-line":
                                self.level = findall(b"\d\d?", line[11:])[0]
                        else:
                                self.level = b"0"
                        return line[11:-1]
       
        def update_battery_level_loop(self):
                # threaded function, should constantly update the battery level
                self.read_battery_level()
                while True:
                        self.batteryPercentStringVar.set(str(self.level)[2:-1]+"%")
                        self.batteryExtendedStringVar.set(self.read_battery_level())
                        if self.level == 2:
                                runProcess(["shutdown", "-h", "now"])
                                return
                        sleep(5)





##############################################
#
# main

BatteryMonitor()



More information about the Python-list mailing list