错误“不能在内部使用几何管理器包它已经有由网格管理的从属”

问题描述

所以我试图让用户上传一个标志的图像文件,然后将其打包到框架中。但是我收到以下错误消息 cannot use geometry manager pack inside . which already has slaves managed by grid 我不明白为什么会发生这种情况,因为我在同一帧中有大量使用 .pack 的其他小部件。我曾尝试在框架上使用 .pack 但我遇到了另一个问题,即我的程序崩溃了。 这是代码

# Imports
from tkinter import * # Tkinter is a GUI toolkit used for Python. This toolkit allows me to create the window and many of the UI options
import Pmw # Pmw stands for 'Python mega widgets'. I imported this primarily for tooltips so the user kNows what everything means
from PIL import ImageTk,Image
from tkinter import filedialog

# Windows
root = Tk() # Root is the main window where I will be putting everything
root.title('Nation Creator') # The title is the text at the top of every window
root.state('zoomed') # This makes the window go full screen
#Fonts
titlefont = ("Aldrich",48)
subtitlefont = ("Aldrich",22)
font = ("Times New Roman",14)

#lists
hosl = ["Elected Monarch","Hereditary Monarch","Elected President","Oligarchy"] #These are the four types of heads of state.
# Functions

#This is so that the user can scroll thru the next frame.
def nextframe(frame):
    frame.tkraise()

# Making the frames
def frameMaker():
    frameName = Frame(root)
    frameName.grid(row=0,column=0,sticky='nsew')
    return frameName

# This is what makes my Titles
def titleMaker(titleText,descriptionText,frame):
    title = Label(frame,text = titleText)
    title.configure(font=(titlefont))
    title.pack()
    description = Label(frame,text = descriptionText)
    description.configure(font=(subtitlefont))
    description.pack()
    return title,description

# Here I am making my spaces. It gives a better asthetic look.
def spaceMaker(spaceName,frame):
    spaceName = Label(frame,text="")
    spaceName.pack()
    return spaceName

#This opens a file browser so you can select your flag
def flagOpener():
        global flagIMG
        global flagLabel
        flagPath = filedialog.askopenfilename(initialdir="/",title="Select an Image File",filetypes=(("Png Files","*.png"),("Jpeg Files","*.jpg; *.jpeg"),("All Files","*.*")))
        flagIMG = ImageTk.PhotoImage(Image.open(flagPath))
        flagLabel = Label(image=flagIMG)
        flagLabel.pack()
        return flagIMG,flagLabel
#######################################################
#######################FRAMES##########################
#######################################################

# These two commands allow the different frames to work
root.rowconfigure(0,weight=1)
root.columnconfigure(0,weight=1)
# There will be 4 different frames.
titleframe = frameMaker()
politicalframe = frameMaker()
econframe = frameMaker()
miscframe = frameMaker()

for frame in (titleframe,politicalframe,econframe,miscframe):
    frame.grid(row=0,sticky='nsew')

nextframe(titleframe)
# Section headings
# These will be the headings for the sections.
# There will be 4 sections; Title Section,Political,Economic,and MicellanIoUs 

titleMaker("Nation Creator","Version 1.0",titleframe)
startbutton = Button(titleframe,text = "Begin",command=lambda:nextframe(politicalframe))
startbutton.pack()

#Political Section

titleMaker("Political Section","This is where your nation's name,flag,territory,\nand political and personal freedoms are entered.",politicalframe)

spaceMaker("pOne",politicalframe)

nationNamePrompt = Label(politicalframe,text = "Enter your nation's name:")
nationNamePrompt.configure(font = (font))
nationNamePrompt.pack()
nationNameInput = Entry(politicalframe)
nationNameInput.configure(font=(font))
nationNameInput.pack()

spaceMaker("pTwo",politicalframe)

flagSelect = Button(politicalframe,text = "Select Flag",command=flagOpener)
flagSelect.pack()


spaceMaker("pThree",politicalframe)

territoryPrompt = Label(politicalframe,text = "List Your Territory")
territoryPrompt.configure(font=(font))
territoryPrompt.pack()
territoryButton = Entry(politicalframe)
territoryButton.configure(font=(font))
territoryButton.pack()

spaceMaker("pFour",politicalframe)

headOfStateVar = StringVar(politicalframe)
headOfStateVar.set("Select Head of State")
headOfStateType = OptionMenu(politicalframe,headOfStateVar,*hosl)
headOfStateType.pack()

spaceMaker("pFive",politicalframe)

headOfStateNamePrompt = Label(politicalframe,text = "What is the name of your head of state?")
headOfStateNamePrompt.configure(font=(font))
headOfStateNamePrompt.pack()
headOfStateName = Entry(politicalframe)
headOfStateName.configure(font=(font))
headOfStateName.pack()

spaceMaker("pSix",politicalframe)

polcontbutton = Button(politicalframe,text = "Next",command=lambda:nextframe(econframe))
polcontbutton.pack()
#Economic Section 
titleMaker("Economic Section","This is where your economic freedoms and control are entered.",econframe)

econbackbutton = Button(econframe,text = "Back",command=lambda:nextframe(politicalframe))
econbackbutton.pack()

# Making sure the window will stay up
root.mainloop()

解决方法

在您的 flagOpener() 函数中:

def flagOpener():
        global flagIMG
        global flagLabel
        flagPath = filedialog.askopenfilename(initialdir="/",title="Select an Image File",filetypes=(("Png Files","*.png"),("Jpeg Files","*.jpg; *.jpeg"),("All Files","*.*")))
        flagIMG = ImageTk.PhotoImage(Image.open(flagPath))
        flagLabel = Label(image=flagIMG)
        flagLabel.pack()
        return flagIMG,flagLabel

您没有为 flagLabel 指定父级。 Tkinter 使用了 master 的默认选项 root,但您在这里使用了 grid 管理器作为 root:

def frameMaker():
    frameName = Frame(root)
    frameName.grid(row=0,column=0,sticky='nsew')
    return frameName

这里:

titleframe = frameMaker()
politicalframe = frameMaker()
econframe = frameMaker()
miscframe = frameMaker()

for frame in (titleframe,politicalframe,econframe,miscframe):
    frame.grid(row=0,sticky='nsew')

Tkinter 不允许您对同一个框架/窗口使用不同的管理器。另外,为什么要为 .grid 调用两次 (titleframe,miscframe) 方法?一旦进入 frameMaker 函数,然后再次进入 for 循环。你不应该那样做。