python - _tkinter.TclError:无效的命令名称“.!canvas”
问题描述
我正在尝试制作游戏,但在我的游戏中加载视频时遇到了一些问题。我知道之前有人问过一些类似的问题,但我无法对我的问题得到满意的解释。这是我运行代码时遇到的错误:
Exception in Tkinter callback
Traceback (most recent call last):
File "C:\Users\jovan\AppData\Local\Programs\Python\Python38-32\lib\tkinter\__init__.py", line 1883, in __call__
return self.func(*args)
File "C:\Users\jovan\AppData\Local\Programs\Python\Python38-32\lib\tkinter\__init__.py", line 804, in callit
func(*args)
File "c:/Jovan/Pycharm Projects/school projects/main_game2.py", line 70, in update
canvas.create_image(0, 0, image = photo, anchor = NW)
File "C:\Users\jovan\AppData\Local\Programs\Python\Python38-32\lib\tkinter\__init__.py", line 2785, in create_image
return self._create('image', args, kw)
File "C:\Users\jovan\AppData\Local\Programs\Python\Python38-32\lib\tkinter\__init__.py", line 2771, in _create
return self.tk.getint(self.tk.call(
_tkinter.TclError: invalid command name ".!canvas"
问题似乎出现在函数中,intro()
但我似乎找不到原因的答案。为什么会这样?我该如何解决这个问题?我是新手,tkinter
所以请尽量保持简单。代码如下:'''
from tkinter import *
from tkinter import messagebox
from random import *
from PIL import ImageTk,Image
import cv2
root = Tk()
root.title("Captain!")
root.geometry("1280x720")
#root.geometry("660x560")
class Game :
def __init__(self):
self.m_cur = {1:["Military",50]}
self.c_cur = {1:["People's",50]}
self.r_cur = {1:["Research",50]}
self.i_cur = {1:["Industrial",50]}
self.p_cur = {1:["Research",50]}
def clear(self):
for widget in root.winfo_children():
widget.destroy()
def exit(self):
msg = messagebox.askquestion("Thank you for playing","Are you sure you want to exit?")
if msg == "yes" :
root.destroy()
else:
Game.main(self)
def start(self):
Label(root,text="Hello, what should we call you?",font=("segoe print",20)).grid(row=0,column=0)
name = Entry(root,width=20)
name.grid(row=1,column=0)
Button(root,text="Enter",font=("segoe print",20),command=lambda: Game.main(self)).grid(row=1,column=1)
self.name=name.get()
def main(self):
Game.clear(self)
Label(root,text="Welcome to the game",font=("segoe print",20)).grid(row=0,column=0)
Label(root,text='What do you want to do?',font=("segoe print",20)).grid(row=1,column=0)
qn_num = randint(1,3)
Button(root,text="Start Game",font=("segoe print",20),command=lambda: Game.intro(self,qn_num)).grid(row=2,column=0)
Button(root,text="Exit Game",font=("segoe print",20),command=lambda: Game.exit(self)).grid(row=3,column=0)
#resetting values of the variables
self.r_cur[1][1] = 50
self.c_cur[1][1] = 50
self.i_cur[1][1] = 50
self.m_cur[1][1] = 50
self.p_cur[1][1] = 50
def intro(self,qn_num):
Game.clear(self)
vid = cv2.VideoCapture("video.mp4")
width = vid.get(cv2.CAP_PROP_FRAME_WIDTH)
height = vid.get(cv2.CAP_PROP_FRAME_HEIGHT)
canvas = Canvas(root, width = width, height = height)
canvas.pack()
def get_frame():
ret,frame = vid.read()
if ret :
return(ret,cv2.cvtColor(frame,cv2.COLOR_BGR2RGB))
else :
return(ret,None)
def update():
ret,frame = get_frame()
if ret :
img = Image.fromarray(frame)
photo = ImageTk.PhotoImage(image=img)
canvas.create_image(0, 0, image = photo, anchor = NW)
canvas.image=photo
root.after(delay,update)
delay = 15
update()
Game.qn_func(self,qn_num)
def game_over(self,x_cur):
if x_cur[1][1]<=0 or x_cur[1][1]>=100 :
Game.clear(self)
Label(root,text=f"{x_cur[1][0]} faction rebelled").place(relx=0.4,rely=0.4)
Label(root,text="GAME OVER",font=("ariel",20)).place(relx=0.5,rely=0.5,anchor=CENTER)
Button(root,text="Continue",font=("segoe print",20),command=lambda: Game.main(self)).place(relx=0.37,rely=0.6)
def qn_func(self,qn_num) :
Game.clear(self)
with open("questions_file.txt") as q_file :
#reading the question, options, next qn numbers and the character name from the file
qn_list = q_file.readlines()
qn = qn_list[qn_num-1].strip().split("$")[1]
char_name = qn_list[qn_num-1].strip().split("$")[2]
qn1 = qn_list[qn_num-1].strip().split("$")[3]
qn2 = qn_list[qn_num-1].strip().split("$")[5]
n_qn1 = int(qn_list[qn_num-1].strip().split("$")[4])
n_qn2 = int(qn_list[qn_num-1].strip().split("$")[6])
#displaying the character name and the question as a label frame widget with character name as parent
label_frame = LabelFrame(root,text = char_name,font = ("segoe print",20))
label = Label(label_frame,text = qn,font = ("segoe print",20))
label_frame.place(relx=0.5,rely=0.5,anchor=CENTER)
label.pack()
#displaying the buttons on the screen
Button(root,text=qn1,command=lambda: Game.qn_func(self,n_qn1)).place(relx=0.2,rely=0.7,anchor=W,width=200,height=50)
Button(root,text=qn2,command=lambda: Game.qn_func(self,n_qn2)).place(relx=0.8,rely=0.7,anchor=E,width=200,height=50)
#running each variable through game_over to see if you are dead
Game.game_over(self,self.r_cur)
Game.game_over(self,self.c_cur)
Game.game_over(self,self.i_cur)
Game.game_over(self,self.m_cur)
Game.game_over(self,self.p_cur)
#defining the Doublevar variables
s_var1 = DoubleVar()
s_var2 = DoubleVar()
s_var3 = DoubleVar()
s_var4 = DoubleVar()
s_var5 = DoubleVar()
#setting the values in the scales
s_var1.set(self.r_cur[1][1])
s_var2.set(self.c_cur[1][1])
s_var3.set(self.i_cur[1][1])
s_var4.set(self.m_cur[1][1])
s_var5.set(self.p_cur[1][1])
#variables as scale widgets
scale1 = Scale(root,from_=100,to=0,orient=VERTICAL,sliderlength=10,variable=s_var1)
scale2 = Scale(root,from_=100,to=0,orient=VERTICAL,sliderlength=10,variable=s_var2)
scale3 = Scale(root,from_=100,to=0,orient=VERTICAL,sliderlength=10,variable=s_var3)
scale4 = Scale(root,from_=100,to=0,orient=VERTICAL,sliderlength=10,variable=s_var4)
scale5 = Scale(root,from_=100,to=0,orient=VERTICAL,sliderlength=10,variable=s_var5)
#opening images to be displayed under scales
img_r = ImageTk.PhotoImage(Image.open("project_pics\\research.PNG"))
img_c = ImageTk.PhotoImage(Image.open("project_pics\\com_ppl.PNG"))
img_i = ImageTk.PhotoImage(Image.open("project_pics\\money.PNG"))
img_m = ImageTk.PhotoImage(Image.open("project_pics\\military.PNG"))
img_p = ImageTk.PhotoImage(Image.open("project_pics\\productivity.PNG"))
#the label widgets for images
img_l1 = Label(root,image=img_r)
img_l2 = Label(root,image=img_c)
img_l3 = Label(root,image=img_i)
img_l4 = Label(root,image=img_m)
img_l5 = Label(root,image=img_p)
#saving a reference of images
img_l1.image = img_r
img_l2.image = img_c
img_l3.image = img_i
img_l4.image = img_m
img_l5.image = img_p
#displaying images
img_l1.grid(row=1,column=0)
img_l2.grid(row=1,column=1)
img_l3.grid(row=1,column=2)
img_l4.grid(row=1,column=3)
img_l5.grid(row=1,column=4)
#displaying the scale widgets on the screen
scale1.grid(row=0,column=0,padx=40,pady=10)
scale2.grid(row=0,column=1,padx=40,pady=10)
scale3.grid(row=0,column=2,padx=40,pady=10)
scale4.grid(row=0,column=3,padx=40,pady=10)
scale5.grid(row=0,column=4,padx=40,pady=10)
#disabling the scales
scale1.config(state=DISABLED)
scale2.config(state=DISABLED)
scale3.config(state=DISABLED)
scale4.config(state=DISABLED)
scale5.config(state=DISABLED)
with open("variables.txt") as v_file :
#reading values of variables from file
v_list = v_file.readlines()
self.r_cur[1][1] += int(v_list[qn_num-1].strip().split("$")[1])
self.c_cur[1][1] += int(v_list[qn_num-1].strip().split("$")[2])
self.i_cur[1][1] += int(v_list[qn_num-1].strip().split("$")[3])
self.m_cur[1][1] += int(v_list[qn_num-1].strip().split("$")[4])
self.p_cur[1][1] += int(v_list[qn_num-1].strip().split("$")[5])
#driver code
game = Game()
game.start()
root.mainloop()
'''
解决方案
你提到的问题,似乎有这个原因:
intro()
调用qn_func()
,调用clear()
。
clear()
销毁所有小部件,它们是根的孩子。
你的画布是根的一个孩子。
=> 下一次调用update()
找不到您的画布。
推荐阅读
- pandas - 基于特定条件的 Pandas 中的 Groupby 累积总和
- java - 使用带有 Node.js 的 aws-secretsmanager-jdbc 连接到 RDS?
- javascript - JS 中的范围导出
- firebase - 我如何将googleapis与flutter firebase一起使用
- javascript - ExpressJS将路由名称添加到静态文件路径的问题
- javascript - "" 将字符串解析为 json 时出错
- c++ - 使用继承和纯虚函数时出现“未定义引用”错误
- c++ - 在编译时获取给定类的基类的特征
- elasticsearch - Elasticsearch 中包含的反义词是什么?
- javascript - 接受不同的 html 模板数据作为 reactjs 组件的选项