Как добавить таймер для каждого экрана деления в tkinter - PullRequest
0 голосов
/ 08 января 2020

Я создал одно окно и разделил его на 3 разных windows. Я хочу добавить часы на каждый экран, который не зависит от других часов. Мой код открывает 2 окна - одно - таймер, а второе - окно, которое я разделил на 3 windows.

    from tkinter import *
import Tkinter as tk


class split_screen(tk.Tk):
    def __init__(self):
        tk.Tk.__init__(self)
        self.label = tk.Label(self, text="", width=10,fg="black", bg ="red", font="david 18 bold underline")
        self.label.pack()
        self.remaining = 0
        self.countdown(1000)
        self.configure(background="black")


    def screen(self):
        root = Tk()
        root.geometry("650x700")
        root.configure(bg='black')
        root.title("test")
        left = Frame(root, borderwidth=200, relief="solid")
        right = Frame(root, borderwidth=20, relief="solid")
        box3 = Frame(right, borderwidth=2, relief="solid")
        box1 = Frame(left, borderwidth=2, relief="solid")
        box2 = Frame(left, borderwidth=2, relief="solid")

        label1 = Label(box3, text="winner's" + "\n\n\n" + "Player 1",fg= "black", bg = "red", font = "david 18 bold underline")
        label2 = Label(box1, text="Computer 1",fg = "black", bg = "red", font= "david 18 bold underline")
        label3 = Label(box2, text="Computer 2",fg = "black", bg = "red", font= "david 18 bold underline")

        left.pack(side="left", expand=True, fill="both")
        right.pack(side="right", expand=True, fill="both")

        box3.pack(expand=True, fill="both", padx=10, pady=10)
        box1.pack(expand=True, fill="both", padx=10, pady=10)
        box2.pack(expand=True, fill="both", padx=10, pady=10)

        label1.pack()
        label2.pack()
        label3.pack()


    def countdown(self, remaining = None):
        if remaining is not None:
            self.remaining = remaining

        if self.remaining <= 0:
            self.label.configure(text="time's up!")
        else:
            self.label.configure(text="%d" % self.remaining)
            self.remaining = self.remaining - 1
            self.after(1000, self.countdown)

if __name__ == "__main__":
    app = split_screen()
    app.screen()
    app.mainloop()

Ответы [ 2 ]

0 голосов
/ 08 января 2020

Я сделал несколько изменений: как сказал Брайан Оукли, не создавайте несколько экземпляров Tk (). Вам также не нужно дважды импортировать tkinter.

import tkinter as tk


class split_screen(tk.Tk):
    def __init__(self):
        tk.Tk.__init__(self)

        self.geometry("650x700")
        self.configure(bg='black')
        self.title("test")
        left = tk.Frame(self, borderwidth=200, relief="solid")
        right = tk.Frame(self, borderwidth=20, relief="solid")
        box1 = tk.Frame(left, borderwidth=2, relief="solid")
        box2 = tk.Frame(left, borderwidth=2, relief="solid")
        box3 = tk.Frame(right, borderwidth=2, relief="solid")

        label1 = tk.Label(box3, text="winner's" + "\n\n\n" + "Player 1",fg= "black", bg = "red", font = "david 18 bold underline")
        label2 = tk.Label(box1, text="Computer 1",fg = "black", bg = "red", font= "david 18 bold underline")
        label3 = tk.Label(box2, text="Computer 2",fg = "black", bg = "red", font= "david 18 bold underline")

        clock1 = Clock(box1, 1000)
        clock2 = Clock(box2, 2000)
        clock3 = Clock(box3, 1300)

        left.pack(side="left", expand=True, fill="both")
        right.pack(side="right", expand=True, fill="both")

        box3.pack(expand=True, fill="both", padx=10, pady=10)
        box1.pack(expand=True, fill="both", padx=10, pady=10)
        box2.pack(expand=True, fill="both", padx=10, pady=10)

        label1.pack()
        label2.pack()
        label3.pack()


class Clock():
    def __init__(self, frame, count):
        self.frame = frame
        self.label = tk.Label(frame, text="", width=10,fg="black", bg ="red", font="david 18 bold underline")
        self.label.pack()
        self.remaining = 0
        self.countdown(count)
        frame.configure(background="black")

    def countdown(self, remaining = None):
        if remaining is not None:
            self.remaining = remaining

        if self.remaining <= 0:
            self.label.configure(text="time's up!")
        else:
            self.label.configure(text="%d" % self.remaining)
            self.remaining = self.remaining - 1
            self.frame.after(1000, self.countdown)

if __name__ == "__main__":
    app = split_screen()
    app.mainloop()
0 голосов
/ 08 января 2020

Самое простое решение - и, возможно, лучшее - это создать класс, представляющий один таймер. Вы можете сделать столько экземпляров, сколько захотите. Это как раз то, для чего предназначены классы: для инкапсуляции некоторого поведения внутри объекта.

Поскольку вы используете метку для отображения времени, вы можете получить класс таймера, унаследованный от Label или вы можете передать метку при создании таймера.

Вот пример, который наследуется от tk.Label:

import tkinter as tk

class TimerLabel(tk.Label):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.after_id = None
        self.remaining = None

    def countdown(self, seconds):
        if seconds <= 0:
            self.configure(text="Time's up!")
        else:
            self.configure(text=f"{seconds}")
            self.after_id = self.after(1000, self.countdown, seconds-1)

    def stop(self):
        if self.after_id:
            self.configure(text="cancelled")
            self.after_cancel(self.after_id)

Используя приведенное выше определение класса, вы можете создать столько таймеров виджеты как хотите. Вот пример, который создает три:

root = tk.Tk()

timer1 = TimerLabel(root, width=10)
timer2 = TimerLabel(root, width=10)
timer3 = TimerLabel(root, width=10)

timer1.pack(side="top", padx=20)
timer2.pack(side="top", padx=20)
timer3.pack(side="top", padx=20)

timer1.countdown(30)
timer2.countdown(20)
timer3.countdown(10)

root.mainloop()
...