使用 Tkinter Python 的交互式游戏板 - 标签更新
Interactive game board with Tkinter Python - label updating
我是 Tkinter 的新手,如果我说错了什么,请见谅。我正在 Python 中实现游戏十五,我想用 Tkinter 制作它的视觉效果。参见下面的 2x2 板:
4 3
2×
如果你提示 x 与 3 交换,那些标签应该是 updated.So far 我初始化了一个 canvas,并且有两个代码片段,一个用于设置板:
def visualize():
for i,row in enumerate(board):
for j,column in enumerate(row):
L = Label(root,text=' %s '%board[i][j],bg='pink')
if board[i][j] == d*d:
L = tk.Label(root,text=' ')
对于移动函数:
def move():
tile = int(raw_input('Which tile would you like to move: '))
global board, blankx, blanky
for i in range(d):
for j in range(d):
if(board[i][j] == tile):
if(i - 1 == blanky or i + 1 == blanky or j - 1 == blankx or j + 1 == blankx):
board[i][j] = d * d
board[blanky][blankx] = tile
blanky = i
blankx = j
return True
return False
关于如何将标签合并到我的 canvas 以及如何将移动合并为 canvas 上的有效事件有什么想法吗?非常感谢
如果您不需要移动图块的动画,那么您可以使用 grid()
将标签放在行和列中 - 而不是使用 Canvas
- 并将文本从一个标签移动到另一个标签。
您甚至可以使用 Button
(而不是 Label
)和 command=
为按钮分配功能。
-
如果您需要动画,那么您可以使用 create_window()
将 Label
添加到 Canvas
并使用 bind(event, function)
将函数分配给事件调用的标签(如 )。
但您也可以使用 place()
在 Frame
中放置标签或按钮
-
而且您必须将所有 label/buttons 保留在全局列表中才能访问它们。
-
编辑: 简单有效的示例(但不完整)
import tkinter as tk
# --- functions ---
def move(x, y):
global empty_x, empty_y, game_running
if game_running:
# check and move tile
if (empty_x, empty_y) in [(x+1, y), (x-1, y), (x, y+1), (x, y-1)]:
board[empty_y][empty_x] = board[y][x]
board[y][x] = ' '
buttons[empty_y][empty_x]['text'] = buttons[y][x]['text']
buttons[y][x]['text'] = ' '
empty_x = x
empty_y = y
if won():
# show label "Hurray"
label.lift()
game_running = False
else:
# start game again
shuffle() # shuffle tiles
game_running = True
# hide label
label.lower() # or frame.lift()
def won():
number = 0
for y, row in enumerate(board):
for x, char in enumerate(row, 1):
number += 1
if number == 9 and char == ' ':
#print('A |%s| %d' % (char, number))
return True
elif char != str(number):
#print('B |%s| %d' % (char, number))
return False
return True
def shuffle():
# TODO: shuffle tiles
# it can't put tiles in random places
# because it can create game without solution
pass
# --- data ---
board = [
['1', '2', '3'],
['4', '5', '6'],
['7', '8', ' '],
]
empty_x = len(board[0])-1
empty_y = len(board)-1
# --- main ---
root = tk.Tk()
# create label hidden behide frame
label = tk.Label(root, text="Hurray!\n\n(click any button to play again)", bg="red")
label.grid(row=0, column=0, ipadx=20, ipady=20)
# create frame with buttons to fast show/hide label
frame = tk.Frame(root)
frame.grid(row=0, column=0) # the same (row,col) to hide label
buttons = []
for y, row in enumerate(board):
buttons_row = []
for x, char in enumerate(row):
b = tk.Button(frame, text=char, width=10, height=5, command=lambda x=x,y=y:move(x,y))
b.grid(row=y, column=x)
buttons_row.append(b)
buttons.append(buttons_row)
# start game
shuffle() # shuffle tiles
game_running = True
# start "the engine"
root.mainloop()
编辑:新版本StringVar
在shuffle
中,我把方块放在随机的地方,有时我的游戏没有解决方案。
有一些较小的修改 - "Hurray" 现在是一个按钮并开始新游戏。
import tkinter as tk
import random
# --- functions ---
def move(x, y):
global empty_x, empty_y, game_running
if game_running:
# check and move tile
if (empty_x, empty_y) in [(x+1, y), (x-1, y), (x, y+1), (x, y-1)]:
board[empty_y][empty_x].set( board[y][x].get() )
board[y][x].set(' ')
empty_x = x
empty_y = y
if won():
# show label "Hurray"
label.lift()
game_running = False
else:
# start game again
shuffle() # shuffle tiles
def won():
number = 0
for y, row in enumerate(board):
for x, string_var in enumerate(row, 1):
number += 1
if number == 9 and string_var.get() == ' ':
#print('A |%s| %d' % (char, number))
return True
elif string_var.get() != str(number):
#print('B |%s| %d' % (char, number))
return False
return True
def shuffle():
global empty_x, empty_y, game_running
# TODO: shuffle tiles
# it can't put tiles in random places
# because it can create game without solution
# clear all tiles to recognize (in next step) empty tiles
for row in board:
for element in row:
element.set('')
# put tiles in random places
for number in range(1, 10):
while True:
row = random.randint(0, 2)
col = random.randint(0, 2)
if board[row][col].get() == '':
board[row][col].set(str(number))
print('row/col/number:', row, col, number)
break
# last number remove:
print('empty row/col:', row, col)
board[row][col].set(' ')
empty_x = col
empty_y = row
# hide label
label.lower() # or frame.lift()
# start game
game_running = True
# --- main ---
root = tk.Tk()
# --- data ---
# StringVar needs `root` - it has to be after tk.Tk()
# empty board
board = [
# [tk.StringVar(value='1'), tk.StringVar(value='2'), tk.StringVar(value='3')],
[tk.StringVar(), tk.StringVar(), tk.StringVar()],
[tk.StringVar(), tk.StringVar(), tk.StringVar()],
[tk.StringVar(), tk.StringVar(), tk.StringVar()],
]
# create label hidden behide frame
label = tk.Button(root, text="Hurray!\n\n(click here to play again)", command=shuffle)
label.grid(row=0, column=0, ipadx=50, ipady=50)
# create frame with buttons to fast show/hide label
frame = tk.Frame(root)
frame.grid(row=0, column=0) # the same (row,col) to hide label
buttons = []
for y, row in enumerate(board):
buttons_row = []
for x, string_var in enumerate(row):
b = tk.Button(frame, textvariable=string_var, width=10, height=5, command=lambda x=x,y=y:move(x,y))
b.grid(row=y, column=x)
buttons_row.append(b)
buttons.append(buttons_row)
# start game
shuffle() # shuffle tiles
# start "the engine"
root.mainloop()
我是 Tkinter 的新手,如果我说错了什么,请见谅。我正在 Python 中实现游戏十五,我想用 Tkinter 制作它的视觉效果。参见下面的 2x2 板:
4 3
2×
如果你提示 x 与 3 交换,那些标签应该是 updated.So far 我初始化了一个 canvas,并且有两个代码片段,一个用于设置板:
def visualize():
for i,row in enumerate(board):
for j,column in enumerate(row):
L = Label(root,text=' %s '%board[i][j],bg='pink')
if board[i][j] == d*d:
L = tk.Label(root,text=' ')
对于移动函数:
def move():
tile = int(raw_input('Which tile would you like to move: '))
global board, blankx, blanky
for i in range(d):
for j in range(d):
if(board[i][j] == tile):
if(i - 1 == blanky or i + 1 == blanky or j - 1 == blankx or j + 1 == blankx):
board[i][j] = d * d
board[blanky][blankx] = tile
blanky = i
blankx = j
return True
return False
关于如何将标签合并到我的 canvas 以及如何将移动合并为 canvas 上的有效事件有什么想法吗?非常感谢
如果您不需要移动图块的动画,那么您可以使用 grid()
将标签放在行和列中 - 而不是使用 Canvas
- 并将文本从一个标签移动到另一个标签。
您甚至可以使用 Button
(而不是 Label
)和 command=
为按钮分配功能。
-
如果您需要动画,那么您可以使用 create_window()
将 Label
添加到 Canvas
并使用 bind(event, function)
将函数分配给事件调用的标签(如 )。
但您也可以使用 place()
在 Frame
-
而且您必须将所有 label/buttons 保留在全局列表中才能访问它们。
-
编辑: 简单有效的示例(但不完整)
import tkinter as tk
# --- functions ---
def move(x, y):
global empty_x, empty_y, game_running
if game_running:
# check and move tile
if (empty_x, empty_y) in [(x+1, y), (x-1, y), (x, y+1), (x, y-1)]:
board[empty_y][empty_x] = board[y][x]
board[y][x] = ' '
buttons[empty_y][empty_x]['text'] = buttons[y][x]['text']
buttons[y][x]['text'] = ' '
empty_x = x
empty_y = y
if won():
# show label "Hurray"
label.lift()
game_running = False
else:
# start game again
shuffle() # shuffle tiles
game_running = True
# hide label
label.lower() # or frame.lift()
def won():
number = 0
for y, row in enumerate(board):
for x, char in enumerate(row, 1):
number += 1
if number == 9 and char == ' ':
#print('A |%s| %d' % (char, number))
return True
elif char != str(number):
#print('B |%s| %d' % (char, number))
return False
return True
def shuffle():
# TODO: shuffle tiles
# it can't put tiles in random places
# because it can create game without solution
pass
# --- data ---
board = [
['1', '2', '3'],
['4', '5', '6'],
['7', '8', ' '],
]
empty_x = len(board[0])-1
empty_y = len(board)-1
# --- main ---
root = tk.Tk()
# create label hidden behide frame
label = tk.Label(root, text="Hurray!\n\n(click any button to play again)", bg="red")
label.grid(row=0, column=0, ipadx=20, ipady=20)
# create frame with buttons to fast show/hide label
frame = tk.Frame(root)
frame.grid(row=0, column=0) # the same (row,col) to hide label
buttons = []
for y, row in enumerate(board):
buttons_row = []
for x, char in enumerate(row):
b = tk.Button(frame, text=char, width=10, height=5, command=lambda x=x,y=y:move(x,y))
b.grid(row=y, column=x)
buttons_row.append(b)
buttons.append(buttons_row)
# start game
shuffle() # shuffle tiles
game_running = True
# start "the engine"
root.mainloop()
编辑:新版本StringVar
在shuffle
中,我把方块放在随机的地方,有时我的游戏没有解决方案。
有一些较小的修改 - "Hurray" 现在是一个按钮并开始新游戏。
import tkinter as tk
import random
# --- functions ---
def move(x, y):
global empty_x, empty_y, game_running
if game_running:
# check and move tile
if (empty_x, empty_y) in [(x+1, y), (x-1, y), (x, y+1), (x, y-1)]:
board[empty_y][empty_x].set( board[y][x].get() )
board[y][x].set(' ')
empty_x = x
empty_y = y
if won():
# show label "Hurray"
label.lift()
game_running = False
else:
# start game again
shuffle() # shuffle tiles
def won():
number = 0
for y, row in enumerate(board):
for x, string_var in enumerate(row, 1):
number += 1
if number == 9 and string_var.get() == ' ':
#print('A |%s| %d' % (char, number))
return True
elif string_var.get() != str(number):
#print('B |%s| %d' % (char, number))
return False
return True
def shuffle():
global empty_x, empty_y, game_running
# TODO: shuffle tiles
# it can't put tiles in random places
# because it can create game without solution
# clear all tiles to recognize (in next step) empty tiles
for row in board:
for element in row:
element.set('')
# put tiles in random places
for number in range(1, 10):
while True:
row = random.randint(0, 2)
col = random.randint(0, 2)
if board[row][col].get() == '':
board[row][col].set(str(number))
print('row/col/number:', row, col, number)
break
# last number remove:
print('empty row/col:', row, col)
board[row][col].set(' ')
empty_x = col
empty_y = row
# hide label
label.lower() # or frame.lift()
# start game
game_running = True
# --- main ---
root = tk.Tk()
# --- data ---
# StringVar needs `root` - it has to be after tk.Tk()
# empty board
board = [
# [tk.StringVar(value='1'), tk.StringVar(value='2'), tk.StringVar(value='3')],
[tk.StringVar(), tk.StringVar(), tk.StringVar()],
[tk.StringVar(), tk.StringVar(), tk.StringVar()],
[tk.StringVar(), tk.StringVar(), tk.StringVar()],
]
# create label hidden behide frame
label = tk.Button(root, text="Hurray!\n\n(click here to play again)", command=shuffle)
label.grid(row=0, column=0, ipadx=50, ipady=50)
# create frame with buttons to fast show/hide label
frame = tk.Frame(root)
frame.grid(row=0, column=0) # the same (row,col) to hide label
buttons = []
for y, row in enumerate(board):
buttons_row = []
for x, string_var in enumerate(row):
b = tk.Button(frame, textvariable=string_var, width=10, height=5, command=lambda x=x,y=y:move(x,y))
b.grid(row=y, column=x)
buttons_row.append(b)
buttons.append(buttons_row)
# start game
shuffle() # shuffle tiles
# start "the engine"
root.mainloop()