как вставить виджет в другой, если они из разных классов. и как создать универсальную функцию закрытия дочерних виджетов?

#python #class #tkinter #widget

#python #класс #tkinter #виджет

Вопрос:

это мой код. Я не могу поместить label2 в self.main , и я не знаю, как написать общий код функции, который закрывал бы дочерние виджеты, которые можно указать в аргументах.

 import tkinter


class mainwin:
    def __init__(self):
        self.root = tkinter.Tk()
        self.main = tkinter.Canvas(self.root, width=200, height=400)
        self.main.place(x=0, y=0, relwidth=1, relheight=1)
        self.main.config(bg='green')
        self.root.mainloop()


class addlabel:
    def __init__(self):
        self.label2 = tkinter.Label(mainwin.main, height=2, width=50,   text='Hello Noob!!') 
        #can't put on the canvas 'main'
        self.label2.place(x=0, y=50)
        self.exit_button = tkinter.Button(self.label2, text='Exit')
        self.exit.button.bind('<1>', quit_from_widget)

'''
class quit_from_widget:

  def __init__(self):
    # what code should be written here, to quit any child widget.
'''

mainwin()
addlabel()
  

Комментарии:

1. Вызов addlabel() в самом конце не выполняется, когда вы думаете, потому что предыдущий вызов self.root.mainloop() in mainwin.__init__() не возвращается, пока вы не закроете окно.

Ответ №1:

Возможно, вы сможете использовать:

 mylist = parent.winfo_children();
  

Затем используйте цикл for и destroy(), чтобы закрыть их

Основная причина, по которой вы не можете вставить метку, заключается в том, что вы вызываете mainloop() перед addLabel . Программа перебирает код и не выполняет addlabel(), пока вы не закроете функцию mainwin() .

во-вторых, вы не можете сделать mainw.main . класс не имеет ссылки на эту функцию. вместо этого попробуйте добавить родительскую функцию в свой addlabel вот так:

 class addlabel:
def __init__(self, parent):
    self.label2 = tkinter.Label(parent, height=2, width=50,   text='Hello Noob!!')
    self.label2.place(x=0, y=50)
    self.exit_button = tkinter.Button(self.label2, text='Exit')
    self.exit_button.bind('<1>', quit)
  

Затем, когда вы вызываете функцию в классе mainw (перед строкой self.root.mainloop()), вы бы написали:

 addlabel(self.main)
  

Комментарии:

1. можете ли вы на примере моего кода написать, как все сделать? Я буду вам очень благодарен

2. Что ж, я был бы признателен, если бы вы сначала попробовали то, что я предложил. Какая часть доставляет вам проблемы?

Ответ №2:

 import tkinter

class mainwin:
    def __init__(self):
        self.root = tkinter.Tk()
        self.main = tkinter.Canvas(self.root, width=200, height=400)
        self.main.place(x=0, y=0, relwidth=1, relheight=1)
        self.main.config(bg='green')
        self.root.mainloop()


class CustomLabel(tkinter.Frame):
    def __init__(self, parent):
        tkinter.Frame.__init__(self, parent)

        self.label = tkinter.Label(self, height=20, width=30, bg='Red', fg='white', text='Hello')
        self.exit_button = tkinter.Button(self, command=self.destroy)

        # pack these widgets into this frame. You can use grid or
        # place, but pack is easiest for such a simple layout
        self.exit_button.pack(side="right")
        self.label.pack(side="left", fill="both", expand=True)



window = mainwin()

label = CustomLabel(window.main)
  

ничего не происходит. выдает зеленый фон, а дочерний виджет не виден. но при закрытии он пишет ошибку:
….
(widgetName, self._w) дополнительный self._options(cnf))
_ткинтеръ.TclError: не удается вызвать команду «frame»: приложение уничтожено

Процесс завершен с кодом выхода 1

Комментарии:

1. похоже, это не ответ на вопрос.