【问题标题】:tkinter image not loading, tclerrortkinter 图像未加载,tclerror
【发布时间】:2022-01-04 00:36:04
【问题描述】:

我会尽力解释这一点。短篇小说,为学校项目制作井字游戏。我认为我拥有所有必要的代码,但是当我运行我的代码时,tkinter 窗口打开没有问题,但是当我单击其中一个可以放置“x”或“o”的方块时,我的图像不会加载进入网格。

当我点击时,这是弹出的错误之一: 第 2776 行,在 _create 返回 self.tk.getint(self.tk.call( _tkinter.TclError:未知选项“562.5”

如果我猜的话,错误一定在“def draw_o”和“def draw_x”中

如果您想尝试这里的代码,请下载图片:https://imgur.com/a/kKJPIop

如果有相关的作业图片:https://imgur.com/a/3iu4MJy

from math import log
from tkinter import *
import numpy as np

size = 600
symbol_size = (size / 3 - size / 8) /2
symbol_thick = 50
symbol_x_color = '#EE4035'
symbol_o_color = '#0492CF'
green = '#7BC043'



class cell:

    def __init__(self):
        self.window = Tk()
        self.window.title("Bondesjakk/Tic Tac Toe")
        self.canvas = Canvas(self.window, width = size, height = size)
        self.canvas.pack()
        self.window.bind("<Button-1>", self.click)

        

        self.initialize_board()
        self.player_x_turns = True
        self.board_status = np.zeros(shape=(3, 3) )

        self.player_x_starts = True
        self.reset_board = False
        self.gameover = False
        self.tie = False
        self.x_wins = False
        self.o_wins = False

        self.x_score = False
        self.o_score = False
        self.tie_score = False

        
    
    def mainloop(self):
        self.window.mainloop()
    
    def initialize_board(self):
        for i in range(2):
            self.canvas.create_line( (i + 1) * size / 3, 0, (i + 1) * size / 3, size)
        
        for i in range(2):
            self.canvas.create_line(0, (i + 1) * size / 3, size, (i + 1) * size / 3)

    def play_again(self):
        self.initialize_board()
        self.player_x_starts = not self.player_x_starts
        self.player_x_turns = self.player_x_starts
        self.board_status = np.zeros(shape =(3, 3) )

    def draw_o(self, logical_pos):
        o_image = PhotoImage('book/pybook/image/o.gif')
        logical_pos = np.array(logical_pos)
        grid_pos = self.convert_logical_to_grid_pos(logical_pos)
        self.canvas.create_image(grid_pos[0] - symbol_size, grid_pos[1] - symbol_size,
                                 grid_pos[0] + symbol_size, grid_pos[1] + symbol_size, width = symbol_thick,
                                 image = o_image)
    
    def draw_x(self, logical_pos):
        x_image = PhotoImage('book/pybook/image/x.gif') 
        grid_pos = self.convert_logical_to_grid_pos(logical_pos)
        self.canvas.create_image(grid_pos[0] - symbol_size, grid_pos[1] - symbol_size,
                                 grid_pos[0] + symbol_size, grid_pos[1] + symbol_size, width = symbol_thick,
                                 image = x_image)
    
    def display_gameover(self):

        if self.x_wins:
            self.x_score += 1
            text = "Winner: Player 1(x)"
            color = symbol_x_color

        elif self.o_wins:
            self.o_score += 1
            text = "Winner: Player 2(o)"
            color = symbol_o_color
        
        else:
            self.tie_score += 1
            text = "It's a tie"
            color = "gray"

        self.canvas.delete("all")
        self.canvas.create_text(size / 2, size / 3, font = "cmr 60 bold", fill = color, text = text)

        score_text = 'Scores \n'
        self.canvas.create_text(size / 2, 5 * size / 8, font = "cmr 40 bold", fill = green, text = score_text)

        score_text = 'Player 1 (x) : ' + str(self.x_score) + '\n'
        score_text = 'Player 2 (o) : ' + str(self.o_score) + '\n'
        score_text = 'Tie          : ' + str(self.tie_score) + '\n'

        self.canvas.create_text(size / 2, 3 * size / 4, font = "cmr 30 bold", fill = green, text = score_text)

        self.reset_board = True

        score_text = "Click to play again \n"
        self.canvas.create_text(size / 2, 15* size / 16, font = "cmr 20 bold", fill = "gray", text = score_text)

    def convert_logical_to_grid_pos(self, logical_pos):
        logical_pos = np.array(logical_pos, dtype = int)
        return (size / 3) * logical_pos + size / 6
    
    def convert_grid_to_logical_pos(self, grid_pos):
        grid_pos = np.array(grid_pos)
        return np.array(grid_pos // (size / 3), dtype = int)
    
    def is_grid_occupied(self, logical_pos):
        if self.board_status[logical_pos[0] ][logical_pos[1] ] == 0:
            return False
        else:
            return True
    
    def is_winner(self, player):
        player = -1 if player == "x" else 1

        #Three in a row
        for i in range(3):
            if self.board_status[i][1] == self.board_status[i][2] == player:
                return True
            if self.board_status[0][1] == self.board_status[2][i] == player:
                return True
        
        #Diagonals
        if self.board_status[0][0] == self.board_status[1][1] == self.board_status[2][2] == player:
            return True
        if self.board_status[2][0] == self.board_status[1][1] == self.board_status[0][2] == player:
            return True

        return False
    
    def is_tie(self):
        r, c = np.where(self.board_status == 0)
        tie = False
        if len(r) == 0:
            tie = True
        
        return tie

    def is_gameover(self):
        self.x_wins = self.is_winner("x")
        if not self.x_wins:
            self.o_wins = self.is_winner("o")

        if not self.o_wins:
            self.tie = self.is_tie()
        
        gameover = self.x.wins or self.o.wins or self.tie

        if self.x_wins:
            print("x wins!")
        if self.o_wins:
            print("o wins!")
        if self.tie:
            print("It's a tie!")
        
        return gameover
    
    def click(self, event):
        grid_pos = [event.x, event.y]
        logical_pos = self.convert_grid_to_logical_pos(grid_pos)

        if not self.reset_board:
            if self.player_x_turns:
                if not self.is_grid_occupied(logical_pos):
                    self.draw_x(logical_pos)
                    self.board_status[logical_pos[0] ][logical_pos[1] ] = -1
                    self.player_x_turns = not self.player_x_turns
            
            else:
                if not self.is_grid_occupied(logical_pos):
                    self.draw_o(logical_pos)
                    self.board_status[logical_pos[0] ][logical_pos[1] ] = 1
                    self.player_x_turns = not self.player_x_turns
            
            if self.gameover():
                self.display_gameover()
        else:
            self.canvas.delete("all")
            self.play_again()
            self.reset_board = False

game_instance = cell()
game_instance.mainloop()

【问题讨论】:

  • 如果您提供minimal reproducible example 会更有帮助。如果代码行数尽可能少,则更容易找出问题
  • 始终将完整的错误消息(从单词“Traceback”开始)作为文本(不是屏幕截图,不是指向外部门户的链接)(不是在 cmets 中)。还有其他有用的信息。
  • 完整的错误信息应该告诉你在哪一行你有问题,首先你可以使用print()来查看你在变量中的内容。它被称为"print debuging"。似乎您在某些变量中有错误的值或以错误的方式使用它。它显示选项 "562.5" 的问题 - 所以可能不是 var="562.5" 它得到类似 "562.5"=var

标签: python python-3.x image tkinter


【解决方案1】:

create_image() 中,您使用x1, y1, x2, y2, width=...,但它只希望将位置(x1,y1) 作为元组(没有x2,y2)并且没有width=...

        x = grid_pos[0] - symbol_size
        y = grid_pos[1] - symbol_size
        self.canvas.create_image( (x, y), image=x_image)

编辑:

你还有其他错误

if self.gameover() 行中,您必须删除()

--

如果您使用PhotoImage('book/pybook/image/o.gif'),那么它会将其视为带有图像数据的字符串,而不是文件路径。你必须使用file=

o_image =  PhotoImage(file='book/pybook/image/o.gif')

--

但是还有另一个问题。 PhotoImage 中有一个错误,当图像被分配给函数中的局部变量时,它会从内存中删除图像。您应该使用self. 分配给类变量

self.o_image =  PhotoImage(file='book/pybook/image/o.gif')

--

这里还有另一个问题。您一次又一次地加载相同的图像并将其分配给相同的变量 - 所以bug 会从内存中删除之前的图像并将其从canvas 中删除。

您只能在 __init__ 中加载一次,然后在以后一直使用相同的 self.o_imageself.x_image

def __init___(...):

    self.o_image =  PhotoImage(file='book/pybook/image/o.gif')
    self.x_image =  PhotoImage(file='book/pybook/image/x.gif')

文档(effbot.org in archive.org):PhotoImage, Canvas

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-11-04
    • 2019-04-30
    • 2016-08-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-25
    相关资源
    最近更新 更多