Уведомления

Группа в Telegram: @pythonsu

#1 Март 10, 2016 23:35:19

4kpt_IV
Зарегистрирован: 2016-01-08
Сообщения: 999
Репутация: +  49  -
Профиль   Отправить e-mail  

Функция для Frame

Вы запускали Ваш код?

Офлайн

#2 Март 11, 2016 07:26:09

drevoborod
Зарегистрирован: 2016-03-09
Сообщения: 15
Репутация: +  0  -
Профиль   Отправить e-mail  

Функция для Frame

4kpt_IV
Вы запускали Ваш код?
Да, конечно. А что не так? При клике по любой кнопке или тексту как во внутренней, так и внешней рамках (а я для проверки ещё пару уровней вложенности добавлял) срабатывает забинденная функция myfunc. Но она не срабатывает в двух случаях: при клике в пустое пространство MyFrame, а также при клике на встроенных в Text чекбаттонах. Чтобы исправить первый случай, добавляем в переопределённый bind строчку
tkinter.Widget.bind(self, sequence, func, add)
Почему-то использовать super() внутри bind у меня не получилось, то есть код
super().bind(sequence, func, add)
вызывает ошибку “TypeError: super(type, obj): obj must be an instance or subtype of type”. Не разобрался пока. Но так, как ниже, работает.

Кстати, у вас в примере про super() ошибка - там не должно быть self, так как "The search order is same as that used by getattr() except that the type itself is skipped.". В итоге весь код будет выглядеть так (для примера добавим рамке границу, чтобы был какой-то смысл переопределять __init__ суперкласса):

import tkinter
class MyFrame(tkinter.Frame):
    def __init__(self, parent=None, **options):
        super().__init__(master=parent, relief='groove', bd=2, **options)
    def bind(self, sequence=None, func=None, add=None):
        tkinter.Widget.bind(self, sequence, func, add)
        for child in self.winfo_children():
            MyFrame.bind(child, sequence, func, add)
def myfunc(event):
    print("clicked", event.widget._name)
if __name__ == "__main__":
    root = tkinter.Tk()
    external_frame = MyFrame(root)
    tkinter.Button(external_frame, text='External Button 1').pack()
    tkinter.Button(external_frame, text='External Button 2').pack()
    internal_frame = tkinter.Frame(external_frame, relief='groove', bd=2)
    internal_frame.pack()
    tkinter.Button(internal_frame, text='Internal button Large').pack()
    tkinter.Button(internal_frame, text='IntButt').pack()
    text1 = tkinter.Text(external_frame)
    checkbox1 = tkinter.Checkbutton(text="Check me")
    checkbox2 = tkinter.Checkbutton(text="Check me too")
    text1.window_create("end", window=checkbox1)
    text1.insert('end', '  some text  ')
    text1.window_create('end', window=checkbox2)
    text1.pack()
    external_frame.bind("<Button-1>", myfunc)
    external_frame.pack()
    root.mainloop()

Отредактировано drevoborod (Март 11, 2016 07:56:34)

Офлайн

#3 Март 11, 2016 09:50:54

4kpt_IV
Зарегистрирован: 2016-01-08
Сообщения: 999
Репутация: +  49  -
Профиль   Отправить e-mail  

Функция для Frame

drevoborod
Кстати, у вас в примере про super() ошибка - там не должно быть self, так как “The search order is same as that used by getattr() except that the type itself is skipped.”. В итоге весь код будет выглядеть так (для примера добавим рамке границу, чтобы был какой-то смысл переопределять __init__ суперкласса):

Добо, кеп

Теперь повторюсь.
1. Инит не нужен.
2. Ваш пример неверный.

Офлайн

#4 Март 11, 2016 10:53:52

drevoborod
Зарегистрирован: 2016-03-09
Сообщения: 15
Репутация: +  0  -
Профиль   Отправить e-mail  

Функция для Frame

4kpt_IV
2. Ваш пример неверный.
В таком случае, предлагаю продемонстрировать верный.
Init в данном случае нужен, так как я решил моему Frame добавлять рамочку по умолчанию. Если этого не делать, то не нужен, конечно.

Отредактировано drevoborod (Март 11, 2016 10:55:10)

Офлайн

#5 Март 11, 2016 20:44:02

4kpt_IV
Зарегистрирован: 2016-01-08
Сообщения: 999
Репутация: +  49  -
Профиль   Отправить e-mail  

Функция для Frame

drevoborod
Init в данном случае нужен, так как я решил моему Frame добавлять рамочку по умолчанию. Если этого не делать, то не нужен, конечно.

Этого делать не нужно. Вы пишете новый виджет. Все настройки должны быть извне. Виджет должен быть как-бы голым…

Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version