简体   繁体   中英

tkinter how to update text on a dynamically created label

I am dynamically creating a given amount of labels (3 in the example) now I would like to individually update the text in them but how can I detect which one is the correct to update?

also is it possible to add some sort of listener in the server class which will report any changes in the status to the GUI so that I don't have to check after every action?

here is an example that I have prepared:-

import tkinter as tk
import time


class App(tk.Tk):
    def __init__(self):
        super().__init__()

        servers = ["Server One", "Server Two", "Server Three"]

        for i, server in enumerate(servers):
            server_instance = Server(server)
            label_server_name = tk.Label(self, text=server)
            label_server_name.grid(row=i + 1, column=0)

            self.label_server_status = tk.Label(self, text="Not Running")
            self.label_server_status.grid(row=i + 1, column=1)

            button_start_server = tk.Button(
                self,
                text="Start",
                command=lambda inst=server_instance: self._start_server(inst),
            )
            button_start_server.grid(row=i + 1, column=2)

            button_stop_server = tk.Button(
                self,
                text="Stop",
                command=lambda inst=server_instance: self._stop_server(inst),
            )
            button_stop_server.grid(row=i + 1, column=3)

    def _start_server(self, server):
        server.start_server()
        # how do I select the correct server text?
        self.label_server_status["text"] = "Starting..."

        # Simulate server starting
        time.sleep(1)
        self._update_status(server)

    def _stop_server(self, server):
        server.stop_server()
        # how do I select the correct server text?
        self.label_server_status["text"] = "Stopping..."

        # Simulate server starting
        time.sleep(1)
        self._update_status(server)

    def _update_status(self, server):
        if server.is_running:
            print(f"{server.name} is running")
            # Change relevant label_server_status to Running
        else:
            print(f"{server.name} is not running")
            # Change relevant label_server_status to Not Running


class Server:
    def __init__(self, name):
        self.name = name
        self.is_running = False

    def start_server(self):
        # simulte starting the server
        self.is_running = True
        return True

    def stop_server(self):
        self.is_running = False


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

Thanks to @TheLizzard for commenting above, as he correctly said the solution was to put the labels into a dictionary, here is my completed working example:

import tkinter as tk


class App(tk.Tk):
    def __init__(self):
        super().__init__()

        servers = ["Server One", "Server Two", "Server Three"]

        self.labels = {}

        for i, server in enumerate(servers):
            server_instance = Server(server)
            label_server_name = tk.Label(self, text=server)
            label_server_name.grid(row=i + 1, column=0)

            label_server_status = tk.Label(self, text="Not Running")
            label_server_status.grid(row=i + 1, column=1)

            self.labels[server] = label_server_status

            button_start_server = tk.Button(
                self,
                text="Start",
                command=lambda inst=server_instance: self._start_server(inst),
            )
            button_start_server.grid(row=i + 1, column=2)

            button_stop_server = tk.Button(
                self,
                text="Stop",
                command=lambda inst=server_instance: self._stop_server(inst),
            )
            button_stop_server.grid(row=i + 1, column=3)

    def _start_server(self, server):
        server.start_server()

        self._update_status(server)

    def _stop_server(self, server):
        server.stop_server()

        self._update_status(server)

    def _update_status(self, server):
        if server.is_running:
            print(f"{server.name} is running")
            self.labels[server.name]["text"] = "running"
        else:
            print(f"{server.name} is not running")
            self.labels[server.name]["text"] = "not running"


class Server:
    def __init__(self, name):
        self.name = name
        self.is_running = False

    def start_server(self):
        # simulte starting the server
        self.is_running = True
        return True

    def stop_server(self):
        self.is_running = False


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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM