Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Stopping a constant ping in Customtkinter

I have some working code that opens a gui and allows you to enter details for a network ping. There is then a switch to make it a constant ping.
This all works fine. (thanks to another thread here haha).

I’m hoping someone can help me with figuring out how to configure the other button to stop that constant ping without closing the gui. (it may not be possible).

My code is:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

import customtkinter
import os


customtkinter.set_appearance_mode("Dark")  # Modes: "System" (standard), "Dark", "Light"
customtkinter.set_default_color_theme("blue")  # Themes: "blue" (standard), "green", "dark-blue"


class App(customtkinter.CTk):
    def __init__(self):
        super().__init__()

        # configure window
        self.title("STEVE's IRT TOOL")
        self.geometry(f"{1100}x{580}")
        self.resizable(False, False)
        self.iconbitmap('icon.ico')

        # configure grid layout (4x4)
        self.grid_columnconfigure(1, weight=1)
        self.grid_columnconfigure((2, 3), weight=0)
        self.grid_rowconfigure((0, 1, 2), weight=1)

        def read_output(fp):
            line = fp.readline()
            if line:
                print_out.insert("end", line)
                print_out.see("end")
                print_out.after(10, read_output, fp)

        def button_ping():
            hostname = info.get()
            fp = os.popen(f"ping {switch_var.get()} {hostname}")
            read_output(fp)

        #def stop():

        # create sidebar frame with widgets
        self.sidebar_frame = customtkinter.CTkFrame(self, width=140, corner_radius=0)
        self.sidebar_frame.grid(row=0, column=0, rowspan=4, sticky="nsew")
        self.sidebar_frame.grid_rowconfigure(4, weight=1)
        self.logo_label = customtkinter.CTkLabel(self.sidebar_frame, text="IRT Tool", font=customtkinter.CTkFont(size=20, weight="bold"))
        self.logo_label.grid(row=0, column=0, padx=20, pady=(20, 10))
        info = customtkinter.CTkEntry(self.sidebar_frame, placeholder_text="Enter Input")
        info.grid(row=1, column=0, padx=20, pady=10)
        sidebar_button_ping = customtkinter.CTkButton(self.sidebar_frame, text="Ping", fg_color="transparent", border_width=2, text_color=("gray10", "#DCE4EE"), command=button_ping)
        sidebar_button_ping.grid(row=2, column=0, padx=20, pady=10)
        switch_var = customtkinter.StringVar(value="")
        switch = customtkinter.CTkSwitch(self.sidebar_frame, text="Constant", variable=switch_var, onvalue="-t", offvalue="")
        switch.grid(row=3, column=0, padx=20, pady=10)
        sidebar_button_stop = customtkinter.CTkButton(self.sidebar_frame, text="StopPing", fg_color="transparent", border_width=2, text_color=("gray10", "#DCE4EE"))#, command=stop)
        sidebar_button_stop.grid(row=4, column=0, padx=20, pady=10)

        self.appearance_mode_label = customtkinter.CTkLabel(self.sidebar_frame, text="Appearance Mode:", anchor="w")
        self.appearance_mode_label.grid(row=9, column=0, padx=20, pady=(10, 0))
        self.appearance_mode_optionemenu = customtkinter.CTkOptionMenu(self.sidebar_frame, values=["Light", "Dark", "System"],
                                                                       command=self.change_appearance_mode_event)
        self.appearance_mode_optionemenu.grid(row=10, column=0, padx=20, pady=(10, 10))

        # OUTPUT WINDOW
        print_out = customtkinter.CTkTextbox(self, width=250)
        print_out.grid(row=0, rowspan=2, column=1, padx=(20, 0), pady=(20, 0), sticky="nsew")



    def change_appearance_mode_event(self, new_appearance_mode: str):
        customtkinter.set_appearance_mode(new_appearance_mode)

    def sidebar_button_event(self):
        print("sidebar_button click")


if __name__ == "__main__":
    app = App()
    app.mainloop()

Many thanks in advance.

>Solution :

Use subprocess.Popen() instead of os.popen(), then you can call proc.terminate() to stop the process. proc is the object returned by subprocess.Popen().

import subprocess as subp
...

class App(customtkinter.CTk):
    def __init__(self):
        ...
        def read_output(proc):
            line = proc.stdout.readline()
            if line:
                print_out.after(10, read_output, proc)
            else:
                line = "--- done ---\n"
            print_out.insert("end", line)
            print_out.see("end")

        def button_ping():
            hostname = info.get().strip()
            if hostname:
                self.proc = subp.Popen(f"ping {switch_var.get()} {hostname}",
                                       stdout=subp.PIPE, stderr=subp.STDOUT,
                                       text=True, bufsize=1)
                read_output(self.proc)

        def stop():
            if self.proc:
                self.proc.terminate()
                self.proc = None

        self.proc = None

        ...
        sidebar_button_stop = customtkinter.CTkButton(self.sidebar_frame, text="StopPing", fg_color="transparent",
                                                      border_width=2, text_color=("gray10", "#DCE4EE"), command=stop)
        ...
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading