【问题标题】:tkinter PIL image is not shown up in classtkinter PIL 图像未在课堂上显示
【发布时间】:2018-10-03 08:43:47
【问题描述】:

我无法在 tkinter PIL 类中显示图像。 图像已成功打包或放置,但未显示。 没有显示windowxp 墙纸和男人的脸。 单击他的脸时,我制作了消息框。 因此,如果我单击该位置,则会显示消息框。但是图片没有显示出来。只是位置:( 我使用 Windows 64 位和 Python 3.6 我是韩国人。我不擅长英语....请理解我。 请帮帮我

这是正确的显示:screenshot

from tkinter import *
import tkinter as tk
from tkinter import messagebox
from PIL import Image, ImageTk

    ##함수
class Mainwindow(tk.Tk):

    def __init__(self, *args, **kwargs):

        tk.Tk.__init__(self, *args, **kwargs)
        self.title("김상곤이 좋아하는 꿈꾸는 학과 과목 문제 맞추기♡")
        self.geometry("1600x900")
        self.resizable(width=FALSE, height=FALSE)


        wall = tk.PhotoImage(file="gif/bg.gif")
        labelwall = tk.Label(self, image = wall)
        labelwall.place(x=0, y=0)

        container = tk.Frame(self)
        container.pack(side="top", fill="both", expand=True)
        container.grid_rowconfigure(0, weight=1)
        container.grid_columnconfigure(0, weight=1)

        def func_make():
            messagebox.showinfo("제작자", "김재온, 정성윤, 안예진, 이소유, 우연서")

        def func_exit():
            window.quit()
            window.destroy()

        mainMenu=Menu(self)
        fileMenu=Menu(mainMenu)
        self.config(menu=mainMenu)
        mainMenu.add_cascade(label="파일", menu=fileMenu)
        fileMenu.add_command(label="제작자", command=func_make)
        fileMenu.add_separator()
        fileMenu.add_command(label="종료", command=func_exit)

        self.frames={}
        for F in (MainPage, QuizPage):
            page_name=F.__name__
            frame = F(parent=container, controller=self)
            self.frames[page_name]=frame

            frame.grid(row=0, column=0, sticky="nsew")

        self.show_frame("MainPage")

    def show_frame(self, page_name):

        frame = self.frames[page_name]
        frame.tkraise()

    def 국어():

        page == 1

    subject=['국어', '과학', '역사', '사회', '기술']  

#색이나 위치 숫자 설정

mint="#99FFFF"
subjectsize=30
subjectbutton=60

##위젯

class MainPage(tk.Frame):

    def __init__(self, parent, controller):

        tk.Frame.__init__(self, parent)
        self.controller=controller
        def clickksk(event):
                messagebox.showinfo("김상곤", "아주 좋아요^^")

        labeltitle=tk.Label(self, text=
                            """김상곤이 좋아하는 꿈꾸는
학과 과목 문제 맞추기♡""", font=("궁서체", 35), bg="#8DFD73")

        ksk=tk.PhotoImage(file="gif/ksk.gif")
        labelksk=tk.Label(self, image=ksk)                           

        labelksk.place(x=400-subjectbutton, y=200)
        labelksk.bind("<Button>", clickksk)
        labelhow=tk.Label(self, text="게임방법!                   ", font=("맑은 고딕", 30), bg="#FFE400")
        labelexplain=tk.Label(self, text=
        """원하는 과목을 택해 클릭한후,
        OX퀴즈를 풀면 됩니다^^
        난이도=중3""", font=("고딕체", 25), bg="#FFE400")   

        btKorean=tk.Button(self, text="국어", font=("양재블럭체", subjectsize), bg=mint,
                        command=lambda: controller.show_frame("QuizPage"))

        btScience=tk.Button(self, text="과학", font=("양재블럭체", subjectsize), bg=mint)
        btHistory=tk.Button(self, text="역사", font=("양재블럭체", subjectsize), bg=mint)
        btSocial=tk.Button(self, text="사회", font=("양재블럭체", subjectsize), bg=mint)
        bttech=tk.Button(self, text="기술", font=("양재블럭체", subjectsize), bg=mint)

        ##pack하는 장소(코드 순차대로)

        labeltitle.place(relx= 0.25, rely=0.02, relwidth=0.5)
        labelhow.place(x=610-subjectbutton, y=200, relwidth=0.3)
        labelexplain.place(x=610-subjectbutton, y=260, relwidth=0.3)

        btKorean.place(x=400-subjectbutton, y=600)
        btScience.place(x=600-subjectbutton, y=600)
        btHistory.place(x=800-subjectbutton, y=600)
        btSocial.place(x=1000-subjectbutton, y=600)
        bttech.place(x=1200-subjectbutton, y=600)

        btKorean.bind("<Button-1>")
        btScience.bind("<Button-1>")
        btHistory.bind("<Button-1>")
        btSocial.bind("<Button-1>")
        bttech.bind("<Button-1>")

class QuizPage(tk.Frame):
    def __init__(self, parent, controller):

        OB=PhotoImage(file="gif/OB.gif")
        XR=PhotoImage(file="gif/XR.gif")

        tk.Frame.__init__(self, parent)
        self.controller = controller
        buttonOB=Button(self, image=OB)
        buttonXR=Button(self, image=XR)

        buttonOB.place()
        buttonXR.place()         

if __name__ == "__main__":
    app = Mainwindow()
    app.mainloop()

【问题讨论】:

  • 您不应该两次导入 tkinter。这条线from tkinter import *...我认为你应该放手。
  • 我还想指出,使用place() 对可维护性和处理不同大小的屏幕非常不利。您真的应该在此处使用grid() 并定义小部件之间的适当间距,使其更具动态性。
  • 通常当我在 tkinter 中使用图像时,我需要让 python 知道它可以在本地目录中查找,购买在本地文件路径前放置 .。所以这个:"gif/bg.gif" 应该看起来像这样"./gif/bg.gif"

标签: python tkinter python-imaging-library


【解决方案1】:

我认为您的主要问题是您正在使用两个子类框架并使用网格来管理它们,但主应用程序窗口没有扩展网格区域。您需要将以下内容添加到MainWindow.__init__

self.grid_rowconfigure(0, weight=1)
self.grid_columnconfigure(0, weight=1)

使 (0,0) 单元格被扩展以填充所有可用空间。然后您当前选择的框架将扩展到该区域,因为它在网格方法调用中设置了sticky='NSWE'

在您定义container 的地方,您既是包装也是网格。你必须只使用一个。但是,这看起来像死代码。也许您打算一次将子类帧放入此容器中。

另外,你不能只打电话给buttonXR.place(),你需要给它一个位置。例如:buttonXR.place(x=1, y=1)

【讨论】: