Python Tkinter move one image with position in chess game - python

I made a chess game in Python with Tkinter, but I've a huge problem.
The piece is generated by a matrix. But, When a case is empty or when I moved a piece, I can't wish(delete) the case. I want to wish(delete) only a piece with cordonnate or just move image of one piece (I don't khnow if it's possible), any one help?
The code:
from tkinter import *
from PIL import Image
import math
root = Tk()
root.title("Game")
frame = Frame(root)
frame.pack()
canvas = Canvas(frame, bg="black", width=500, height=500)
canvas.pack()
background = PhotoImage(file="image/Chessboard.png")
canvas.create_image(250,250,image=background)
pion = PhotoImage(file="image/W_pion.png")
Matrixe= [["","","","","","","",""],
["","","","","","","",""],
["","","","","","","",""],
["","","","","","","",""],
["","","","","","","",""],
["","","","","","","",""],
["W_Pion","W_Pion","W_Pion","W_Pion","W_Pion","W_Pion","W_Pion","W_Pion"],
["","","","","","","",""]]
ligne=len(Matrixe)
col=len(Matrixe[0])
def actu():
for l in range(ligne):
for c in range(col):
if Matrixe[c][l] == "W_Pion":
canvas.create_image(62.5 * l + 33,62.5 * c + 33,image=pion)
actu()
#mouse input
def getorigin(eventorigin):
global Posx,Posy, i, piece
Posx = eventorigin.x
Posy = eventorigin.y
Xcase = math.ceil((Posx / 62)) - 1
Ycase = math.ceil((Posy / 62)) - 1
if Matrixe[Ycase][Xcase] != "":
global preY , preX, piece
piece = Matrixe[Ycase][Xcase]
i = 1
preY = Ycase
preX = Xcase
print(piece)
if canvas.bind("<Button-1>") and Matrixe[Ycase][Xcase] == "":
Matrixe[Ycase][Xcase] = piece
Matrixe[preY][preX] = ""
print(Matrixe[preY][preX])
actu()
canvas.bind("<Button-1>", getorigin)
root.title("Chess")
root.iconbitmap("icon.ico")
root.geometry("500x500")
root.mainloop()

It is because you did not delete the previous set of chess pieces before creating new set of chess pieces inside actu().
Create the chess pieces with a tag, for example 'piece', then you can delete old set of chess pieces using that tag:
def actu():
canvas.delete('piece') # delete old chess pieces
for l in range(ligne):
for c in range(col):
if Matrixe[c][l] == "W_Pion":
canvas.create_image(62.5*l+33, 62.5*c+33, image=pion, tag='piece')
However, better approach is just to move the piece selected instead of recreate the set of pieces:
def actu():
for l in range(ligne):
for c in range(col):
if Matrixe[c][l] == "W_Pion":
# replace cell content by the canvas item ID
Matrixe[c][l] = canvas.create_image(62.5*l+33, 62.5*c+33, image=pion, tag=Matrixe[c][l])
actu()
piece = None
def getorigin(eventorigin):
global preX, preY, piece
Posx = eventorigin.x
Posy = eventorigin.y
Xcase = math.ceil((Posx / 62)) - 1
Ycase = math.ceil((Posy / 62)) - 1
if Matrixe[Ycase][Xcase] != "":
# select the piece
piece = Matrixe[Ycase][Xcase]
preY = Ycase
preX = Xcase
elif piece:
# a piece is selected, so move the piece
canvas.coords(piece, Xcase*62.5+33, Ycase*62.5+33)
Matrixe[Ycase][Xcase] = piece
Matrixe[preY][preX] = ""
piece = None # deselect the piece

Related

Chess game using Tkinter GUI, Moving the pieces

