Как получить доступ к индивидуальной кнопке tkinter? - PullRequest
1 голос
/ 05 августа 2020

Цель: динамически создать метку и кнопку (представляет задачу), и когда я нажимаю эту кнопку, она должна уничтожить метку и кнопку.

Проблема: невозможно получить доступ к кнопкам по отдельности

Вот мой код:

class Gui:

    # constructor
    def __init__(self, root):
        self.root = root
        self.root.title("TASKS")
        self.root.geometry("300x700")
        self.root.resizable(width=False, height=False)
        self.clock = Label(self.root, fg="blue")
        self.clock.grid(row = 0,column = 0,padx = 80,pady = 40)
        self.update_clock()
        self.new_button = Button(self.root, text="New",command = self.newwindow).grid(row = 0, column =1)
        self.r =0
    # clock
    def update_clock(self):
        now = strftime("%H:%M:%S")
        self.clock.configure(text=now)
        self.clock.after(1000, self.update_clock)

    # label creator
    def label(self, txt):
        self.l = Label(self.root, text=txt, fg="red",pady =15)
        self.l.grid(row = self.r, column =0)

    # button creator
    def donebutton(self):
        self.b = Button(self.root, text="Done",command = lambda : self.del_task())
        self.b.grid(row = self.r,column = 1)

    # create a task
    def task(self,txt):
        self.r +=1
        self.label(txt)
        self.donebutton()

    # delete task
    def del_task(self):
        self.l.destroy()
        self.b.destroy()

    # display gui method
    def display(self):
        self.root.mainloop()

    # new window
    def newwindow(self):
        self.newwindow = Toplevel(self.root)
        self.newwindow.title("NEW TASK")
        self.newwindow.geometry("300x200")
        self.newwindow.resizable(width=False, height=False)
        Label(self.newwindow,text="Task").grid()
        self.t1 = Text(self.newwindow,height = 2,width = 36)
        self.t2 = Text(self.newwindow,height = 2,width = 10)
        self.t1.grid()
        Label(self.newwindow, text="Time").grid()
        self.t2.grid()
        self.c_b=Button(self.newwindow,text = "CREATE",command = lambda : self.task(self.t1.get("1.0",END)))

        self.c_b.grid()

if __name__ == '__main__':
    a = Gui(Tk())
    a.display()

Запрашиваю помощь с кодом, и я не против изменить весь код.

1 Ответ

1 голос
/ 05 августа 2020

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

  • Windows, Часы и задачи разделены на классы
  • нет целевых ссылок до windows или удерживаются кнопки
  • command для «New Button» создает NewTasks окно
  • command для «Done Button» уничтожает его родительский элемент
  • command для кнопки «Создать» создает Task в главном окне
  • был добавлен прокручиваемый фрейм, поэтому задачи никогда не могут вертикально выходить за пределы главного окна
  • запуск, пауза, выполнение и удаление Buttons были включены
  • включена прокручиваемая панель вывода
  • включена возможность перемещать задачи на дисплее
  • метки задач можно щелкать для отображения их содержимого на панели вывода
  • отчет о запуске, приостановке и завершении, а готово включает в себя прошедшее время
  • после запуска задачи ее нельзя удалить
  • задача может быть «выполнена», только если она запущена g
  • было применено небольшое форматирование виджетов / сеток, чтобы дисплей не прыгал при создании / удалении задач

Мне стало скучно и я создал ваше приложение ... вероятно.

from tkinter import Tk, Button, Label, Toplevel, Text, Frame, Canvas, Scrollbar
from time import strftime, time


