I am trying to create a basic Battleship game in Python using Tkinter.
Below is a very simplified version of my code. Essentially I am creating a 10*10 grid of buttons and positioning them using .grid
. What I'd like to do is click one of those buttons and pass that buttons grid values (x, y) from the GameBoard
class to the Battleship
class to position the ship.
I have tried using self.row = row
and self.column = column
, however when I do this I immediately receive an attribute error, 'GameBoard' object has no attribute 'row'
.
import tkinter as tk
class GameBoard:
def __init__(self):
self.mw = tk.Tk()
self.size = 10
def build_grid(self):
for x in range(self.size):
for y in range(self.size):
self.button = tk.Button(self.mw, text = '', width = 2, height = 1,\
command = lambda row = x, column = y: self.clicked(row, column))
self.button.grid(row = x, column = y)
def clicked(self, row, column):
print(row, column)
self.row = row
self.column = column
class Battleship:
def __init__(self, board):
self.gboard = board
def position_ship(self):
x = self.gboard.row
y = self.gboard.column
for i in range (3):
self.submarine = tk.Button(self.gboard.mw, background = "black", text = '',\
width = 2, height = 1)
self.submarine.grid(row = x, column = y)
def main():
gboard = GameBoard()
gboard.build_grid()
bt = Battleship(gboard)
bt.position_ship()
main()
CodePudding user response:
As @acw1668 pointed out in a comment, the problem is the gboard
attributes row
and column
haven't been created yet when you call bt.position_ship()
in the main()
function.
I don't know your overall game design, but a very simple way to fix that would be to assign a random board position to them in the GameBoard.__init__()
method.
I've also modified the code to show how to call bt.position_ship()
when a button is clicked. This is done by passing the BattleShip
instance bt
to the build_grid()
function so it can be included in calls to the clicked()
method, which can now call it when its called.
from random import randrange
import tkinter as tk
class GameBoard:
def __init__(self):
self.mw = tk.Tk()
self.size = 10
self.row = randrange(self.size)
self.column = randrange(self.size)
def build_grid(self, bt):
for x in range(self.size):
for y in range(self.size):
self.button = tk.Button(self.mw, text='', width=2, height=1,
command=lambda row=x, column=y:
self.clicked(bt, row, column))
self.button.grid(row=x, column=y)
def clicked(self, bt, row, column):
print(row, column)
self.row = row
self.column = column
bt.position_ship()
class Battleship:
def __init__(self, board):
self.gboard = board
def position_ship(self):
x = self.gboard.row
y = self.gboard.column
for i in range (3):
self.submarine = tk.Button(self.gboard.mw, background="black", text='',
width=2, height=1)
self.submarine.grid(row=x, column=y)
def main():
gboard = GameBoard()
bt = Battleship(gboard)
gboard.build_grid(bt)
bt.position_ship()
tk.mainloop()
main()