I am currently working on a chess game as the A-Level programming project and I am having trouble getting the pieces to move across the board. The canvas.move() function that i am using doesn't seem to move the images and i have tried other functions including canvas.coords() any help would be appreciated.
This is the code for moving the pieces:
piece = None
def getorigin(eventorigin):
global Posx,Posy, piece
Posx = eventorigin.x
Posy = eventorigin.y
Xcase = math.ceil((Posx / 62)) - 1
Ycase = math.ceil((Posy / 62)) - 1
if Matrix[Ycase][Xcase] != "":
# select the piece
piece = Matrix[Ycase][Xcase]
preY = Ycase
preX = Xcase
print(piece)
elif piece:
# a piece is selected, so move the piece
canvas.move(piece, Xcase*62.5+33, Ycase*62.5+33)
Matrix[Ycase][Xcase] = piece
Matrix[preY][preX] = ""
piece = None # deselect the piece
piecePosition()
canvas.bind("<Button-1>", getorigin)
root.title("Chess")
root.iconbitmap()
root.geometry("500x500")
root.mainloop()
This is the matrix grid being used as the board:
Matrix= [["bRook","bKnight","bBishop","bQueen","bKing","bBishop","bKnight","bRook"],
["bPawn","bPawn","bPawn","bPawn","bPawn","bPawn","bPawn","bPawn"],
["","","","","","","",""],
["","","","","","","",""],
["","","","","","","",""],
["","","","","","","",""],
["wPawn","wPawn","wPawn","wPawn","wPawn","wPawn","wPawn","wPawn"],
["wRook","wKnight","wBishop","wQueen","wKing","wBishop","wKnight","wRook"]]

Why does my program require me to press the enter key before continuing (python tkinter)

I am making a program, using python tkinter, which simply prints some circles to the screen (I call it a board in this program). The program moves on to a different "board" once the mouse cursor moves over the button. The problem I have is that I simply call the "create_board" function 3 times using a for loop however in-between each iteration of the loop the "enter" key must be pressed. This isn't a massive deal but I'm trying to understand why and if there is a way to remove this requirement and have the next board load automatically.
I'm certain it has something to do with the tkinter windows and triggering the command "destroy" once the buttons (circles) are pressed however I'm still learning how to effectively use tkinter and any help would be very much appreciated.
def create_board(user_name, board):
# define the name of tkinter window
win = Tk()
# get the size of the displace for position and size calculations
app = wx.App(False)
w, h = wx.GetDisplaySize()
name = user_name
# define variables based on board number
if board == 0:
gx_pos = int(w/8) # locations of circles
gy_pos = int(h/8)
bx_pos = (w/8)*5
by_pos = (h/8)*5
board_num = str(1)
elif board == 1:
gx_pos = int(w/12)
gy_pos = int(h/12)
bx_pos = (w/6)*5
by_pos = (h/6)*5
board_num = str(2)
elif board == 2:
gx_pos = int(w/3)
gy_pos = int(h/3)
bx_pos = (w/3)*2
by_pos = (h/3)*2
board_num = str(3)
# records the mouse cursor position into a file along with time taken
def record_pos(x, y, board_num, s):
filename = name + "_" + board_num + ".txt"
try:
os.path.isfile('./'+filename)
except:
open(filename, 'r')
with open(filename, 'a') as f:
f.write(str(x) + "," + str(y) + "," + str(s) + "\n")
# determining when left click should be made
def mouse_pos():
flags, hcursor, (x, y) = win32gui.GetCursorInfo()
time_taken = time.time()
record_pos(x, y, board_num, time_taken)
mouse.click('left')
win.after(500, mouse_pos)
# wait 3 seconds before loading first board
time.sleep(3)
geometry = "%dx%d" % (w,h)
win.geometry(geometry)
win.attributes('-fullscreen', True)
win.config(cursor="circle")
# get the grid image
bg = Image.open("grid_image.png")
img = bg.resize((w, h))
grid_img=ImageTk.PhotoImage(img)
image_label = Label(win, image=grid_img)
image_label.place(x=0, y=0, relwidth=1, relheight=1)
# print an image of a green circle
gw = int(w/26)
gh = int(h/15)
g_circle = Image.open('green_circle.png')
g_img = g_circle.resize((gw,gh))
g_circle_image=ImageTk.PhotoImage(g_img)
g_label = Label(win, image=g_circle_image)
g_label.place(x = gx_pos,y = gy_pos)
g_btn = Button(win, image=g_circle_image, command = win.destroy)
g_btn.place(x= gx_pos , y= gy_pos)
# print an image of a blue circle
bw = int(w/26)
bh = int(h/15)
b_circle = Image.open('circle.png')
b_img = b_circle.resize((bw,bh))
b_circle_image=ImageTk.PhotoImage(b_img)
b_label = Label(win, image=b_circle_image)
b_label.place(x=bx_pos, y=by_pos)
b_btn = Button(win, image=b_circle_image, command = win.destroy)
b_btn.place(x=bx_pos, y=by_pos)
# record mouse position
mouse_pos()
win.mainloop()
EDIT: I added the simple for loop that I'm using to iterate through the boards.
for i in range(3):
create_board(user_name, i)
The issue was caused by using time.sleep() in tkinter. After removing this the code runs with out requiring an enter key press each time.

