Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/user-interface/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python Tkinter窗口/小部件按比例调整大小_Python_User Interface_Tkinter - Fatal编程技术网

Python Tkinter窗口/小部件按比例调整大小

Python Tkinter窗口/小部件按比例调整大小,python,user-interface,tkinter,Python,User Interface,Tkinter,我目前正在为一个编程类开发一个Python GUI版本的Reversi。我已经对游戏逻辑进行了编程,目前正在尝试使用Tkinter实现GUI。我在按比例调整游戏板(根窗口)和上面的所有内容(画布和形状)时遇到了一些问题。游戏目前运行正常,但我试图让棋盘正确调整大小的一切都没有起作用。有关守则如下 class OthelloApplication: def __init__(self, game_state: othello.Othello): self._game_sta

我目前正在为一个编程类开发一个Python GUI版本的Reversi。我已经对游戏逻辑进行了编程,目前正在尝试使用Tkinter实现GUI。我在按比例调整游戏板(根窗口)和上面的所有内容(画布和形状)时遇到了一些问题。游戏目前运行正常,但我试图让棋盘正确调整大小的一切都没有起作用。有关守则如下

class OthelloApplication:
    def __init__(self, game_state: othello.Othello):
        self._game_state = game_state
        self._game_state.new_game()
        self._game_board = game_state.show_board()
        self._root_window = tkinter.Tk()

        for row in range(self._game_state.show_rows()):
            for col in range(self._game_state.show_cols()):
                canvas = tkinter.Canvas(self._root_window, width = 100, height = 100, 
                    borderwidth = 0, highlightthickness = 1, 
                    background = _BACKGROUND_COLOR, highlightbackground = 'black')
                canvas.grid(row = row, column = col, padx = 0, pady = 0,
                    sticky = tkinter.N + tkinter.S + tkinter.E + tkinter.W)
                self._root_window.rowconfigure(row, weight = 1)
                self._root_window.columnconfigure(col, weight = 1)

        self._turn_window = tkinter.Canvas(self._root_window, width = 200,
            height = 100, highlightthickness = 0, background = 'white')

        self._root_window.bind('<Button-1>', self._on_canvas_clicked)
        self._root_window.bind('<Configure>', self.on_resize)



    def draw_game_pieces(self) -> None:
        for row in range(self._game_state.show_rows()):
            for col in range(self._game_state.show_cols()):
                if self._game_board[col][row] == ' ':
                    pass
                else:
                    canvas = tkinter.Canvas(master = self._root_window, width = 100, height = 100, 
                        borderwidth = 0, highlightthickness = 1,
                        background = _BACKGROUND_COLOR, highlightbackground = 'black')
                    canvas.grid(row = row, column = col, padx = 0, pady = 0,
                        sticky = tkinter.N + tkinter.S + tkinter.E + tkinter.W)
                    canvas.update()
                    canvas.create_oval(2, 2, canvas.winfo_width() - 2,
                        canvas.winfo_height() - 2, fill = self._which_color(col,
                        row), outline = self._which_color(col, row))
                    self._root_window.rowconfigure(row, weight = 1)
                    self._root_window.columnconfigure(col, weight = 1)



    def display_turn(self) -> None:
        if self._game_state.show_turn() == 'B':
            turn = 'black'
        else:
            turn = 'white'
        self._turn_window.grid(row = self._game_state.show_rows() // 2 - 1, 
            column = self._game_state.show_cols() + 1,
            sticky = tkinter.N + tkinter.S + tkinter.E + tkinter.W)
        self._turn_info = self._turn_window.create_text(10, 10, 
            font = 'Helvetica', anchor = 'nw')
        self._turn_window.itemconfig(self._turn_info, text = 'Turn = ' + turn)



    def on_resize(self, event: tkinter.Event) -> None:
        self.draw_game_pieces()



    def _which_color(self, col: int, row: int) -> str:
        if self._game_board[col][row] == 'B':
            return 'black'
        elif self._game_board[col][row] == 'W':
            return 'white'



    def _on_canvas_clicked(self, event: tkinter.Event) -> (int):
        print(event.widget.winfo_reqwidth(), event.widget.winfo_reqheight())
        print(event.widget.winfo_width(), event.widget.winfo_height())
        try:
            grid_info = event.widget.grid_info()
            move = (int(grid_info["row"]), int(grid_info["column"]))
            self._game_state.player_move(move[1], move[0])
            self.draw_game_pieces()
            self.display_turn()
        except AttributeError:
            pass
        except othello.InvalidMoveError:
            print('Error: that wasn\'t a valid move.')
        except othello.GameOverError:
            print('The game is over.')



    def start(self) -> None:
        self.draw_game_pieces()
        self.display_turn()
        self._root_window.mainloop()
