PhotoImage在PIL-Python函数中的应用

PhotoImage在PIL-Python函数中的应用,python,python-3.x,tkinter,tkinter-canvas,Python,Python 3.x,Tkinter,Tkinter Canvas,我希望你们是小家伙 我是开发方面的新手,我正在尝试制作一个带有按钮和图片的窗口 但是我犯了一个错误,我不知道为什么。我在函数外部尝试过我的代码,它运行得很好,但当它在函数内部时,img似乎无法获得路径 这是我的密码: from tkinter import * import PIL.Image import PIL.ImageTk def MainScreen(): main_screen = Tk() main_screen.geometry("700x45

我希望你们是小家伙

我是开发方面的新手,我正在尝试制作一个带有按钮和图片的窗口

但是我犯了一个错误,我不知道为什么。我在函数外部尝试过我的代码,它运行得很好,但当它在函数内部时,img似乎无法获得路径

这是我的密码:

from tkinter import *
import PIL.Image
import PIL.ImageTk





def MainScreen():
    main_screen = Tk()
    main_screen.geometry("700x450")
    main_screen.title("Gestion")
    canvas = Canvas(main_screen)
    canvas.pack()
    image_info = PIL.Image.open(r"C:/Users/etc...")
    img = PhotoImage(width=700, height=450)
    image_info = image_info.resize((100, 100), PIL.Image.BOX)
    image = PIL.ImageTk.PhotoImage(image_info)
    PhotoImage(master=canvas, width=300, height=200)
    canvas.create_image((0, 0), anchor=NW, image=image)
    canvas.place(x=350, y=300)

def ConnexionMainScreen():
    receptusername = username.get()
    receptpassword = password.get()
    if receptusername == "D":
        if receptpassword == "A":
            MainScreen()
            login_screen.destroy()


def LoginScreen():
    global username
    global password
    global login_screen
    login_screen = Tk()
    login_screen.geometry("300x400")
    login_screen.title("Connexion")
    username = StringVar()
    password = StringVar()
    Label(login_screen, text="Page de connexion", bg="grey", width=20, height=2, font=("Calibri", 13)).pack()
    Label(login_screen, text='').pack()
    Label(login_screen, text="Identifiant").pack()
    Label(login_screen, text='').pack()
    Entry(login_screen, textvariable=username).pack()
    Label(login_screen, text='').pack()
    Label(login_screen, text="Mot de passe").pack()
    Label(login_screen, text='').pack()
    Entry(login_screen, textvariable=password).pack()
    Label(login_screen, text='').pack()
    Button(login_screen, text='Connexion',height = 2, command=ConnexionMainScreen).pack()
    login_screen.mainloop()


LoginScreen()
这里是错误

Exception in Tkinter callback
Traceback (most recent call last):
  File "Programs\Python\Python39\lib\tkinter\__init__.py", line 1885, in __call__
    return self.func(*args)
  File "PycharmProjects\pythonProject2\test connaissance2.py", line 28, in ConnexionMainScreen
    MainScreen()
  File "PycharmProjects\pythonProject2\test connaissance2.py", line 20, in MainScreen
    canvas.create_image((0, 0), anchor=NW, image=image)
  File "Programs\Python\Python39\lib\tkinter\__init__.py", line 2787, in create_image
    return self._create('image', args, kw)
  File "Programs\Python\Python39\lib\tkinter\__init__.py", line 2773, in _create
    return self.tk.getint(self.tk.call(
_tkinter.TclError: image "pyimage2" doesn't exist
谢谢你的帮助

两大问题:

  • 打开的Tk()实例不应超过一个。在打开第二个之前,您需要退出(而不仅仅是销毁)第一个

     if receptpassword == "A":
         login_screen.quit()
         MainScreen()
    
    或者(可能更好),您可以重新制作屏幕,而不是关闭屏幕并制作新屏幕

  • 您需要显式地保留图像对象。请参见此处的注释:

    def主屏幕():
    主屏幕=Tk()
    主屏幕几何(“700x450”)
    主屏幕标题(“手势”)
    画布=画布(主屏幕)
    canvas.pack()
    image\u info=PIL.image.open(r“C:/Users/etc.)
    image\u info=image\u info.resize((100100),PIL.image.BOX)
    image=PIL.ImageTk.PhotoImage(图像信息)
    canvas.create_image((0,0),anchor=NW,image=image)
    
    canvas.img=image#感谢您的知识!我有一个新的错误,我要自己解决它。再次感谢!使用
    login\u screen.quit()
    只会退出
    mainloop()
    ,但不会破坏
    login\u screen
    。因此,当执行
    MainScreen()
    时,由于
    Tk()
    的多个实例,将引发相同的异常。
     def MainScreen():
         main_screen = Tk()
         main_screen.geometry("700x450")
         main_screen.title("Gestion")
         canvas = Canvas(main_screen)
         canvas.pack()
         image_info = PIL.Image.open(r"C:/Users/etc...")
         image_info = image_info.resize((100, 100), PIL.Image.BOX)
         image = PIL.ImageTk.PhotoImage(image_info)
         canvas.create_image((0, 0), anchor=NW, image=image)
         canvas.img = image # <== code to keep the reference
         canvas.place(x=350, y=300)