0

I have a problem using the bind option so I can click a button in my keyboard, and call a function once the key is pressed. I tried taking other codes that have the similar purpose and I saw that I'm doing pretty much the same, though I still have some problem I must've missed. I will be very thankful if you help me with this. Here's my code:

# -*- coding: utf-8 -*-

#Imports
from Tkinter import *        
from PIL import ImageTk, Image
import time
import tkMessageBox

#===========================================================================================================================================#
#Tkinter Class
class App(Frame):
    def __init__(self, master=None):
        Frame.__init__(self, master)
        self.pack()

#===========================================================================================================================================#
#Game Pieces Classes
class Board:
    def __init__(self, rows = 7, columns = 6, picture_height = None, picture_width = None):
        self.rows = rows
        self.columns = columns
        self.picture = ImageTk.PhotoImage(Image.open(r"C:\Users\Ariel\Desktop\Python\4inarow.gif"))
        self.picture_height = self.picture.height()
        self.picture_width = self.picture.width()

    def create_and_pack(self, canvas):
        board_item = canvas.create_image(700, 370, image = self.picture)

    def __str__(self):
        print "Rows:", self.rows, "Columns:", self.columns

class Disk:
    def __init__(self, player_number = None):
        self.picture = ImageTk.PhotoImage(Image.open(r"C:\Users\Ariel\Desktop\Python\me" + str(player_number) + ".gif"))
        self.player_number = player_number

    def create_and_pack(self, canvas, x, y):
        disk_item = canvas.create_image(x, y, image = self.picture)

    def get_x_parameter(self, number):
        #X growing by 70~73 per number
        x = 330
        for i in range(7):
            if number == i:
                x = x + i * 72
        return x

    def get_y_parameter(self, number):
        #Y lowered by 70~73 per number
        y = 635
        for i in range(6):
            if number == i:
                y = y - i * 72
        return y

    def place(self, canvas, x, y):
        #First left down circle parameters
        #480, 635
        canvas.move(self.picture, x, y)

    def __str__(self):
        print "The disk's picture string:", self.picture, "The player disk's number:", self.player_number

#===========================================================================================================================================#
#Game Class 
class Game:
    def __init__(self, board = None, disk1 = None, disk2 = None):
        self.disk1 = disk1
        self.disk2 = disk2
        self.board = board

#===========================================================================================================================================#
#KeyboardClass
class Keyboard:
    def __init__(self, key_number = None):
        self.key_number = key_number

    def press_and_place(self, canvas, number, function):
    canvas.focus_set()
    canvas.bind("<" + str(number) + ">", function)

#===========================================================================================================================================#
#Main.
myapp = App()
myapp.master.title("4 in a Row")
myapp.master.maxsize(2000, 1200)
#---------------------------------------------------------------------------------------------------#
GameBoard = Board(7, 6)
FirstPlayerDisk = Disk(1)
SecondPlayerDisk = Disk(2)
GameClass = Game(GameBoard, FirstPlayerDisk, SecondPlayerDisk)
#---------------------------------------------------------------------------------------------------#
#Creating Canvas and placing the disks and the board.
board_canvas = Canvas(width = GameBoard.picture_width, height = GameBoard.picture_height)
board_canvas.pack(expand=1, fill=BOTH)

GameBoard.create_and_pack(board_canvas)
FirstPlayerDisk.create_and_pack(board_canvas, 330, 635)
SecondPlayerDisk.create_and_pack(board_canvas, 260, 635)
#---------------------------------------------------------------------------------------------------#
#Creating Keyboard instance and placing the first disk in the last row in a column of choice
number_choice = 3
KeyboardClass = Keyboard(number_choice)

first_player_x = FirstPlayerDisk.get_x_parameter(number_choice)
first_player_y = FirstPlayerDisk.get_y_parameter(number_choice)
KeyboardClass.press_and_place(board_canvas, number_choice, FirstPlayerDisk.place(board_canvas, first_player_x, first_player_y))
#---------------------------------------------------------------------------------------------------#

myapp.mainloop()

Thanks a lot in advance.

0

1 Answer 1

2

I believe your problem lies in this line:

KeyboardClass.press_and_place(board_canvas, number_choice, FirstPlayerDisk.place(board_canvas, first_player_x, first_player_y))

the third argument FirstPlayerDisk.place(board_canvas, first_player_x, first_player_y) is actually a None type as

def place(self, canvas, x, y):
    #First left down circle parameters
    #480, 635
    canvas.move(self.picture, x, y)

returns None

From How to bind a keypress to a button in Tkinter and this site, you need to pass the function, that is, simply FirstPlayerDisk.place (no parenthesis following it).

Sign up to request clarification or add additional context in comments.

2 Comments

I changed the code, thank you very much, but then I get the following error : "place() takes exactly 4 arguments (2 given). And you said that if I give any arguments, it'll be referred as to None. #Matthew
Yes, you will need to pass the argument with the now bound keys. Check out this and this for some pointers

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.