Уведомления

Группа в Telegram: @pythonsu

#1 Янв. 22, 2017 19:30:05

megabax
Зарегистрирован: 2017-01-22
Сообщения: 5
Репутация: +  0  -
Профиль   Отправить e-mail  

Не вызывается при нажатии на кнопку.

Добрый день. Выполняю такой код:

 from tkinter import * 
class Calculator(Frame):
    def __init__(self, parent):
        Frame.__init__(self, parent)
        self.parent = parent
        print("11111")
        self.setUI() 
    def button_clicked(self, event):
        print("event")
        self.output.delete("0.0","end") 
        self.output.insert("0.0","sdfdsfsd")
    def setUI(self):
        print("UI")
        self.pack(fill=BOTH, expand=1)
        self.output=Text(self, height=1, width=25)
        self.output.grid(row=0, column=0, columnspan = 5)
        #i=0
        #currow=1
        #while i<=9:
        #    if i>=5:
        #        currow=2
        #    btn = Button(self, text=i, width=3)
        #    btn.grid(row=currow, column=i % 5)
        #    btn.bind("Button-",self.button_clicked) 
        #    i=i+1
        btn = Button(self, text="Кнопка", width=10, command=self.button_clicked)
        btn.grid(row=1, column=0)
        #btn.bind("Button-1",self.button_clicked)         
        print("end UI")
def main():
    root = Tk()
    root.geometry("1500x900")
    #root.textvar=root.StringVar()
    app = Calculator(root)
    root.mainloop() 
if __name__ == "__main__":
    print("start")
    main()
    

При нажатии на кнопочку вылазит сообщение об ошибке:
Traceback (most recent call last):
File “D:\Самообразование\Питон\Calk1.py”, line 41, in <module>
main()
File “D:\Самообразование\Питон\Calk1.py”, line 36, in main
app = Calculator(root)
File “D:\Самообразование\Питон\Calk1.py”, line 8, in __init__
self.setUI()
File “D:\Самообразование\Питон\Calk1.py”, line 27, in setUI
btn = Button(self, text=“Кнопка”, width=10, command=self.button_clicked(btn))
UnboundLocalError: local variable ‘btn’ referenced before assignment
Подскажите, пожалуйста, что делаю не так?

Офлайн

#2 Янв. 22, 2017 21:15:24

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

Не вызывается при нажатии на кнопку.

Не обманывайте. Вы не этот код выполняете. Вы пытаетесь повесить на событие в качестве обработчика результат выполнения функции, а не объект функции.

 btn = Button(self, text=“Кнопка”, width=10, command=self.button_clicked(btn))

Для того, чтобы делать такие фокусы нужно использовать lambda

 btn = Button(self, text=“Кнопка”, width=10, command=lambda event: self.button_clicked(btn))

Офлайн

#3 Янв. 23, 2017 19:53:17

megabax
Зарегистрирован: 2017-01-22
Сообщения: 5
Репутация: +  0  -
Профиль   Отправить e-mail  

Не вызывается при нажатии на кнопку.

Сделал вот так:

 btn = Button(self, text="Кнопка", width=10, command=lambda event: self.button_clicked(btn))
И вот такой обработчик:
     def button_clicked(self,event):
        print("event")
        self.output.delete("0.0","end") 
        self.output.insert("0.0","sdfdsfsd")
Теперь он говорит:
Exception in Tkinter callback
Traceback (most recent call last):
File “C:\Users\pc1\AppData\Local\Programs\Python\Python35-32\lib\tkinter\__init__.py”, line 1550, in __call__
return self.func(*args)
TypeError: <lambda>() missing 1 required positional argument: ‘event’
Если я делаю вот так:
 btn = Button(self, text="Кнопка", width=10, command=self.button_clicked)
и так
     def button_clicked(self):
        print("event")
        self.output.delete("0.0","end") 
        self.output.insert("0.0","sdfdsfsd")
То все нормально отрабатывает. Но мне надо каким-то волшебным образом передать в обработчик события параметр или ссылку на то, какая кнопка была нажата.

Офлайн

#4 Янв. 23, 2017 19:55:17

megabax
Зарегистрирован: 2017-01-22
Сообщения: 5
Репутация: +  0  -
Профиль   Отправить e-mail  

Не вызывается при нажатии на кнопку.

А, спасибо, понял сам, ссылку на еще не созданную кнопку видимо нельзя передавать, надо так:

 btn = Button(self, text="Кнопка", width=10, command=lambda: self.button_clicked(1))
и
     def button_clicked(self, event):
        print("event")
        print(event)
        self.output.delete("0.0","end") 
        self.output.insert("0.0","sdfdsfsd")

Офлайн

#5 Янв. 23, 2017 19:59:09

megabax
Зарегистрирован: 2017-01-22
Сообщения: 5
Репутация: +  0  -
Профиль   Отправить e-mail  

Не вызывается при нажатии на кнопку.

Зато не получается так сделать:

     def setUI(self):
        print("UI")
        self.pack(fill=BOTH, expand=1)
        self.output=Text(self, height=1, width=25)
        self.output.grid(row=0, column=0, columnspan = 5)
        i=0
        currow=1
        while i<=9:
            if i>=5:
                currow=2
            btn = Button(self, text=i, width=3, command=lambda: self.button_clicked(i))
            btn.grid(row=currow, column=i % 5)
            #btn.bind("Button-",self.button_clicked) 
            i=i+1
        #btn = Button(self, text="Кнопка", width=10, command=lambda: self.button_clicked(1))
        #btn.grid(row=1, column=0)
        #btn.bind("Button-1",self.button_clicked)         
        print("end UI")
Почему-то передаётся только последнее значение 10, а надо чтобы каждая кнопка сообщала свою цифру.

Офлайн

#6 Янв. 23, 2017 22:07:39

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

Не вызывается при нажатии на кнопку.

Это фокус lambda. Описывайте явно.

 btn = Button(self, text=i, width=3, command=lambda i=i: self.button_clicked(i))

Офлайн

#7 Янв. 23, 2017 22:09:07

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

Не вызывается при нажатии на кнопку.

Ну и вообще не надо это передавать.
Попробуйте в функции обработчике

 #
def button_clicked(self, event):
        print(event.widget["text"])

И будете очень удивлены

Офлайн

#8 Янв. 24, 2017 19:09:06

megabax
Зарегистрирован: 2017-01-22
Сообщения: 5
Репутация: +  0  -
Профиль   Отправить e-mail  

Не вызывается при нажатии на кнопку.

Спасибо большое.
Вот так работает:

 btn = Button(self, text=i, width=3, command=lambda i=i: self.button_clicked(i))
Про последнее, я, правда, не совсем понял: откуда возьмётся event со свойством widget? Если я ничего не передаю, то у меня в функции не может быть два аргумента, на такой обработчик интерпретатор ругается
TypeError: button_clicked() missing 1 required positional argument: ‘event’

Офлайн

#9 Янв. 25, 2017 08:18:36

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

Не вызывается при нажатии на кнопку.

А Вы не передавайте ничего Event валится в функцию при использовании bind по-умолчанию. На command его не будет.

Вот

 Button(self, text=i, width=3).bind("<Button-1>", button_clicked)

Отредактировано 4kpt_IV (Янв. 25, 2017 08:18:53)

Офлайн

Board footer

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

Powered by DjangoBB

Lo-Fi Version