I’ve recently been working on a gadget that aims to generate a widget that displays the current system time, CPU and memory usage, and network upload and download speeds.
Initial goals:
- Generate a pop-up window and keep the window on top
- You can make settings in the pop-up window, check the corresponding information you want to display, and adjust the window transparency.
- End the program when the user closes the app
- Finally, it is packaged into an executable file and does not exist as a python file.
Preconditions:
python3
Additional libraries that need to be installed:
tkinter generate window
psutil monitors system resources
pyinstaller packages python scripts into exe files
The detailed code is as follows:
import tkinter as tk from tkinter import ttk import psutil import time class myClass: def __init__(self): #Create the main window self.root = tk.Tk() self.root.title("Configuration Window") self.root.geometry("400x300") # Set the window size to 300 pixels wide and 200 pixels high self.x = 0 #Monitoring system network resources, including uploading and downloading, etc... self.net_io_counters = psutil.net_io_counters() self.download_speed_b = self.net_io_counters.bytes_recv self.upload_speed_b = self.net_io_counters.bytes_sent def mainWin(self): root = self.root self.var1 = tk.IntVar() # Create a variable for the checked status of option 1 self.r = 1 #Generate a button on the root with the text 'time' check1 = ttk.Checkbutton(root, text="time", variable=self.var1) #Display the button on the window row and column represent the position, padx, pady represent the distance from the border check1.grid(row=self.r, column=0, padx=10,pady=10) self.r + = 1 #Move each item down one line to avoid display overlay self.var2 = tk.IntVar() check2 = ttk.Checkbutton(root, text="CPU and memory", variable=self.var2) check2.grid(row=self.r, column=0, padx=10,pady=10) self.r + = 1 self.var3 = tk.IntVar() check3 = ttk.Checkbutton(root, text="network", variable=self.var3) check3.grid(row=self.r, column=0, padx=10,pady=10) self.r + = 1 #Create a slider prompt self.var4 = tk.Text(root, height=1, width=25) self.var4.grid(row=self.r,column=0,padx=10,pady=10) self.var4.insert(tk.END, "High <--window transparency--> low") self.r + = 1 #Create the slide bar (4-100) if it is set to 0, it will be fully transparent, and you will not be able to find how to close the window. slider = ttk.Scale(root, from_=4, to=100, orient=tk.HORIZONTAL, command=self.on_slider_change) slider.grid(row=self.r, column=0, padx=10,pady=10) #Create a text box to display the selected value self.text_box = tk.Text(root, height=1, width=5) self.text_box.grid(row=self.r, column=1, padx=10,pady=10) self.r + = 1 ttk.Button(root, text="Execute configuration", command=self.updateInfo).grid(row=self.r, column=0, padx=10) #root.attributes("-alpha", 1) # Set the default window transparency of the main window root.mainloop() def on_slider_change(self,value): self.value = round(float(value),1) self.text_box.delete(1.0, tk.END) # Clear the text box content self.text_box.insert(tk.END, self.value) # Insert the current selection value into the text box self.root.attributes("-alpha", self.value/100) # Set window transparency def updateInfo(self): #self.root.withdraw() if self.x == 0: self.sWin = tk.Tk() self.sWin.attributes("-topmost", True) # Place the window on top of other windows self.sWin.attributes("-alpha", self.value/100) # Set window transparency self.sWin.protocol("WM_DELETE_WINDOW", self.closeRoot) #Set the action to be performed when clicking the "X" in the upper right corner if self.var1.get() == 1: #Set a label tk.Label(window, font=(font, size, style [bold bold]), bg="white" background color is white) self.clock = tk.Label(self.sWin, font=("times", 40, "bold"), bg="white") #Content is displayed in the window, fill="both" fills both top and bottom, expand=1 allows filling self.clock.pack(fill="both", expand=1) if self.var2.get() == 1: self.cpumem = tk.Label(self.sWin, font=("times", 20, "bold"), bg="white") self.cpumem.pack(fill="both", expand=1) if self.var3.get() == 1: self.netwok = tk.Label(self.sWin, font=("times", 20, "bold"), bg="white") self.netwok.pack(fill="both", expand=1) self.x = 1 #var1.get() grabs the value of the checked option on our window, 0 means unchecked, 1 means checked self.myvalue = [self.var1.get(),self.var2.get(),self.var3.get()] if self.myvalue[0] == 1: #Update time current_time = time.strftime("%H:%M:%S") self.clock.config(text=current_time) if self.myvalue[1] == 1: #Update CPU and mem usage cpu = str(psutil.cpu_percent()) mem = str(psutil.virtual_memory().percent) # Determine the memory usage below. If it is greater than 70, set it to orange, if it is greater than 90, it will be red, and for other characters, it will be black. if (float(mem) > 70) or (float(cpu) > 70): self.mycolor = "orange" elif (float(mem) > 90) or (float(cpu) > 90): self.mycolor = "red" else: self.mycolor = "black" self.cpumem.config(text="cpu:" + cpu + "% mem:" + mem + "%",fg=self.mycolor) if self.myvalue[2] == 1: #Update network upload and download speed #while True: net_io_counters = psutil.net_io_counters() self.download_speed_a = net_io_counters.bytes_recv self.upload_speed_a = net_io_counters.bytes_sent self.download_speed = round((self.download_speed_a - self.download_speed_b) / 1024,2) # Convert to KB/s self.upload_speed = round((self.upload_speed_a - self.upload_speed_b) / 1024,2) # round(x,2) floating point number retains two decimal places self.download_speed_b = self.download_speed_a self.upload_speed_b = self.upload_speed_a self.netwok.config(text="up:" + str(self.upload_speed) + "KB/s down:" + str(self.download_speed) + "KB/s") if self.myvalue[0] == 1: #Wait for 1000ms and execute the function again, aiming to refresh the content displayed in the window every second self.clock.after(1000, self.updateInfo) else: if self.myvalue[1] == 1: self.cpumem.after(1000, self.updateInfo) else: self.netwok.after(1000, self.updateInfo) def closeRoot(self): #Set when I click to close the window, completely destroy the window. You can achieve the purpose of stopping the script from running. self.sWin.destroy() self.root.destroy() if __name__ == "__main__": app = myClass() app.mainWin() """# Create labels and input boxes ttk.Label(root, text="username").grid(row=0) user_entry = ttk.Entry(root) user_entry.grid(row=0, column=1) ttk.Label(root, text="password").grid(row=1) password_entry = ttk.Entry(root, show="*") password_entry.grid(row=1, column=1)"""
Packaging code:
pyinstaller -w x.py -F
Use pyinstaller for packaging
-w means to hide the executed CMD window
x.py is a python script
-F means packaging into an independent executable file, which is an exe file. If you do not add this parameter, additional folders will be generated. If you put it in other environments, you need to bring the folder with you, otherwise it will not be executed.
After execution, two folders will be generated
build and dist
Our executable file is in dist. This exe file can be placed on any other computer and executed directly by double-clicking it. There is no need for other computers to download library files first, etc.
Here are sample photos: