Re: Class and tkinter problem
Às 20:35 de 07/01/21, Terry Reedy escreveu: > On 1/7/2021 4:20 AM, Terry Reedy wrote: >> On 1/7/2021 2:42 AM, Christian Gollwitzer wrote: >>> Am 07.01.21 um 08:29 schrieb Paulo da Silva: >>> Does anybody know why cmd method isn't called when I change the button state (clicking on it) in this example? I know that this seems a weird class use. But why doesn't it work? Thanks. class C: from tkinter import Checkbutton import tkinter @staticmethod >>> ^^it works if you remove the staticmethod here >> >> staticmethods are essentially useless in Python. What little was >> gained by their addition is partly offset by the introduced confusion. > def cmd(): print("Test") > > The confusion is that methods are callable, whereas 'staticmethods' are > not. I was not completely aware of this until pointed out by Peter > Otten with example > > " cmd() > > Traceback (most recent call last): > File "", line 1, in > class C: > File "", line 4, in C > cmd() > TypeError: 'staticmethod' object is not callable > > You have to go through the descriptor protocol:" > > Indeed, dir(cmd) shows that it does not have a .__call__ attribute. > >> top=tkinter.Tk() >> cb=Checkbutton(command=cmd) > >> Button commands have to be tcl functions. Tkinter wraps Python >> functions as tcl function. Static methods also wrap python functions, >> as a .__func__ attribute. So the code if one passes cmd.__func__. > > "So the code works if one passes the callable cmd.__func__." > >>> Maybe there is a bug in tkinter, that it doesn't work with static >>> methods? >> >> One could propose that tkinter test whether callables are staticmethods > > Command options, as documented, must be callables. Neither staticmethods > nor classmethods are callable. > >> and unwrap them when they are. > > I would propose instead that if possible tkinter raise TypeError when > passed a non-callable as a command. > Yes, that would be much better. Thanks. -- https://mail.python.org/mailman/listinfo/python-list
Re: Class and tkinter problem
On 1/7/2021 4:20 AM, Terry Reedy wrote: On 1/7/2021 2:42 AM, Christian Gollwitzer wrote: Am 07.01.21 um 08:29 schrieb Paulo da Silva: Does anybody know why cmd method isn't called when I change the button state (clicking on it) in this example? I know that this seems a weird class use. But why doesn't it work? Thanks. class C: from tkinter import Checkbutton import tkinter @staticmethod ^^it works if you remove the staticmethod here staticmethods are essentially useless in Python. What little was gained by their addition is partly offset by the introduced confusion. def cmd(): print("Test") The confusion is that methods are callable, whereas 'staticmethods' are not. I was not completely aware of this until pointed out by Peter Otten with example "cmd() Traceback (most recent call last): File "", line 1, in class C: File "", line 4, in C cmd() TypeError: 'staticmethod' object is not callable You have to go through the descriptor protocol:" Indeed, dir(cmd) shows that it does not have a .__call__ attribute. top=tkinter.Tk() cb=Checkbutton(command=cmd) Button commands have to be tcl functions. Tkinter wraps Python functions as tcl function. Static methods also wrap python functions, as a .__func__ attribute. So the code if one passes cmd.__func__. "So the code works if one passes the callable cmd.__func__." Maybe there is a bug in tkinter, that it doesn't work with static methods? One could propose that tkinter test whether callables are staticmethods Command options, as documented, must be callables. Neither staticmethods nor classmethods are callable. and unwrap them when they are. I would propose instead that if possible tkinter raise TypeError when passed a non-callable as a command. Classmethods also do not work as is. By experiment, the following works. cb=Checkbutton(command=lambda: C.cmd.__func__(C)) But if the class were nested, it would be more complicated. -- Terry Jan Reedy -- https://mail.python.org/mailman/listinfo/python-list
Re: Class and tkinter problem
Às 07:29 de 07/01/21, Paulo da Silva escreveu: > Hi! > > Does anybody know why cmd method isn't called when I change the button > state (clicking on it) in this example? > I know that this seems a weird class use. But why doesn't it work? > Thanks. > > class C: > from tkinter import Checkbutton > import tkinter > > @staticmethod > def cmd(): > print("Test") > > top=tkinter.Tk() > cb=Checkbutton(command=cmd) > cb.pack() > > @staticmethod > def loop(): > C.top.mainloop() > > c=C() > c.loop() > After some experiments I found two solutions: 1) class C: @staticmethod def cmd(): print("Test") class C: #@DuplicatedSignature from tkinter import Checkbutton import tkinter top=tkinter.Tk() cb=Checkbutton(command=C.cmd) cb.pack() @staticmethod def loop(): C.top.mainloop() c=C() c.loop() 2) class C: from tkinter import Checkbutton import tkinter @staticmethod def cmd(): print("Test") top=tkinter.Tk() cb=Checkbutton(command=lambda : C.cmd()) cb.pack() @staticmethod def loop(): C.top.mainloop() c=C() c.loop() This one as a sequence of the answer of Terry - thanks. BTW, does anyone know I can I get the arguments eventually passed by the Checkbutton event, or any other widget callback (*pargs, **kargs) using this "solution"? -- https://mail.python.org/mailman/listinfo/python-list
Re: Class and tkinter problem
Às 16:02 de 07/01/21, Peter Otten escreveu: > On 07/01/2021 08:42, Christian Gollwitzer wrote: >> Am 07.01.21 um 08:29 schrieb Paulo da Silva: >> ... > > I recommend that the OP use a more conventional stye and do the setup > outside the class or, better, in an instance of the class. > There are lots of possible more conventional ways, of course. My purpose was only to understand what was wrong. Thanks anyway. -- https://mail.python.org/mailman/listinfo/python-list
Re: Class and tkinter problem
Às 09:20 de 07/01/21, Terry Reedy escreveu: > On 1/7/2021 2:42 AM, Christian Gollwitzer wrote: >> Am 07.01.21 um 08:29 schrieb Paulo da Silva: >> >>> Does anybody know why cmd method isn't called when I change the button >>> state (clicking on it) in this example? >>> I know that this seems a weird class use. But why doesn't it work? >>> Thanks. >>> >>> class C: >>> from tkinter import Checkbutton >>> import tkinter >>> >>> @staticmethod >> ^^it works if you remove the staticmethod here > > staticmethods are essentially useless in Python. What little was gained > by their addition is partly offset by the introduced confusion. It depends on what the classes are being used for. Sometimes I just want to use them as static wrappers. Of course I could use them in the conventional way for this purpose, but it's not so clean :-) ... > > Classmethods also do not work as is. By experiment, the following works. > cb=Checkbutton(command=lambda: C.cmd.__func__(C)) Why not just cb=Checkbutton(command=lambda : C.cmd()) ? Also works. BTW, just for curiosity, and for my personal learning ... What does "__func__" does? Thank you. -- https://mail.python.org/mailman/listinfo/python-list
Re: Class and tkinter problem
Às 07:42 de 07/01/21, Christian Gollwitzer escreveu: > Am 07.01.21 um 08:29 schrieb Paulo da Silva: > >> Does anybody know why cmd method isn't called when I change the button >> state (clicking on it) in this example? >> I know that this seems a weird class use. But why doesn't it work? >> Thanks. >> >> class C: >> from tkinter import Checkbutton >> import tkinter >> >> @staticmethod > ^^it works if you remove the staticmethod here Yes, that's the coventional way. Thanks -- https://mail.python.org/mailman/listinfo/python-list
Re: Class and tkinter problem
On 07/01/2021 08:42, Christian Gollwitzer wrote: Am 07.01.21 um 08:29 schrieb Paulo da Silva: Does anybody know why cmd method isn't called when I change the button state (clicking on it) in this example? I know that this seems a weird class use. But why doesn't it work? Thanks. class C: from tkinter import Checkbutton import tkinter @staticmethod ^^it works if you remove the staticmethod here def cmd(): print("Test") Maybe there is a bug in tkinter, that it doesn't work with static methods? It has nothing to do with tkinter, a staticmethod object cannot be called directly: >>> class C: @staticmethod def cmd(): print("Hello") cmd() Traceback (most recent call last): File "", line 1, in class C: File "", line 4, in C cmd() TypeError: 'staticmethod' object is not callable You have to go through the descriptor protocol: >>> class C: @staticmethod def cmd(): print("Hello") >>> C.cmd() Hello I recommend that the OP use a more conventional stye and do the setup outside the class or, better, in an instance of the class. -- https://mail.python.org/mailman/listinfo/python-list
Re: Class and tkinter problem
On 1/7/2021 2:42 AM, Christian Gollwitzer wrote: Am 07.01.21 um 08:29 schrieb Paulo da Silva: Does anybody know why cmd method isn't called when I change the button state (clicking on it) in this example? I know that this seems a weird class use. But why doesn't it work? Thanks. class C: from tkinter import Checkbutton import tkinter @staticmethod ^^it works if you remove the staticmethod here staticmethods are essentially useless in Python. What little was gained by their addition is partly offset by the introduced confusion. I am not sure is removing @staticmethod would have been sufficient in 2.x. def cmd(): print("Test") top=tkinter.Tk() cb=Checkbutton(command=cmd) cb.pack() Button commands have to be tcl functions. Tkinter wraps Python functions as tcl function. Static methods also wrap python functions, as a .__func__ attribute. So the code if one passes cmd.__func__. Maybe there is a bug in tkinter, that it doesn't work with static methods? One could propose that tkinter test whether callables are staticmethods and unwrap them when they are. Classmethods also do not work as is. By experiment, the following works. cb=Checkbutton(command=lambda: C.cmd.__func__(C)) But if the class were nested, it would be more complicated. -- Terry Jan Reedy -- https://mail.python.org/mailman/listinfo/python-list
Re: Class and tkinter problem
Am 07.01.21 um 08:29 schrieb Paulo da Silva: Does anybody know why cmd method isn't called when I change the button state (clicking on it) in this example? I know that this seems a weird class use. But why doesn't it work? Thanks. class C: from tkinter import Checkbutton import tkinter @staticmethod ^^it works if you remove the staticmethod here def cmd(): print("Test") Maybe there is a bug in tkinter, that it doesn't work with static methods? Christian -- https://mail.python.org/mailman/listinfo/python-list
Class and tkinter problem
Hi! Does anybody know why cmd method isn't called when I change the button state (clicking on it) in this example? I know that this seems a weird class use. But why doesn't it work? Thanks. class C: from tkinter import Checkbutton import tkinter @staticmethod def cmd(): print("Test") top=tkinter.Tk() cb=Checkbutton(command=cmd) cb.pack() @staticmethod def loop(): C.top.mainloop() c=C() c.loop() -- https://mail.python.org/mailman/listinfo/python-list