Теги Tkinter на этикетках - PullRequest
1 голос
/ 22 января 2020

Использование tkinter с Python 3

У меня есть фрейм, к которому я привязываю функцию обратного вызова, когда кликаю по фрейму, но когда я помещаю виджеты в фрейм, они не реагируют на щелчок. Поэтому я хочу связать их с той же функцией обратного вызова, что и родительский фрейм, чтобы щелчок в любом месте фрейма работал. Есть ли способ присвоить тег виджету метки, чтобы я мог сделать frame.tag_bind () и связать все дочерние виджеты одновременно? Есть ли у фреймов метод .tag_bind ()? Или мне нужно привязать все виджеты по отдельности?

Вот несколько упрощенных кодов для текущей ситуации.

import tkinter as tk

class Window():
    def __init__(self, master):
        master.geometry('100x100')
        frame = tk.Frame(master)
        frame.pack(fill='both', expand=1)
        frame.bind('<Button-1>', self.callback)
        label = tk.Label(frame, text='Label')
        label.pack()

    def callback(self, event):
        print(event.x)

root = tk.Tk()
Window(root)
root.mainloop()

--- EDIT ---
Мой настоящий код содержит больше чем один кадр, поэтому bind_all не будет работать.

Ответы [ 2 ]

1 голос
/ 22 января 2020

Как вы упомянули, у вас есть более одного frame виджета в вас GUI, вы можете использовать следующий метод.

Используйте frame_widget.winfo_children(), чтобы получить child widget(s) внутри frame_widget , затем дайте callback каждому из дочерних виджетов.

Я добавил еще один виджет кадра в code you posted ради визуального понимания метода, который я использовал.

Вот код:

import tkinter as tk

class Window():
    def __init__(self, master):
        master.geometry('100x100')

        # --- frame 1 --- #
        frame1 = tk.Frame(master, bg='blue')
        frame1.pack(fill='both', expand=1)
        frame1.bind('<Button-1>', self.callback)

        label1 = tk.Label(frame1, text='Label 1 in frame 1')
        label1.pack()

        label2 = tk.Label(frame1, text='Label 2 in frame 1')
        label2.pack()

        # you can get the child widgets inside the frame and set callback
        for child_widget in frame1.winfo_children():
            child_widget.bind('<Button-1>', self.callback)

        # --- frame 1 --- #

        # --- frame 2 --- #
        frame2 = tk.Frame(master, bg='white')
        frame2.pack(fill='both', expand=1)
        #frame2.bind('<Button-1>', self.callback)

        label1 = tk.Label(frame2, text='Label 1 in frame 2')
        label1.pack()

        label2 = tk.Label(frame2, text='Label 2 in frame 2')
        label2.pack()
        # --- frame 2 --- #

    def callback(self, event):
            print(event.x)

root = tk.Tk()
Window(root)
root.mainloop()

gui

Итак, frame 1 имеет blue по цвету и frame 2 имеет white по цвету.

Теперь вы можете щелкнуть в любом месте внутри и на frame 1, включая child widgets и назначенный callback. С другой стороны, frame 2 вообще не назначается никакого обратного вызова.

Я пытался объяснить с некоторой теорией. Надеюсь, это поможет!

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

Вы можете смоделировать эффект tag_bind(...), добавив функцию tag_bind() в свой класс Window и назначив атрибут tag дочернему виджету Window экземпляр:

import tkinter as tk

class Window(tk.Frame):
    def __init__(self, master, *args, **kwargs):
        super().__init__(master, *args, **kwargs)
        self.bind('<Button-1>', self.callback)

    def callback(self, event):
        print(event.x)

    def tag_bind(self, tag, callback=None):
        for child in self.winfo_children():
            if hasattr(child, 'tag') and child.tag == tag:
                child.bind('<Button-1>', callback if callback else self.callback)

root = tk.Tk()

win = Window(root, bg='yellow')
win.pack(fill=tk.BOTH, expand=1)

lbl1 = tk.Label(win, text='Label')
lbl1.tag = 'label'  # assign a tag to this label
lbl1.pack()

lbl2 = tk.Label(win, text='Blocked')
lbl2.pack()

lbl3 = tk.Label(win, text='Passed')
lbl3.tag = 'passed'  # assign another tag to this label
lbl3.pack()

win.tag_bind('label') # bind to default internal callback
win.tag_bind('passed', lambda e: print('passed')) # bind to external callback

tk.Frame(root, width=100, height=100, bg='blue').pack()

root.mainloop()

Вы можно изменить функцию tag_bind() в соответствии с вашими требованиями.

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