A small window plug-in used to display the current system time, CPU and memory usage, and network upload and download speeds.

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:

  1. Generate a pop-up window and keep the window on top
  2. You can make settings in the pop-up window, check the corresponding information you want to display, and adjust the window transparency.
  3. End the program when the user closes the app
  4. 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: