我认为关于tkinter我不了解一些基本知识,但是阅读了大量教程和其他答案后,我仍然不明白。我正在尝试组织一个简单的GUI。它应该有一个带有游戏板的左侧窗格(游戏是othello),该板上具有活动按钮(我已经省略了动作功能,可以正常工作),然后是一个右侧窗格,其中包含3个窗格,从上到下:一个带有单选按钮,可在1个或2个玩家之间切换,一个带有当前得分,另一个带有游戏评估。就目前而言,后2个只是文本行。
我想我可以在父框架中设置一个网格结构,然后在该网格中具有4个框架,然后在其中构建小部件。这是代码(除非您想运行它,否则可以忽略Board类:我苦苦挣扎的那一点在Master中)
from tkinter import *
from collections import defaultdict
from PIL import Image as PIL_Image, ImageTk
class Master:
def __init__(self):
self.board = Board()
self.display = Tk()
self.f = Frame(self.display, width=1050, height=700)
self.f.grid(row=0, column=0, rowspan=8, columnspan=8)
self.frame2 = Frame(self.f)
self.frame2.grid(row=0, column=8, rowspan=4, columnspan=4)
self.frame3 = Frame(self.f)
self.frame3.grid(row=4, column=8, rowspan=2, columnspan=4)
self.frame4 = Frame(self.f)
self.frame4.grid(row=6, column=8, rowspan=2, columnspan=4)
self.text1 = Text(self.frame3)
self.text1.pack()
self.text2 = Text(self.frame4)
self.text2.pack()
self.square = defaultdict(Button)
self.images = [ImageTk.PhotoImage(PIL_Image.open(f)) for f in ['white.png', 'empty.png', 'black.png']]
modes = [('{} vs {}'.format(i,j), (i, j)) for i in ['human','computer']
for j in ['human', 'computer']]
v = StringVar()
v.set(modes[0][1])
for text, mode in modes:
b = Radiobutton(self.frame2, text=text, variable=v, value=mode, command=lambda mode=mode: self.cp_set(mode))
b.pack(anchor=W)
self.text1.insert(END, 'score')
self.text2.insert(END, 'evaluation')
self.draw_board()
self.display.mainloop()
def draw_board(self):
for i, j in [(x,y) for x in range(8) for y in range(8)]:
self.square[i,j] = Button(self.f, command=lambda i=i, j=j: self.press(i,j), image=self.images[1 + self.board.square[i,j]])
self.square[i,j].image = 1 + self.board.square[i,j]
self.square[i,j].grid(column=i, row=j)
def cp_set(self, m):
self.pb, self.pw = m
return
def press(self, a, b):
# make it do something
return
class Board:
def __init__(self, parent=None):
self.parent = parent
if parent:
self.square = parent.square.copy()
self.black_next = not parent.black_next
self.game_over = parent.game_over
else:
self.square = defaultdict(int)
for square in [(x,y) for x in range(8) for y in range(8)]:
self.square[square] = 0
for square in [(3,3), (4,4)]:
self.square[square] = 1
for square in [(3,4), (4,3)]:
self.square[square] = -1
self.black_next = True
self.game_over = False
这给出了一张图片,其中游戏板的顶部4行与单选按钮对齐,但底部4行被拆分,两条文本行均排成一行,而不是在游戏板的对面
看到这行不通,我读到一些有关网格不保留父框架和子框架之间的行和列的问题,因此我尝试了另一种方法,将父框架分为两列,然后将子框架框架位于其下方,具有自己的行/列定义。但这也不起作用:
self.board = Board()
self.display = Tk()
self.f = Frame(self.display, width=1050, height=700)
self.f.grid(row=0, column=0, rowspan=1, columnspan=2)
self.frame1 = Frame(self.f, width=700, height=700)
self.frame1.grid(row=0, column=0, rowspan=8, columnspan=8)
self.f2 = Frame(self.f)
self.f2.grid(row=0, column=1, rowspan=2, columnspan=1)
self.frame2 = Frame(self.f2, width=350, height=350)
self.frame2.grid(row=0, column=0)
self.frame3 = Frame(self.f2, width=350, height=350)
self.frame3.grid(row=1, column=0)
self.text1 = Text(self.frame2)
self.text1.pack()
self.text2 = Text(self.frame3)
self.text2.pack()
# in this version, Radiobuttons are children of self.frame2,
# and Buttons in draw_board() are children of self.frame1
在看到董事会完全消失的结果之前,我非常喜欢第二版。任何指针将不胜感激。
答案 0 :(得分:3)
您可能想尝试这样的事情:
from tkinter import *
from collections import defaultdict
from PIL import Image as PIL_Image, ImageTk
class Master:
def __init__(self):
self.board = Board()
self.display = Tk()
self.left = Frame(self.display)
self.left.grid(row=0, column=0, sticky="new")
self.right = Frame(self.display)
self.right.grid(row=0, column=1)
self.right_top = Frame(self.right)
self.right_top.grid(row=0, column=0, sticky="nsw")
self.right_mid = Frame(self.right)
self.right_mid.grid(row=1, column=0)
self.right_bottom = Frame(self.right)
self.right_bottom.grid(row=2, column=0)
self.text1 = Text(self.right_mid)
self.text1.pack()
self.text2 = Text(self.right_bottom)
self.text2.pack()
self.square = defaultdict(Button)
self.images = [ImageTk.PhotoImage(PIL_Image.open(f)) for f in ['white.png', 'empty.png', 'black.png']]
modes = [('{} vs {}'.format(i,j), (i, j)) for i in ['human','computer'] for j in ['human', 'computer']]
v = StringVar()
v.set(modes[0][1])
for text, mode in modes:
b = Radiobutton(self.right_top, text=text, variable=v, value=mode, command=lambda mode=mode: self.cp_set(mode))
b.pack(anchor=W)
self.text1.insert(END, 'score')
self.text2.insert(END, 'evaluation')
self.draw_board()
self.display.mainloop()
def draw_board(self):
for i, j in [(x,y) for x in range(8) for y in range(8)]:
self.square[i,j] = Button(self.left, command=lambda i=i, j=j: self.press(i,j), image=self.images[1 + self.board.square[i,j]])
self.square[i,j].image = 1 + self.board.square[i,j]
self.square[i,j].grid(column=i, row=j)
框架的布局如下: