Как динамически обновлять виджеты холста tkinter? - PullRequest
0 голосов
/ 23 февраля 2020

Я пишу программу для имитации сигнала железной дороги, которая в конечном итоге будет работать на Raspberry Pi, получающем аналоговые сигналы через AD C для управления сигналами разных цветов.

Я очень плох в программировании GUI, поэтому мой вопрос в том, как написать функцию для изменения цвета каждого "светодиода", который я могу в конечном итоге вызывать при каждом обнаружении высокого напряжения? Сейчас я просто хочу иметь функцию set_top_signal ("Green"), которая может быть вызвана для обновления графика c.

. Затем я хочу написать функцию для fla sh сигнала включается и выключается каждые пол секунды. flash_top_signal ("Зеленый")

Текущий GUI Фото

import tkinter as tk

class WaysideSimulator(tk.Frame):

    def __init__(self, master=None):
        super().__init__(master)
        self.master = master
        # self.pack()
        self.grid()
        self.create_widgets()

    def create_widgets(self):

        self.Searchlight_Button = tk.Button(self, text="Start Simulation", command=self.start_simulation())
        # self.Searchlight_Button.pack(side="bottom")
        self.Searchlight_Button.grid(row=0, column=0)

        self.End_Simulation_Button = tk.Button(self, text="End Simlation", fg="red", command=self.master.destroy)
        # self.End_Simulation_Button.pack(side="bottom")
        self.End_Simulation_Button.grid(row=1, column=0)

        # Draw the Signal Rectangle
        self.canvas = tk.Canvas(self, width=500, height=500, bg="white")
        # self.rectangle.pack()
        self.canvas.grid()

        # Draw the Searchlight Signal Heads
        self.signal_pole = self.canvas.create_rectangle(245, 20, 255, 500, fill="grey")

        self.top_signal_head = self.canvas.create_oval(200, 10, 300, 110, fill="black")
        self.middle_signal_head = self.canvas.create_oval(200, 160, 300, 260, fill="black")
        self.bottom_signal_head = self.canvas.create_oval(200, 310, 300, 410, fill="black")

        self.top_signal_light = self.canvas.create_oval(240, 50, 260, 70, fill="red")
        self.middle_signal_light = self.canvas.create_oval(240, 200, 260, 220, fill="yellow")
        self.bottom_signal_light = self.canvas.create_oval(240, 350, 260, 370, fill="green")

    def set_top_signal_color(self, color):
        self.canvas.delete(self.top_signal_light)
        self.canvas.delete(self.middle_signal_light)
        self.canvas.delete(self.bottom_signal_light)

        """
        Signal Color Code Chart:
        0 = Black(Off)
        1 = Red
        2 = Yellow
        3 = Green
        """
        if color == "Off":
            self.top_signal_light = self.canvas.create_oval(240, 50, 260, 70, fill="black")
        elif color == "Red":
            self.top_signal_light = self.canvas.create_oval(240, 50, 260, 70, fill="red")
        elif color == "Yellow":
            self.top_signal_light = self.canvas.create_oval(240, 50, 260, 70, fill="yellow")
        elif color == "Green":
            self.top_signal_light = self.canvas.create_oval(240, 50, 260, 70, fill="green")

    def start_simulation(self):
        print("Searchlight Simulation Started")


def main():
    root = tk.Tk()
    root.title("Searchlight Simulator")
    root.geometry("500x525")
    root.resizable(0, 0)
    s1 = WaysideSimulator(master=root)
    s1.mainloop()


if __name__ == '__main__':
    main()

Ответы [ 2 ]

0 голосов
/ 23 февраля 2020

Ошибка в том, что вы вызываете функцию __init__, root_window.mainloop(), поэтому .set_top_signal_color("Off") никогда не достигается (mainloop() - это функция блокировки).

Вы можете это исправить с 2 шагами.

Шаг 1 Если вы запустите:

sl = SearchLight()
sl.set_top_signal_color("Off")
sl.root_window.mainloop()

И удалите root_window.mainloop() из __init__, вы получите AttributeError: 'int' object has no attribute 'get'.

Это потому, что вы не используете рекомендованную .set() функцию для переменных Tkinter. Но теперь мы можем изменить приложение до того, как mainl oop заблокирует пользовательский интерфейс. (если вы хотите понять, что я имею в виду, прикрепите точку останова после SearchLight() строки)

Шаг 2 Теперь рефакторинг для использования .set(), выведенный тип self.signal_color больше не int.

def set_top_signal_color(self, color):
    if color == "Off":
        self.signal_color.set(0)
    elif color == "Red":
        self.signal_color.set(1)
    elif color == "Yellow":
        self.signal_color.set(2)
    elif color == "Green":
        self.signal_color.set(3)
    self.update_signal_color()
0 голосов
/ 23 февраля 2020

Недавно я задал похожий вопрос о вращении изображений костей для имитации пары костей. Возможно, если все, что вам нужно сделать, это «повернуть» к новому «сигнальному» изображению, то вы можете отменить то, что вам нужно, из рабочего кода, который я разместил по этой ссылке (пожалуйста, укажите acw1668, без чьей помощи я бы не пришел к рабочей версии !):

Tkinter, python 3.8.1, win10Pro, Как изменить изображение метки?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...