class Otherlo应用程序:
定义初始(自我,游戏状态:Otherlo.Otherlo):
自我。\游戏\状态=游戏\状态
self._game_state.new_game()
self.\u game\u board=game\u state.show\u board()
self.\u root\u window=tkinter.Tk()
对于范围内的行(self.\u game\u state.show\u rows()):
对于范围内的列(self.\u game\u state.show\u cols()):
canvas=tkinter.canvas(自根窗口,宽度=100,高度=100,
borderwidth=0,highlightthickness=1,
背景=\背景\颜色,强光背景='黑色')
网格(行=行,列=列,padx=0,pady=0,
粘性=tkinter.N+tkinter.S+tkinter.E+tkinter.W)
self.\u root\u window.rowconfigure(行,权重=1)
self.\u root\u window.columnconfigure(列,权重=1)
self.\u turn\u window=tkinter.Canvas(self.\u root\u window,宽度=200,
高度=100,高光厚度=0,背景='白色')
self.\u root\u window.bind(“”,在画布上单击self.\u)
self.\u root\u window.bind(“”,self.on\u resize)
def draw_game_碎片(自身)->无:
对于范围内的行(self.\u game\u state.show\u rows()):
对于范围内的列(self.\u game\u state.show\u cols()):
如果自选游戏棋盘[col][row]='':
通过
其他:
canvas=tkinter.canvas(master=self.\u root\u窗口,宽度=100,高度=100,
borderwidth=0,highlightthickness=1,
背景=\背景\颜色,强光背景='黑色')
网格(行=行,列=列,padx=0,pady=0,
粘性=tkinter.N+tkinter.S+tkinter.E+tkinter.W)
canvas.update()
canvas.create_oval(2,2,canvas.winfo_width()-2,
canvas.winfo\u height()-2,fill=self.\u哪个颜色(col,
行),轮廓=自身颜色(列,行))
self.\u root\u window.rowconfigure(行,权重=1)
self.\u root\u window.columnconfigure(列,权重=1)
def显示\ U形转弯(自)->无:
如果self.\u game\u state.show\u turn()=“B”:
转弯=‘黑色’
其他:
转向=‘白色’
self.\u turn\u window.grid(row=self.\u game\u state.show\u rows()//2-1,
column=self.\u game\u state.show\u cols()+1,
粘性=tkinter.N+tkinter.S+tkinter.E+tkinter.W)
self.\u turn\u info=self.\u turn\u窗口。创建文本(10,10,
字体='Helvetica',锚点='nw')
self.\u turn\u window.itemconfig(self.\u turn\u info,text='turn='+turn)
def on_resize(自身,事件:tkinter.event)->无:
赛尔夫。抽签
def _哪个颜色(self,col:int,row:int)->str:
如果self.\u game\u board[col][row]=“B”:
返回“黑色”
elif self._game_board[col][row]=“W”:
返回“白色”
在画布上单击定义(self,事件:tkinter.event)->(int):
打印(event.widget.winfo_reqwidth(),event.widget.winfo_reqheight())
打印(event.widget.winfo_width(),event.widget.winfo_height())
尝试:
grid\u info=event.widget.grid\u info()
移动=(int(网格信息[“行])、int(网格信息[“列]))
自我。\游戏\状态。玩家\移动(移动[1],移动[0])
赛尔夫。抽签
self.display_turn()
除属性错误外:
通过
除Otherlo.InvalidMoveError外:
打印('错误:这不是有效的移动')
除了奥赛罗。加梅奥菲尔外:
打印('游戏结束')
def启动(自)->无:
赛尔夫。抽签
self.display_turn()
self.\u root\u window.mainloop()
draw\u game\u parties()
方法根据要绘制的画布的大小,在棋盘上正确的空间中绘制相应颜色的圆圈

我的调整大小问题的解决方案是将_resize()上的
绑定到init方法中的
'
事件,但这会导致程序在递归循环中崩溃。我对tkinter和GUIs都是新手。为什么将
on_resize()
方法绑定到
'
会导致程序崩溃

对不起,代码太乱了,我还在努力


谢谢。

递归导致的崩溃可能是因为您的
on\u resize
方法创建了新的小部件。下面是正在发生的事情:

  • 小部件获取一个事件,该事件
  • 调用_resize哪个
  • 创建一个嵌套循环,其中
  • 创建一个画布,其中
  • 导致小部件中的配置更改
  • 在嵌套循环中调用update,该循环
  • 导致事件被处理,这
  • 调用_resize,这
  • 创建一个嵌套循环,其中
  • 创建一个画布,其中
  • 导致小部件中的配置更改
  • 在嵌套循环中调用update,该循环
  • 导致事件被处理,这
  • 调用_resize,这
  • 根据经验,除非你绝对确定你需要更新,否则你不应该调用update,即使这样,你也需要停下来仔细考虑一下。一个几乎永远不会被打破的规则是在func中调用update