Как напечатать текст в ярлыках, созданных из списка при нажатии на - PullRequest
0 голосов
/ 11 февраля 2020

Я создаю метки из списка, перебирая список и создавая каждую метку, поскольку для l oop итерируется по списку. Я пытаюсь заставить программу печатать текст в ярлыке при нажатии, но вместо этого программа печатает имя последнего созданного ярлыка.

Код

from tkinter import *
from tkinter import ttk  

root = Tk()

friends = ["Luke", "Justin", "Sam"]

# *** Scrollable Frame Class ***
class VerticalScrolledFrame(Frame):
    def __init__(self, parent, *args, **kw):
        Frame.__init__(self, parent, *args, **kw)

        vscrollbar = Scrollbar(self, orient=VERTICAL)
        vscrollbar.pack(fill=Y, side=LEFT, expand=FALSE)
        canvas = Canvas(self, bd=0, highlightthickness=0, yscrollcommand=vscrollbar.set, bg="#383C41")
        canvas.pack(side=LEFT, fill=BOTH, expand=TRUE)
        vscrollbar.config(command=canvas.yview)

        canvas.xview_moveto(0)
        canvas.yview_moveto(0)

        self.interior = interior = Frame(canvas)
        interior_id = canvas.create_window(0, 0, window=interior,
                                       anchor=NW)
        def _on_mousewheel(event):
            canvas.yview_scroll(int(-1 * (event.delta / 120)), "units")
        self.interior.bind_all("<MouseWheel>", _on_mousewheel)
        canvas.bind_all("<MouseWheel>", _on_mousewheel)

        def _configure_interior(event):
            size = (interior.winfo_reqwidth(), interior.winfo_reqheight())
            canvas.config(scrollregion="0 0 %s %s" % size)
            if interior.winfo_reqwidth() != canvas.winfo_width():
            canvas.config(width=interior.winfo_reqwidth())
        interior.bind('<Configure>', _configure_interior)

        def _configure_canvas(event):
            if interior.winfo_reqwidth() != canvas.winfo_width():
                canvas.itemconfigure(interior_id, width=canvas.winfo_width())
        canvas.bind('<Configure>', _configure_canvas)

def switch_target(event):
    print(name.cget("text"))


# *** Set frame for friends view ***
friends_frame = VerticalScrolledFrame(root, bg="#23272A")
friends_frame.pack(side=LEFT, fill=BOTH, expand=TRUE)

for friend in friends:
    friend_frame = Frame(friends_frame.interior)
    friend_frame.pack(fill=X)
    name = Label(friend_frame, text=friend, bg="#45494D", fg="white")
    name.pack(side=TOP, fill=X)
    name.bind("<Button-1>", switch_target)

root.mainloop()

Примеры:

Если я нажму на метку "Luke", вывод будет Sam Результат должен быть таким же, как метка, на которой я щелкну, если я нажму на «Люк», он должен напечатать Luke

Любая помощь будет принята с благодарностью!

1 Ответ

2 голосов
/ 11 февраля 2020

Вам нужно изменить 2 вещи.

Один, вам нужно добавить лямбда-функцию, чтобы привязка была связана с правильным виджетом.

Два вам нужно обновить оператор печати .

Попробуйте это:

def switch_target(widget):
    print(widget['text'])


# *** Set frame for friends view ***
friends_frame = VerticalScrolledFrame(root, bg="#23272A")
friends_frame.pack(side=LEFT, fill=BOTH, expand=TRUE)

for friend in friends:
    friend_frame = Frame(friends_frame.interior)
    friend_frame.pack(fill=X)
    name = Label(friend_frame, text=friend, bg="#45494D", fg="white")
    name.pack(side=TOP, fill=X)
    name.bind("<Button-1>", lambda e, n=name: switch_target(n))

root.mainloop()

Ваша главная проблема в том, что в вашем l oop вы переопределяете то, что name когда-либо есть l oop, пока, наконец, ваш последний l oop. Так что это будет только ваша последняя ценность.

Здесь лямбды приходят помочь. Они позволяют нам сохранять значение таким, какое оно есть на момент каждого l oop, сохраняя значение или ссылку правильными.

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