How can I get my game of life code to animate in python?

I'm currently writing the John Conway's game of life in python and I'm stuck when it comes getting the cells to animate according to the rules. currently my code is compiling without any errors but I just can't figure out how I can get the code to animate. My code is:
code edit
from tkinter import *
from random import *
import time
import numpy as np
PIXEL_SIZE = 10
ROW = 910
COLUMN = 700
grid = []
updated_grid = [[]]
def create_grid():
for row in range(0, ROW):
grid2 = []
for column in range(0, COLUMN):
grid2.append(randint(0, 1))
grid.append(grid2)
def draw_grid():
for row in range(0, ROW):
for column in range(0, COLUMN):
if grid[row][column] == 1:
x0 = row*PIXEL_SIZE
y0 = column*PIXEL_SIZE
x1 = x0+PIXEL_SIZE
y1 = y0+PIXEL_SIZE
canvas.create_rectangle(x0, y0, x1, y1, fill='red')
def apply_rules():
for row in range(1, ROW - 1):
for column in range(1, COLUMN - 1):
neighbours_count = 0
# will count the neighbours for each cell
neighbours_count += grid[row-1][column-1] # top left
neighbours_count += grid[row][column-1] # top center
neighbours_count += grid[row+1][column-1] # top right
neighbours_count += grid[row-1][column] # middle left
neighbours_count += grid[row+1][column] # middle right
neighbours_count += grid[row-1][column+1] # bottom left
neighbours_count += grid[row][column+1] # bottom center
neighbours_count += grid[row+1][column+1] # bottom right
# Game Of Life rules:
# alive cell rules
if grid[row][column] == 1:
if neighbours_count < 2: # rule 1 any live cell with fewer than two live neighbours dies, as if by underpopulation
grid[row][column] = 0
elif neighbours_count == 2 | neighbours_count == 3: # rule 2 any live cell with two or three live neighbours lives on to the next generation
grid[row][column] = 1
elif neighbours_count > 3 & neighbours_count <= 8: # rule 3 any live cell with more than three live neighbours dies, as if by overpopulation
grid[row][column] = 0
else:
grid[row][column] = 0
elif grid[row][column] == 0: # dead cells rule 4 any dead cell with exactly three live neighbours becomes a live cell, as if by reproduction
if neighbours_count == 3:
grid[row][column] = 1
else:
grid[row][column] = 0
def one_cycle():
apply_rules()
draw_grid()
window.after(1, one_cycle)
window = Tk() # creates the window for the game
window.title('Game Of Life Python') # is the game title written on the window
canvas_frame = Frame(window) # creates a frame on the window to hold the canvas
game_title = Frame(window) # creates a frame on the window to display the game title (which will be a label)
start_button = Button(window, text='Start Game', command=one_cycle) # creates a button which will be used to start the game
canvas = Canvas(canvas_frame, width=ROW, height=COLUMN, background='black') # creates the canvas used to the draw the game of life
game_title_label = Label(game_title, text='Game Of Life', font='Helvetica 20 bold', fg='grey') # creates the label for the game title which will be placed in a frame
canvas.grid(row=0, column=0) # places the canvas onto the canvas_frame
canvas_frame.grid(row=1, column=1) # places the canvas_frame onto the window
game_title_label.grid(rowspan=2, column=0) # places the title of the game onto the game_title frame
game_title.grid(row=0, columnspan=2) # places the frame for the game title onto the window
start_button.grid(rowspan=2, column=1) # places the start onto the window
create_grid()
window.mainloop()
I am new to python so please forgive me if you see any errors I've missed and thank you for any help you are able to give me.
I think you need a few modifications:
Change your Button to start the drawing: start_button = Button(window, text='Start Game', command=apply_rules)
Modify def apply_rules(): to have this addition at the end: window.after(0, apply_rules)
Don't call apply_rules() your self: apply_rules()
When you run the program you will need to press the Start Game button.
================
Update:
You may need to add another function to encapsulate the idea of running the rules and displaying the results continuously:
Keep def apply_rules(): as you have it in your posting and add a new function:
def one_cycle():
apply_rules()
draw_grid()
window.after(1, one_cycle) # use 1 to ease performance as Bryan suggests
Change the Button command to: command=one_cycle
Now you only need this at the bottom:
create_grid()
window.mainloop()

