鱼C论坛

 找回密码
 立即注册
查看: 1774|回复: 5

[已解决]函数调用

[复制链接]
发表于 2023-5-28 17:29:12 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
请大神帮忙解决,万分感谢!!
代码:
from tkinter import *
from tkinter import ttk

def go(n=None):
    if n==None:
        n=int(com.get())
        print(n^2)
    else:
        print(n*2)

root=Tk()
com=ttk.Combobox(root,width=10)
com.pack()
com['values']=[x for x in range(1,11)]
com.current(0)
com.bind('<<ComboboxSelected>>',go)
bnt=Button(root,text='Run',command=lambda x=10: go(x))
bnt.pack()
root.mainloop()

我的问题是,当使用列表控件触发函数时,会报错,报错信息:
TypeError: unsupported operand type(s) for *: 'Event' and 'int'
用按钮控件调用时输出正常:20

我的问题是:如果分别写两个函数,一个用于com控件的“选中”触发,而另一个函数用于按钮控件调用是没问题的,那么,如果只用这一个函数来实现两类控件的调用该如何实现?
最佳答案
2023-5-28 17:36:00
当你绑定一个事件到 tkinter 控件时,回调函数会自动接收一个参数,这是一个  Event  对象,你不能将其用于数学运算。

在你的情况中,当你从 ComboBox 中选择一个选项时, go  函数将会被调用,并且它会接收一个  Event  对象作为参数,然后你试图将这个  Event  对象与  2  进行乘法运算,这就导致了你所看到的错误。

为了解决这个问题,你可以检查参数的类型,如果是  Event  对象,则从 ComboBox 获取当前值;如果是  int  类型,则直接使用它进行运算。下面是修改后的  go  函数:
from tkinter import *
from tkinter import ttk

def go(n=None):
    if isinstance(n, Event):
        n = int(com.get())
        print(n**2)
    elif isinstance(n, int):
        print(n*2)

root=Tk()
com=ttk.Combobox(root,width=10)
com.pack()
com['values']=[x for x in range(1,11)]
com.current(0)
com.bind('<<ComboboxSelected>>',go)
bnt=Button(root,text='Run',command=lambda x=10: go(x))
bnt.pack()
root.mainloop()

这样就能成功地使用同一个函数来处理 ComboBox 的选中事件以及按钮的点击事件了。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2023-5-28 17:34:40 | 显示全部楼层
这个错误是由于在绑定 <<ComboboxSelected>> 事件时,传递了一个 event 参数,而在 go 函数中未处理该参数,导致出现类型不匹配的错误。

要解决这个问题,可以在 go 函数定义时为 n 参数添加默认值 None,然后进行判断。如果 n 值为 None,说明是通过选中 com 控件触发的函数,此时可以从 com 控件获取选中的值,进行平方操作;否则说明是通过点击按钮触发的函数,此时直接对 n 进行双倍操作即可。

修改后的代码如下所示:
from tkinter import *
from tkinter import ttk

def go(n=None, event=None):
    if n is None:
        n = int(com.get())
        print(n ** 2)
    else:
        print(n * 2)

root=Tk()
com=ttk.Combobox(root,width=10)
com.pack()
com['values']=[x for x in range(1,11)]
com.current(0)
com.bind('<<ComboboxSelected>>',go)
bnt=Button(root,text='Run',command=lambda x=10: go(x))
bnt.pack()
root.mainloop()
这样修改后,无论是从 com 控件触发还是从按钮控件触发,都会调用同一个 go 函数,并且输出结果都是正确的。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-5-28 17:36:00 | 显示全部楼层    本楼为最佳答案   
当你绑定一个事件到 tkinter 控件时,回调函数会自动接收一个参数,这是一个  Event  对象,你不能将其用于数学运算。

在你的情况中,当你从 ComboBox 中选择一个选项时, go  函数将会被调用,并且它会接收一个  Event  对象作为参数,然后你试图将这个  Event  对象与  2  进行乘法运算,这就导致了你所看到的错误。

为了解决这个问题,你可以检查参数的类型,如果是  Event  对象,则从 ComboBox 获取当前值;如果是  int  类型,则直接使用它进行运算。下面是修改后的  go  函数:
from tkinter import *
from tkinter import ttk

def go(n=None):
    if isinstance(n, Event):
        n = int(com.get())
        print(n**2)
    elif isinstance(n, int):
        print(n*2)

root=Tk()
com=ttk.Combobox(root,width=10)
com.pack()
com['values']=[x for x in range(1,11)]
com.current(0)
com.bind('<<ComboboxSelected>>',go)
bnt=Button(root,text='Run',command=lambda x=10: go(x))
bnt.pack()
root.mainloop()

这样就能成功地使用同一个函数来处理 ComboBox 的选中事件以及按钮的点击事件了。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2023-5-28 17:46:49 | 显示全部楼层
陶远航 发表于 2023-5-28 17:34
这个错误是由于在绑定  事件时,传递了一个 event 参数,而在 go 函数中未处理该参数,导致出现类型不匹配 ...

按照您的代码运行后,还是报同样的错,isdkz的代码可以无误运行,谢谢您的耐心解答!
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2023-5-28 17:48:15 | 显示全部楼层
isdkz 发表于 2023-5-28 17:36
当你绑定一个事件到 tkinter 控件时,回调函数会自动接收一个参数,这是一个  Event  对象,你不能将其用于 ...

谢谢大佬回复,已完美解决!!
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-5-28 17:48:53 | 显示全部楼层
las6040 发表于 2023-5-28 17:48
谢谢大佬回复,已完美解决!!

不客气
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-9-23 01:33

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表