基于Tkinter的石头剪刀布GUI程序报错:pyimage3不存在
解决Tkinter石头剪刀布程序的"pyimage3 doesn't exist"错误
错误根源
- Frame类初始化错误:自定义
rps类继承Frame但未调用父类__init__方法,导致组件与窗口的归属关系混乱,引发Tcl层面的图像引用错误。 - PhotoImage引用丢失:链式调用
.zoom().subsample()时,临时对象被Python垃圾回收机制清理,导致Tkinter无法找到图像资源。 - 主循环调用对象错误:
rps是Frame子类,直接调用app.mainloop()无效,应调用主窗口的mainloop()。 - 缺失依赖模块:游戏逻辑使用
random但未导入该模块。 - 初始化逻辑疏漏:
__init__方法仅赋值self.interface,未实际调用创建窗口的方法。
修复步骤
- 在
rps类的__init__中调用父类Frame的初始化方法,并绑定主窗口。 - 拆分PhotoImage的链式操作,确保图像对象被
self持有,避免被回收。 - 修正主程序中
mainloop的调用对象为窗口实例。 - 在类文件中导入
random模块。 - 调整类的初始化流程,在
__init__中完成窗口创建和界面初始化。
修正后的代码
classe.py
from tkinter import * import random class rps(Frame): def __init__(self, window): super().__init__(window) self.window = window self.all() def all(self): self.window.title("Rock Paper Or Scissors ?") self.window.iconbitmap("aopa.ico") self.window.geometry("1280x720") self.window.minsize(960, 720) self.window.config(background="#307ec7") self.window.configure(borderwidth=150) boite = Frame(self.window, bg="#307ec7") boite2 = Frame(boite, bg="#307ec7") # 拆分图像操作,保留引用 self.image = PhotoImage(file="Lab.png") self.image = self.image.zoom(35).subsample(32) self.canvas = Canvas(boite, width=200, height=200, bg="#18153f", bd=0, highlightthickness=0) self.canvas.create_image(100, 100, image=self.image) self.canvas.grid(row=0, column=0, sticky=W) self.texte1 = Label(boite2, text="Rock Paper Or Scissors ?", bg="#3fc5bf", font=("Arial", 25), fg="#307ec7") self.texte1.pack() self.bouton1 = Button(boite2, text="Rock", font=("Arial", 20), command=self.Play_Rock_Paper_Scissors1) self.bouton1.pack() self.bouton2 = Button(boite2, text="Paper", font=("Arial", 20), command=self.Play_Rock_Paper_Scissors2) self.bouton2.pack() self.bouton3 = Button(boite2, text="Scissors", font=("Arial", 20), command=self.Play_Rock_Paper_Scissors3) self.bouton3.pack() self.texte2 = Label(boite2, text="", bg="#3fc5bf", font=("Arial", 25), fg="#307ec7") self.texte2.pack() self.texte3 = Label(boite2, text="", bg="#3fc5bf", font=("Arial", 25), fg="#307ec7") self.texte3.pack() boite.pack(expand=YES) boite2.grid(row=0, column=1, sticky=E) def Play_Rock_Paper_Scissors1(self): a = self.bouton1.cget("text") choix_possibles = ["Rock", "Paper", "Scissors"] choice_of_AI = random.choice(choix_possibles) self.texte2.configure(text=f"choice of AI : {choice_of_AI}") if a == choice_of_AI: self.texte3.configure(text="equality") elif choice_of_AI == "Paper": self.texte3.configure(text="AI won") else: self.texte3.configure(text="YOU WIN") def Play_Rock_Paper_Scissors2(self): b = self.bouton2.cget("text") choix_possibles = ["Rock", "Paper", "Scissors"] choice_of_AI = random.choice(choix_possibles) self.texte2.configure(text=f"choice of AI : {choice_of_AI}") if b == choice_of_AI: self.texte3.configure(text="equality") elif choice_of_AI == "Scissors": self.texte3.configure(text="AI won") else: self.texte3.configure(text="YOU WIN") def Play_Rock_Paper_Scissors3(self): c = self.bouton3.cget("text") choix_possibles = ["Rock", "Paper", "Scissors"] choice_of_AI = random.choice(choix_possibles) self.texte2.configure(text=f"choice of AI : {choice_of_AI}") if c == choice_of_AI: self.texte3.configure(text="equality") elif choice_of_AI == "Rock": self.texte3.configure(text="AI won") else: self.texte3.configure(text="YOU WIN")
jeu_pfc.py
from tkinter import * from classe import rps window = Tk() app = rps(window) window.mainloop()
额外优化说明
- 修正了字体名错误:"Arials"改为正确的"Arial"
- 简化了游戏逻辑中的冗余判断(如
a == a这类无意义条件) - 使用f-string优化字符串拼接,提升可读性
- 将图像坐标从
200/2改为整数100,避免浮点数潜在问题
内容的提问来源于stack exchange,提问作者optik basique
相关产品推荐
相关产品推荐