tkinter cant assign text variable

the problem was my input popup had to be a toplevel window so changing tk.Tk() to tk.Toplevel() makes it work fine ;)
#Josh Harrison
#3008088
from graphics import *
from random import randrange
import winsound, sys
#scale for size of squares
scale = 50
#setupBoard sets up the board with a randomly generated puzzle
def setupBoard(size, color):
board = [[[0, Rectangle(Point(scale*.05,scale*.05),Point(scale*.95,scale*.95))] for x in range(size)] for x in range(size)]
for x in range(size):
for y in range(size):
board[x][y][1] = Rectangle(Point(x*scale+scale*.05,y*scale+scale*.05),Point(x*scale+scale*.95,y*scale+scale*.95))
for i in range(1):
selectTile(board, Point(randrange(size)*scale,randrange(size)*scale), size, color)
return board
#selectTile does the action for selecting tiles
#set color to 0 for black and white and 1 for color rotation
def selectTile(board,point,size,color):
#sets value switch according to if colors are desired or not
if color == 1:
valueSwitch = colorSwitch
else:
valueSwitch = bwSwitch
x = int(point.getX()/scale)
y = int(point.getY()/scale)
#temp is made to preserve the selected tiles state
temp = board[x][y][0]
#swap all square values
#note try and except are also looped
for i in range(3):
for z in range(3):
try:
board[x-1+i][y-1+z][0] = valueSwitch(board[x-1+i][y-1+z][0])
except:
#overlap fix for x maxed
if x == size - 1 and y != size - 1:
board[0][y-1+z][0] = valueSwitch(board[0][y-1+z][0])
#overlap fix for y maxed
if y == size - 1 and x != size - 1:
board[x-1+i][0][0] = valueSwitch(board[x-1+i][0][0])
#overlap fix for bottom right corner
if x == size - 1 and y == size - 1:
board[0][0][0] = valueSwitch(board[0][0][0])
for a in range(2):
board[0][size-a-1][0] = valueSwitch(board[0][size-a-1][0])
board[size-a-1][0][0] = valueSwitch(board[size-a-1][0][0])
#give middle square initial value again
board[x][y][0] = temp
#updateBoard updates the squares to the right colour according to value
def updateBoard(board, size, count):
if count != 0:
winsound.Beep(333, 200)
for x in range(size):
for y in range(size):
if board[x][y][0] == 0:
board[x][y][1].setFill('white')
elif board[x][y][0] == 1:
board[x][y][1].setFill('yellow')
elif board[x][y][0] == 2:
board[x][y][1].setFill('green')
elif board[x][y][0] == 3:
board[x][y][1].setFill('blue')
elif board[x][y][0] == 4:
board[x][y][1].setFill('black')
#drawBoard draws the initial board
def drawBoard(size, board, win):
for x in range(size):
for y in range(size):
board[x][y][1].draw(win)
return
#checks to see if board is white(Winning condition)
def winGame(board, size):
#steps through all x and y values
for x in range(size):
for y in range(size):
if board[x][y][0] != 0:
return 0
#returns true if no black squares are found
return 1
#valueSwitch() just makes switching values easier by checking values and selecting the appropriate one
def colorSwitch(value):
if value == 4:
return 0
else:
return value + 1
#bwSwitch only selects from black and white value
def bwSwitch(value):
if value == 4:
return 0
else:
return 4
#winMessage() displaying a winning message graphic
def winMessage(size, scale, win):
gameMessage = Text(Point(size*scale/2,size*scale/2),"You have won logic!")
gameMessage.setSize(int(scale/4))
gameMessage.setTextColor('red')
gameMessage.draw(win)
#gameMenu() is a menu to select game size
def gameMenu():
win = GraphWin("Logic Menu", 400, 600)
win.setBackground('light blue')
board = [[[Text(Point(0,0),'bleh'),Rectangle(Point(0,0),Point(200,200))] for y in range(3)] for x in range(2)]
#Making and drawing the buttons ;)
for x in range(2):
for y in range(3):
board[x][y][1] = Rectangle(Point(x*200+200*.05,y*200+200*.05),Point(x*200+200*.95,y*200+200*.95))
board[x][y][1].draw(win)
board[0][0][0] = Text(board[0][0][1].getCenter(), 'Click for 5x5 puzzle')
board[1][0][0] = Text(board[1][0][1].getCenter(), 'Click for 7x7 puzzle')
board[0][1][0] = Text(board[0][1][1].getCenter(), 'Click for 9x9 puzzle')
board[1][1][0] = Text(board[1][1][1].getCenter(), 'Click for 12x12 puzzle')
board[0][2][0] = Text(board[0][2][1].getCenter(), 'Click to toggle colors')
board[1][2][0] = Text(board[1][2][1].getCenter(), 'Highscores!')
#drawing button options
for x in range(2):
for y in range(3):
board[x][y][0].draw(win)
#check to see what button is pressed
point = win.getMouse()
x = int(point.getX()/200)
y = int(point.getY()/200)
#colors is either 1 for colors or 0 for no colors
colors = 0
#turning colors on and off
#board[0][2][1] is the rectangle for colors
while y == 2:
if x == 0:
if colors == 0:
winsound.Beep(400, 200)
colors = 1
board[0][2][1].setFill('green')
else:
winsound.Beep(363, 200)
colors = 0
board[0][2][1].setFill('')
else:
winsound.Beep(400, 200)
board[1][2][1].setFill('red')
#board is just passed in for a smother button click effect not necessary for functionality
highscore_board(board)
point = win.getMouse()
x = int(point.getX()/200)
y = int(point.getY()/200)
board[x][y][1].setFill('red')
winsound.Beep(400, 200)
win.close()
if x == 0 and y == 0:
return 5 , colors
if x == 1 and y == 0:
return 7 , colors
if x == 0 and y == 1:
return 9 , colors
if x == 1 and y == 1:
return 12 , colors
return 5 , colors
#highscore() checks to see if player has highscore and outputs a highscore to a text file
def highscore(count):
#checks to see if highscore file exists
try:
scoreInfo = [line.strip() for line in open('highscore.txt')]
#remove all spacing
for i in range(scoreInfo.count('')):
scoreInfo.remove('')
scoreInfo[1]
scores = int(len(scoreInfo)/2)
newEntry = 0
#creates new highscore file is none exist
except:
win = GraphWin("Highscore!", 400, 200)
gameMessage = Text(Point(200,100),"Please input name: ")
gameMessage.setSize(int(scale/4))
gameMessage.setTextColor('red')
gameMessage.draw(win)
name=inputWin()
f = open('highscore.txt', 'w')
f.write(name)
f.write('\n'+str(count))
f.close()
gameMessage.setText(name+': '+str(count)+' - saved!')
time.sleep(1)
win.close()
return
#if there is a new highscore it is added at the beginning of the file
for i in range(scores):
if scores < 10 or count < int(scoreInfo[i*2+1]):
win = GraphWin("Highscore!", 400, 200)
gameMessage = Text(Point(200,100),"Please input name: ")
gameMessage.setSize(int(scale/4))
gameMessage.setTextColor('red')
gameMessage.draw(win)
name=inputWin()
f = open('highscore.txt', 'w')
#max 10 highscores 9 + new highscore
if scores >= 10:
scores = 9
for i in range(scores):
try:
if count < int(scoreInfo[i*2+1]) and not newEntry:
f.write(name)
f.write('\n'+str(count))
f.write('\n\n\n')
newEntry = 1
f.write(scoreInfo[i*2])
f.write('\n')
f.write(scoreInfo[i*2+1])
f.write('\n\n\n')
except:
pass
#if no entries have been added
#the new value is then added to the end
if newEntry == 0:
f.write(name)
f.write('\n'+str(count))
f.write('\n\n\n')
f.close()
gameMessage.setText(name+': '+str(count)+' - saved!')
time.sleep(1)
win.close()
break
pass
#board is just passed in for a smother button click effect not necessary for functionality
def highscore_board(board):
win = GraphWin("Highscores", 200, 500)
win.setBackground('light green')
try:
scoreInfo = [line.strip() for line in open('highscore.txt')]
#remove all spacing
for i in range(scoreInfo.count('')):
scoreInfo.remove('')
Text(Point(50,20),"Highscores:").draw(win)
for i in range(10):
Text(Point(10,45*i+60),str(i+1)+'. ').draw(win)
try:
Text(Point(60,45*i+60),scoreInfo[i*2]).draw(win)
Text(Point(170,45*i+60),scoreInfo[1+i*2]).draw(win)
except:
pass
except:
Text(Point(100,250),"no scores yet.").draw(win)
time.sleep(.05)
board[1][2][1].setFill('')
#prevent program crash if scoreboard is exited through os
try:
win.getMouse()
winsound.Beep(363, 200)
win.close()
except:
winsound.Beep(363, 200)
import tkinter as tk
def getString(ment,mGui):
global hsname
hsname = ment.get()
mGui.destroy()
mGui.quit()
def inputWin():
mGui = tk.Tk()
ment = tk.StringVar()
mGui.title('New Highscore!')
mEntry = tk.Entry(mGui,textvariable=ment).pack(side=tk.LEFT)
mbutton = tk.Button(mGui,text='OK',command=lambda:getString(ment,mGui),fg='red',bg='blue').pack(side=tk.RIGHT)
mGui.mainloop()
return hsname
this is the portion that wont work
import tkinter as tk
def getString(ment,mGui):
global hsname
hsname = ment.get()
mGui.destroy()
mGui.quit()
def inputWin():
mGui = tk.Tk()
ment = tk.StringVar()
mGui.title('New Highscore!')
mEntry = tk.Entry(mGui,textvariable=ment)
mEntry.pack(side=tk.LEFT)
mbutton = tk.Button(mGui,text='OK',command=lambda:getString(ment,mGui),fg='red',bg='blue')
mbutton.pack(side=tk.RIGHT)
mGui.mainloop()
return hsname
I'm just screwing around trying to make adding a highscore more visual for a game I made this code it works fine by itself but when I import it or even copy the whole code into a py file with other functions it just stops assigning ment any values I don't understand :/
any help is appreciated
this is the code that runs the game
#Josh Harrison
#3008088
from logic_game import *
def playGame():
option = gameMenu()
size = option[0]
color = option[1]
win = GraphWin("Logic Game", size*scale, size*scale)
win.setBackground('light pink')
board = setupBoard(size, color)
drawBoard(size, board, win)
countText = Text(Point(scale,scale/2),'moves: 0')
countText.setTextColor('red')
countText.draw(win)
count = 0
while not winGame(board, size):
updateBoard(board, size, count)
selectTile(board, win.getMouse(), size, color)
count += 1
countText.setText('moves: ' + str(count))
updateBoard(board, size, count)
winMessage(size, scale, win)
highscore(count)
#pauses the window and waits for click before continuing
win.getMouse()
#closes the window "win"
win.close()
playGame()
link for graphics.py
http://mcsp.wartburg.edu/zelle/python/graphics.py
I don't understand exactly what your problem is doing wrong, but I'm pretty sure I know what the problem is.
Most of your program is using some library named graphics to run a GUI. Then you're trying to use Tkinter to run another GUI in the same program.
I don't know what that graphics library that is, but unless it's either built on top of Tkinter, or specifically designed to work with Tkinter, this is unlikely to work. Both of them are going to try to be in charge of the one and only GUI for your program, handling all of the events from the user/windowing system, and so forth. One or both are going to fail.
In fact, even if graphics were built on top of Tkinter or designed to work together with it, calling mainloop on the Tkinter window is at best going to freeze up the rest of your GUI until you exit that mainloop, and at worst going to break the outer mainloop that the other GUI is relying on.
From what I can see from your other code, that graphics library seems to have enough features to do everything you were trying to do with Tkinter—create a new window, place some widgets on it, handle a button click. So, why not just use that?
Now that you've given us a link to the graphics library you're using… it looks like a thin wrapper around Tkinter. Which means you should be able to integrate them easily. You just have to create a new Toplevel instead of a root window (since graphics has already created a Tkinter root), and not call mainloop or quit (because you're already in a Tkinter main loop created by graphics).
Since you haven't given us an SSCCE that I can just run and hack on, I've built my own super-simple one around the first example in the graphics docs, which does what you were trying to do, and also shows how you can interact with the graphics window from the Tkinter code.
from graphics import *
import Tkinter as tk
def getString(ment,mGui):
global win
print(ment.get())
mGui.destroy()
win.close()
def inputWin():
global hsname
mGui = tk.Toplevel()
ment = tk.StringVar()
mGui.title('New Highscore!')
tk.Entry(mGui,textvariable=ment).pack(side=tk.LEFT)
tk.Button(mGui,text='OK',command=lambda:getString(ment,mGui),fg='red',bg='blue').pack(side=tk.RIGHT)
win.getMouse()
def main():
global win
win = GraphWin("My Circle", 100, 100)
c = Circle(Point(50,50), 10)
c.draw(win)
win.getMouse() # Pause to view result
inputWin()
main()
It would be better to refactor this to eliminate your global variables, either using an OO design (create a class so you can store things as instance attributes) or a functional design (pass values through closures or bake them in with lambda/partial, as you're already doing in your Button command), but I tried to follow the style you already set in your code rather than rewrite everything.

Making Tkinter Photoimage crashes python program

I'm writing a minesweeper game using tkinter, and everything appears to function alright, but python crashes every time after a number of clicks, and I believe it is because I've added images for the "flags" used to flag where a mine is. Below is the function that draws all of the cells, which is called with each move/click.
def draw_cake_cell(canvas, row, col):
# draws different cells on the board (blank cell, numbers, cake flags)
margin = 5
cellSize = 30
board = canvas.data['board']
mask = canvas.data['mask']
cake_count = canvas.data['cake_count']
player_board = canvas.data['player_board']
left = margin + col*cellSize
top = margin + row*cellSize
bottom = top + cellSize
right = left+cellSize
flag_img = PhotoImage(file="flag.gif")
flag_label = Label(image = flag_img)
flag_label.image = flag_img
cake_img = PhotoImage(file = "cakeflag.gif")
cake_label = Label(image = cake_img)
cake_label.image = cake_img
canvas.create_rectangle(left,top, right, bottom, fill = 'gray')
if board[row][col] == -1:
if canvas.data['isGameOver'] == True:
canvas.create_image((left+right)/2,(top+bottom)/2,image = cake_img)
elif mask[row][col] == -2:
canvas.create_image((left+right)/2,(top+bottom)/2,image = flag_img)
else:
if cake_count[row][col] > 0 and player_board[row][col] == 1:
value = cake_count[row][col]
canvas.create_rectangle(left,top,right,bottom, fill = 'white')
canvas.create_text((left+right)/2,(top+bottom)/2 , text = str(value), font = ('Helvetica',12))
if mask[row][col] == -2:
canvas.create_image((left+right)/2,(top+bottom)/2,image = flag_img)
if cake_count[row][col] == 0 and player_board[row][col] == 1:
canvas.create_rectangle(left,top,right,bottom, fill = 'white')
Since you are using python3, (left+right)/2 is float, not an int. maybe that's the problem - use (left+right)//2.

Categories