2014-05-24 81 views
4

我正在用Tk在python中創建一個Sudoku遊戲。Python:函數需要1個位置參數,但有2個被給出,怎麼樣?

lb[0][0].bind('<KeyPress-2>',self.kk)

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 

得到了有關在按鍵功能錯誤的按鈕

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() 

與此錯誤/例外,我不介意在那裏是錯誤。我已經包含在我的功能

回答

7

我明白這已被回答,但我有一種我更喜歡的方式,並且您和其他人可能會喜歡。

再說說你的方法KK在多個地點使用,你不希望有一些隨機變量來發送佔用如下所示(工作過基督教的迴應)了「another_parameter」現場,

def kk(self, another_parameter): 

個人而言,我認爲參數列表應該只有他們需要的東西。所以,只要你有沒有必要爲「another_parameter」變量綁定()函數發送,我建議使用lambda通過執行以下操作:

lb[0][0].bind('<KeyPress-2>',lambda e:self.kk()) 

我認爲你需要兩個括號KK之後,因爲現在lambda實際上是要用它的參數運行該函數(在你的情況下,如果你刪除了我說的那個,那就沒有)。什麼lambda爲我們做的是捕獲從綁定函數拋出kk的參數(這就是lambda後的'e',它代表了參數)。現在,我們不需要它在我們的參數列表中,我們可以繼續我們的KK的定義是

def kk(self): 

我開始使用由基督教的辦法(工作!),但我不喜歡額外的變量。很顯然,這兩種方法都可以工作,但我認爲這有助於,特別是如果在綁定中調用的函數多次使用而不一定由綁定調用使用。

+0

優秀的答案,謝謝 – Pontios

5

自我我不是一個tkinter專家,但似乎(由什麼我至今讀),該方法

bind(some_string, some_function) 

電話function傳遞參數string到它。

聲明該方法kk

def kk(self): 

,這意味着它只能期待一個參數。您還傳遞方法self.kkbind(),這意味着它會被稱爲像

self.kk('<KeyPress-2>') 

有問題!實際上,這個調用將兩個參數傳遞給方法kk。這相當於

sudoku.kk(janela, '<KeyPress-2>') 

注意janela是類sudoku的實際情況。回到這個問題,你通過兩個參數 !!!

你如何解決它?

正如我說我不是這方面的專家,但我的猜測是有兩個參數來聲明方法kk

def kk(self, another_parameter): 
    # ... 

注:我建議你遵循Python naming conventions。換句話說,類名應該像SomeClassNameSudoku

+1

感謝你非常非常非常多= D 與此'another_parameter'(或'event' like another answers)現在我可以使用event.keysym並獲取按鍵的值= D – 648trindade

+0

綁定確實_not_調用'self.kk' like'self.kk('')'。這是誤導。它用代表事件的對象調用'self,kk'。它不僅僅是事件的字符串表示。 –

3

您需要定義kk功能如下:

def kk(self, event): 
    lb[0][0]['text']='2' 

因爲你結合kk到按鍵事件,它是自動傳遞事件對象(其中有關於該事件的一些有用的信息) ,所以kk需要另外一個參數,event,而不是self

3

變化kk定義

def kk(self, event): 
    ... 

那麼當你通過self.kk回調,tk會這樣稱呼它func(event)self.kk(event)),一切都會好起來的。

現在當tk調用func(event),就像self.kk(event)一樣,參數的數量是錯誤的。

相關問題