class Task(Frame):    
    def __init__(self, master, text, output, move, **kwargs):
        Frame.__init__(self, master, **kwargs)
        self.grid_columnconfigure(0, weight=1)
        
        self.stored     = []
        self.starttime  = 0
        self.send_output= output
        
        self.lbl = Label(self, text=text, height=1, anchor='nw', fg='blue', font='calibri 14')
        self.lbl.grid(row=0, column=0, sticky='nswe')
        self.lbl.bind('<1>', self.output)
        
        font = 'consolas 10 bold'
        self.b1 = Button(self, font=font, text=chr(9654), command=self.start)
        self.b2 = Button(self, font=font, text=chr(10073)+chr(10073), state='disabled', command=self.pause)
        self.b3 = Button(self, font=font, text=chr(10006), state='disabled', command=self.done)
        self.b4 = Button(self, font=font, text=chr(9866), command=self.destroy)
        self.b5 = Button(self, font=font, text=chr(9650), command=lambda: move(self, -1))
        self.b6 = Button(self, font=font, text=chr(9660), command=lambda: move(self, 1))
        
        self.b1.grid(row=0, column=1) #start
        self.b2.grid(row=0, column=2) #pause
        self.b3.grid(row=0, column=3) #done
        self.b4.grid(row=0, column=4) #remove
        self.b5.grid(row=0, column=5) #move up
        self.b6.grid(row=0, column=6) #move down
        
    def start(self):
        self.b1['state'] = 'disabled'
        self.b2['state'] = 'normal'
        self.b3['state'] = 'normal'
        self.b4['state'] = 'disabled'
        
        self.starttime = time()
        self.send_output(f"{self.lbl['text']}", f"{strftime('%I:%M:%S')} STARTED: ")
        
    def pause(self):
        self.b1['state'] = 'normal'
        self.b2['state'] = 'disabled'
        self.b3['state'] = 'disabled'
        
        self.stored.append(time() - self.starttime)
        self.send_output(f"{self.lbl['text']}", f"{strftime('%I:%M:%S')} PAUSED: ")
        
    def done(self):
        self.stored.append(time() - self.starttime)
        t = sum(self.stored)
        self.send_output(f"{self.lbl['text']}\telapsed time: {self.etime(t)}\n", f"{strftime('%I:%M:%S')} FINISHED: ")
        self.destroy()
        
    def etime(self, s):
        h = int(s//3600)
        s -= 3600*h
        m = int(s//60)
        s -= 60*m
        return f'{h:02}:{m:02}:{int(s):02}'
        
    def output(self, event):
        self.send_output(self.lbl['text'], 'Task: ')
        
        
class NewTasks(Toplevel):
    WIDTH  = 416
    HEIGHT = 50

    def __init__(self, master, slave, output, move, **kwargs):
        Toplevel.__init__(self, master, **kwargs)
        self.title("New Task")
        self.geometry(f'{NewTasks.WIDTH}x{NewTasks.HEIGHT}')
        self.resizable(width=False, height=False)

        Label(self, text="Task").grid(row=0, column=0)
        txt = Text(self, height=2, width=36, font='consolas 12')
        txt.grid(row=0, column=1)

        Button(self, text="CREATE", command=lambda: self.create(slave, output, move, txt)).grid(row=0, column=2, sticky='e', padx=4, pady=12)

    def create(self, target, output, move, txt):
        t = Task(target.frame, txt.get("1.0",'end'), output, move)
        t.grid(column=0, sticky='nswe')
        target.update(t)
        

class ScrollFrame(Canvas):
    def __init__(self, master, **kwargs):
        Canvas.__init__(self, master, **kwargs)
        vsb = Scrollbar(self, orient='vertical', command=self.yview)
        vsb.pack(side='right', fill='y')
        self.configure(yscrollcommand=vsb.set)
        
        self.frame = Frame(self, height=0)
        self.frame.grid_columnconfigure(0, weight=1)
        self.frame.bind('<Configure>', lambda e:self.configure(scrollregion=self.bbox("all")))
        self.create_window((0,0), width=App.WIDTH-20, window=self.frame, anchor="nw")
        
        self.movelist = []
        
    def update(self, target):
        self.movelist.append(target)
        
    def move_item(self, elem, dir=1):
        c = self.frame.winfo_children()
        i = self.movelist.index(elem)
        if i+dir in range(0, len(self.movelist)):
            e = self.movelist.pop(i)
            self.movelist.insert(i+dir, e)
            for n in range(len(self.movelist)):
                while n < len(self.movelist) and self.movelist[n] not in c:
                    self.movelist.pop(n)
                    
                if n < len(self.movelist):  
                    self.movelist[n].grid(row=n, column=0, sticky='nswe')
                    continue
                break


class Clock(Label):
    def __init__(self, master, **kwargs):
        Label.__init__(self, master, **kwargs)
        self.update()
        
    def update(self):
        self['text'] = strftime('%I:%M:%S')
        self.after(1000, self.update)


class App(Tk):
    WIDTH  = 600
    HEIGHT = 447

    def __init__(self, **kwargs):
        Tk.__init__(self, **kwargs)
        self.grid_rowconfigure(1, weight=1)
        self.grid_columnconfigure(0, weight=1)
        Clock(self, fg="blue", font='calibri 18').grid(row=0, column=0, ipady=10, sticky='nswe')
        
        sf = ScrollFrame(self, highlightthickness=0)
        sf.grid(row=1, column=0, columnspan=3, sticky='nswe')
        
        command = lambda: NewTasks(self, sf, self.output, sf.move_item)
        Button(self, text="New", font='calibri 12', command=command).grid(row=0, column=1, columnspan=2)
        
        self.out = Text(self, height=8, font="calibri 14")
        self.out.grid(row=2, column=0, columnspan=2)
        self.out.tag_configure("bold", font="calibri 12 bold")
        
        vsb = Scrollbar(self, orient='vertical', command=self.out.yview)
        vsb.grid(row=2, column=2, sticky='ns')
        
        self.out.configure(yscrollcommand=vsb.set)

    def output(self, text, btext=''):
        self.out.insert('end', btext, 'bold')
        self.out.insert('end', text)
        

if __name__ == '__main__':
    app = App()
    app.title("Task Scheduler")
    app.geometry(f'{App.WIDTH}x{App.HEIGHT}')
    app.resizable(width=False, height=False)
    app.mainloop()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...