I was creating a Sudoku Game in python with Tk.
我用Tk在python中创建了一个Sudoku游戏。
I got a error about the function on a keypress for a button
我在按键的按键上有一个错误。
from random import randint
from tkinter import *
class sudoku:
global root,result,lb
def __init__(self):
self.aleatoriedade()
for k in range(9):
j=randint(0,80)
x=j//9
y=j-(x*9)
lb[x][y]['text']=result[x][y]
lb[0][0].bind('<KeyPress-2>',self.kk)
#setted this for test
root.mainloop()
def kk(self):
lb[0][0]['text']='2'
def aleatoriedade(self):
for i in range(9):
var=0
while var in result[0]:
var=randint(1,9)
result[0][i]=var
for i in range(1,9):
for j in range(9):
result[i][j]=result[0][field[i][j]-1]
#MAIN()
n = 3
field = [[(i*n + i//n + j) % (n*n) + 1 for j in range(9)]for i in range(9)]
result = [[None for i in range(9)]for i in range(9)]
lb=[[None for i in range(9)]for i in range(9)]
x=0
y=0
root=Tk()
for i in range(9):
for j in range(9):
lb[i][j]=Button(root,font=("Verdana",'13',"bold"),bd=1,height=3,width=6)
if (i in (0,1,2,6,7,8) and j in (0,1,2,6,7,8))or(i in (3,4,5) and j in (3,4,5)):
lb[i][j]['bg']='white'
lb[i][j].grid(row=i,column=j)
janela=sudoku()
and this error/exception in lb[0][0].bind('<KeyPress-2>',self.kk)
这个错误/异常在lb[0][0] .bind('
Exception in Tkinter callback
Traceback (most recent call last):
File "C:\Python33\lib\tkinter\__init__.py", line 1489, in __call__
return self.func(*args)
TypeError: kk() takes 1 positional argument but 2 were given
I don't mind where is the error. I have included the self on my function
我不介意错误在哪里。我在函数中包含了self。
4 个解决方案
#1
8
I see that this has been answered, but I have a way I really prefer and that you and others may appreciate.
我知道这已经得到了回答,但我有一种我真正喜欢的方式,你和其他人可能会欣赏。
Say that your method kk is used in multiple spots, and you don't want to have to send in some random variable to take up the spot of "another_parameter" shown below (working off of Christian's response),
假设您的方法kk在多个点上使用,并且您不希望必须发送某个随机变量来占用下面显示的“another_parameter”点(根据Christian的响应进行工作),
def kk(self, another_parameter):
Personally, I think parameter lists should have ONLY what they need. So, as long as you have no need for the "another_parameter" variable that the bind() function sends, I suggest using Lambda by doing the following:
就个人而言,我认为参数列表应该只有他们需要的。因此,只要您不需要绑定()函数发送的“another_parameter”变量,我建议使用Lambda来执行以下操作:
lb[0][0].bind('<KeyPress-2>',lambda e:self.kk())
I think you need the two parentheses after kk now because lambda is actually going to run that function with it's parameters (in your case, if you remove the one I said to, there would be none). What lambda is doing for us is catching the parameter being thrown to kk from the bind function (that is what the 'e' is after lambda, it represents the argument). Now, we don't need it in our parameter list, and we can resume our kk definition to be
我认为你需要在kk之后的两个圆括号,因为lambda实际上是用它的参数来运行那个函数(在你的例子中,如果你删除了我说的那个,那就没有了)。为我们做的是捕获从绑定函数抛出kk的参数(这是“e”在lambda之后的值,它表示参数)。现在,我们不需要它在我们的参数列表中,我们可以恢复kk定义。
def kk(self):
I started using the approach by Christian (which works!) but I didn't like the extra variable. Obviously both methods work, but I think this one helps, especially if the function being called in bind is used more than once and not necessarily used by a bind call.
我开始使用基督教的方法(有效!),但我不喜欢额外的变量。显然,这两种方法都有效,但我认为这一点很有帮助,特别是如果在bind中调用的函数不止一次使用,并且不需要绑定调用使用。
#2
5
I'm not a tkinter
expert, but it seems (by what I've read so far) that the method
我不是一个tkinter专家,但是看起来(根据我迄今为止所读到的)方法。
bind(some_string, some_function)
calls function
passing the parameter string
to it.
调用函数将参数字符串传递给它。
You have declared the method kk
like
您已经声明了kk的方法。
def kk(self):
and it means that it is only expecting one argument. You are also passing the method self.kk
to bind()
, which means that it will be called like
这意味着它只期望一个参数。您也在传递方法self。kk绑定(),这意味着它将被调用。
self.kk('<KeyPress-2>')
There is the problem! That call, in fact, is passing two arguments to the method kk
. It's equivalent to
有一个问题!实际上,这个调用将两个参数传递给方法kk。它等于
sudoku.kk(janela, '<KeyPress-2>')
Note that janela
is the actual instance of the class sudoku
. Coming back to the problem, you are passing two arguments!!!
注意,janela是类数独的实例。回到这个问题,你正在传递两个论点!!!
How can you solve it?
怎么解决呢?
As I said I'm not an expert on this topic, but my guess is to declare the method kk
with two parameters:
正如我所说的,我不是这方面的专家,但我的猜测是用两个参数来声明方法kk:
def kk(self, another_parameter):
# ...
Note: I would recommend you to follow Python naming conventions. In other words, class names should be like SomeClassName
or Sudoku
.
注意:我建议您遵循Python命名约定。换句话说,类名应该类似于SomeClassName或Sudoku。
#3
4
You need to define kk
function as this:
你需要定义kk函数为:
def kk(self, event):
lb[0][0]['text']='2'
Because you're binding kk
to a key press event, and it is automatically passed the event object (which has some useful information about the event), so kk
need to have another argument, event
, other than self
.
因为您将kk绑定到一个关键的新闻事件,并且它会自动通过事件对象(它有一些关于事件的有用信息),所以kk需要有另一个参数,event,而不是self。
#4
4
Change kk
definition to
改变kk定义
def kk(self, event):
...
then when you pass self.kk
as callback, tk
will call it like func(event)
(self.kk(event)
) and everything will be fine.
然后当你超越自我。kk作为回调,tk会将其称为func(event) (self。kk(event)),一切都会很好。
Now when tk
calls func(event)
, which is like self.kk(event)
, the number of arguments is wrong.
现在,当tk调用func(event)时,就像self。kk(事件)一样,参数的数量是错误的。
#1
8
I see that this has been answered, but I have a way I really prefer and that you and others may appreciate.
我知道这已经得到了回答,但我有一种我真正喜欢的方式,你和其他人可能会欣赏。
Say that your method kk is used in multiple spots, and you don't want to have to send in some random variable to take up the spot of "another_parameter" shown below (working off of Christian's response),
假设您的方法kk在多个点上使用,并且您不希望必须发送某个随机变量来占用下面显示的“another_parameter”点(根据Christian的响应进行工作),
def kk(self, another_parameter):
Personally, I think parameter lists should have ONLY what they need. So, as long as you have no need for the "another_parameter" variable that the bind() function sends, I suggest using Lambda by doing the following:
就个人而言,我认为参数列表应该只有他们需要的。因此,只要您不需要绑定()函数发送的“another_parameter”变量,我建议使用Lambda来执行以下操作:
lb[0][0].bind('<KeyPress-2>',lambda e:self.kk())
I think you need the two parentheses after kk now because lambda is actually going to run that function with it's parameters (in your case, if you remove the one I said to, there would be none). What lambda is doing for us is catching the parameter being thrown to kk from the bind function (that is what the 'e' is after lambda, it represents the argument). Now, we don't need it in our parameter list, and we can resume our kk definition to be
我认为你需要在kk之后的两个圆括号,因为lambda实际上是用它的参数来运行那个函数(在你的例子中,如果你删除了我说的那个,那就没有了)。为我们做的是捕获从绑定函数抛出kk的参数(这是“e”在lambda之后的值,它表示参数)。现在,我们不需要它在我们的参数列表中,我们可以恢复kk定义。
def kk(self):
I started using the approach by Christian (which works!) but I didn't like the extra variable. Obviously both methods work, but I think this one helps, especially if the function being called in bind is used more than once and not necessarily used by a bind call.
我开始使用基督教的方法(有效!),但我不喜欢额外的变量。显然,这两种方法都有效,但我认为这一点很有帮助,特别是如果在bind中调用的函数不止一次使用,并且不需要绑定调用使用。
#2
5
I'm not a tkinter
expert, but it seems (by what I've read so far) that the method
我不是一个tkinter专家,但是看起来(根据我迄今为止所读到的)方法。
bind(some_string, some_function)
calls function
passing the parameter string
to it.
调用函数将参数字符串传递给它。
You have declared the method kk
like
您已经声明了kk的方法。
def kk(self):
and it means that it is only expecting one argument. You are also passing the method self.kk
to bind()
, which means that it will be called like
这意味着它只期望一个参数。您也在传递方法self。kk绑定(),这意味着它将被调用。
self.kk('<KeyPress-2>')
There is the problem! That call, in fact, is passing two arguments to the method kk
. It's equivalent to
有一个问题!实际上,这个调用将两个参数传递给方法kk。它等于
sudoku.kk(janela, '<KeyPress-2>')
Note that janela
is the actual instance of the class sudoku
. Coming back to the problem, you are passing two arguments!!!
注意,janela是类数独的实例。回到这个问题,你正在传递两个论点!!!
How can you solve it?
怎么解决呢?
As I said I'm not an expert on this topic, but my guess is to declare the method kk
with two parameters:
正如我所说的,我不是这方面的专家,但我的猜测是用两个参数来声明方法kk:
def kk(self, another_parameter):
# ...
Note: I would recommend you to follow Python naming conventions. In other words, class names should be like SomeClassName
or Sudoku
.
注意:我建议您遵循Python命名约定。换句话说,类名应该类似于SomeClassName或Sudoku。
#3
4
You need to define kk
function as this:
你需要定义kk函数为:
def kk(self, event):
lb[0][0]['text']='2'
Because you're binding kk
to a key press event, and it is automatically passed the event object (which has some useful information about the event), so kk
need to have another argument, event
, other than self
.
因为您将kk绑定到一个关键的新闻事件,并且它会自动通过事件对象(它有一些关于事件的有用信息),所以kk需要有另一个参数,event,而不是self。
#4
4
Change kk
definition to
改变kk定义
def kk(self, event):
...
then when you pass self.kk
as callback, tk
will call it like func(event)
(self.kk(event)
) and everything will be fine.
然后当你超越自我。kk作为回调,tk会将其称为func(event) (self。kk(event)),一切都会很好。
Now when tk
calls func(event)
, which is like self.kk(event)
, the number of arguments is wrong.
现在,当tk调用func(event)时,就像self。kk(事件)一样,参数的数量是错误的。