python TKinter无效帧错误,窗口路径错误“,!框架”

iyfjxgzm  于 2023-06-20  发布在  Python
关注(0)|答案(1)|浏览(86)

我试图制作一个菜单系统来导航我的程序,我菜单系统中的所有其他选项都可以工作,除了“主页”,我只是想把我带回我原来的开始屏幕。我以为如果我在开始时将其设置为self.frame就可以工作了,它有我的开始屏幕的所有小部件,但我得到了错误:

File "Documents\Vocabulary Practice\rymn.py", line 152, in showFrame
    self.curr_frame.pack()
  File "C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.10_3.10.3056.0_x64__qbz5n2kfra8p0\lib\tkinter\__init__.py", line 2425, in pack_configure
    self.tk.call(
_tkinter.TclError: bad window path name ".!frame"

下面是我的代码:

import math
import tkinter as tk
from datetime import date
from datetime import datetime
from datetime import timedelta
import re
import pickle

class Item: 
    def __init__(self, item_name, item_definition):
        self.item_name = item_name
        self.item_definition = item_definition
        self.item_level = "0"
        self.date_to_review = 0 # string
        self.hour_to_review = 0 # int
    
    def __lt__(self, otherItem):
        return self.item_name < self.otherItem.item_name
    def __gt__(self, otherItem):
        return self.item_name > self.otherItem.item_name
    def __le__(self, otherItem):
        return self.item_name <= self.otherItem.item_name
    def __ge__(self, otherItem):
        return self.item_name >= self.otherItem.item_name
    def __ne__(self, otherItem):
        return self.item_name != self.otherItem.item_name
    def __eg__(self, otherItem):
        return self.item_name == self.otherItem.item_name
    def __repr__(self) -> str:
        return f"term: {self.item_name}, defn: {self.item_definition}, dateReview: {self.date_to_review}, hourToReview: {self.hour_to_review}, level: {self.item_level}"

class MainGUI:
    def __init__(self):
        global allTerms
        global itemFinder
        with open("allTermsOut", "rb") as infile:
            allTerms = pickle.load(infile)
        with open("itemFinderOut", "rb") as infile:
            itemFinder = pickle.load(infile)

        self.t_entry = None
        self.d_entry = None
        self.curr_frame = None      

        #GUI Start
        self.root = tk.Tk()
        self.term_entry = tk.StringVar()
        self.defn_entry = tk.StringVar()

        self.root.geometry("750x750")
        self.root.title("Rymn")

        #menu bar
        
        
        # starting screen
        self.frame = tk.Frame(self.root)

        #prompt
        self.prompt = tk.Label(self.frame, text = "What would you like to do?", font = ('Arial', 18))
        self.prompt.pack(padx = 10, pady = 10)
        # review button
        practiceButton = tk.Button(self.frame, text = f"Practice terms", font = ('Arial, 20'), command=self.startPractice)
        practiceButton.grid(row = 0, column=0)
        #add button
        addItems = tk.Button(self.frame, text = "Add Items", font = ('Arial', 20), command= self.addItem)
        addItems.grid(row= 0, column= 1, padx = 10)
        #delete button
        deleteItems = tk.Button(self.frame, text = "Delete Items", font = ('Arial', 20), command = self.deleteItems)
        deleteItems.grid(row=0,column=2)
        self.frame.pack()
        
        # Menu stuff
        self.frames2 = [None, None, None] # creating separate frames
        self.frames = [self.addItem, self.deleteItems, self.startPractice] # storing function for separate frames
        #menu bar
        menubar = tk.Menu(self.root)
        self.root.config(menu=menubar)
        #filemenu stuff
        filemenu = tk.Menu(menubar, tearoff = 0)
        filemenu.add_command(label = "Home", command = lambda: self.showFrame('home'))
        filemenu.add_command(label = "Reviews Terms", command=lambda: self.showFrame('review'))
        filemenu.add_command(label = "Add Terms", command= lambda: self.showFrame('add'))
        filemenu.add_command(label = "Delete Terms", command= lambda: self.showFrame('delete'))
        menubar.add_cascade(label="Go To", menu = filemenu, underline = 0)
        
        self.root.mainloop()

    def showFrame(self, frameToDisplay):
        if self.curr_frame:
            self.curr_frame.pack_forget()
        match frameToDisplay:
                case 'add':
                    self.curr_frame = self.frames[0]()
                case 'delete':
                    self.curr_frame = self.frames[1]()
                case 'review':
                    self.curr_frame = self.frames[2]()
                case 'home':
                    self.curr_frame = self.frame
        self.curr_frame.pack()
        

    def clearFrame(self):
        self.prompt.destroy()
        if self.curr_frame:
            self.curr_frame.destroy()
        self.frame.destroy()
def startPractice(self):
        self.clearFrame()
        print()
        # getting current hour
        frame = tk.Frame(self.root)
        
        timestr = (datetime.now()).strftime("%d/%m/%Y %H:%M:%S")
        hr = re.search(" \d{1,2}", timestr)
        hr = hr.group()
        hr = hr[1:]

        # reviewing all items for hour
        if dailyLoadUp[str(hr)] == []:
            nothing = tk.Label(frame, text = "Nothing to review!", font = ('Arial', 20))
            nothing.pack()
        for item in dailyLoadUp[str(hr)]:
            prompt = tk.Label(frame, text = f"Definition of {item.item_name}?")
            prompt.pack()
            answerBox = tk.Entry(frame).place(x = 250, y = 100)
            answerBox.pack()
            
            answer = answerBox.get()
            # Gets the correct answer
            # need to move it to next level, display correct, and update it's time.
            if answer == item.item_definition:
                # Displaying correct
                correct = tk.Button(frame, text = "Correct!", font = ('Arial', 10))
                # Fixing level
                item.item_level+=1
                # Updating time for next review
                item = HelperMethods.getNewHoursForItem(item)
                correct.pack()
            # Gets the wrong answer
            else:
                # demoting level
                item.item_level-=1

                # Updating time for next reviwe
                item = HelperMethods.getNewHoursForItem(item)

                #Displaying definition, as well as informing of incorrect
                definitionLabel = tk.Label(frame, text = f"Wrong! Correct definition is {item.item_definition}")
                definitionLabel.pack()
                nextButton = tk.Button(frame, text = "Next", font = ('Arial', 10))
                nextButton.pack()
        self.clearFrame()
        return frame
    def addItem(self):
        self.clearFrame()      
        
        frame = tk.Frame(self.root)
        # for term
        term_frame = tk.Frame(frame)
        self.curr_frame = term_frame
        term_label = tk.Label(term_frame, text = "Please enter the term you would like to add", font = ('Arial', 16))
        term_label.grid(row = 0, column=0)
        self.t_entry = tk.Entry(term_frame)
        self.t_entry.grid(row = 0, column=1)
        term_frame.pack()
        

        # for defn
        defn_frame = tk.Frame(frame)
        defn_label = tk.Label(defn_frame, text = "Please enter the definition of the term", font = ('Arial', 16))
        defn_label.grid(row = 0, column = 0)
        self.d_entry = tk.Entry(defn_frame)
        self.d_entry.grid(row = 0, column=1)
        defn_frame.pack()
        
        
        # confirmation
        button_confirm = tk.Button(frame, text = "Add Item", font = ('Arial', 16), command = self.addEntries)
        button_confirm.pack()
        frame.pack()

        return frame
    def addEntries(self):
        self.term_entry = self.t_entry.get()
        self.defn_entry = self.d_entry.get()
        term = self.term_entry
        defn = self.defn_entry

        item_to_add = Item(term, defn)

        # getting date and time for next review
        now = datetime.now()
        now = now+timedelta(hours = 4)
        item_to_add.date_to_review = now.strftime("%d/%m/%Y %H:%M:%S")
        item_to_add.hour_to_review = int((re.search(" \d{1,2}", item_to_add.date_to_review)).group())
        print(item_to_add)

        # set the new time, set the date, add it to our list of terms.
        allTerms.append(item_to_add)
        itemFinder['0'].append(item_to_add)
        print("itemFinder ", itemFinder['0'])
        print("allTerms ", allTerms)
        print("review time ", item_to_add.date_to_review)

    def deleteItems(self):
        self.clearFrame()

        frame = tk.Frame(self.root)
        self.frames2[1] = frame
        
        self.curr_frame = frame
        qLabel = tk.Label(self.frames2[1], text = f"What is the term you want to delete?", font = ('Arial', 20))
        qLabel.grid(row = 0, column = 0)

        entryLabel = tk.Entry(self.frames2[1])
        entryLabel.grid(row = 1, column = 0, sticky = tk.EW)
        self.term_entry = entryLabel
        searchButton = tk.Button(self.frames2[1], text = f"Search!", font = ('Arial', 20), command = self.getEntryItem)
        searchButton.grid(row = 1, column = 1, padx= 10)

        frame.pack()

        return frame

    def getEntryItem(self):
        deleteItem = None
        # need to remove from allTerms, itemFinder, and possibly dailyLoadUp
        def delete():
            print("in  here")
            deletedLabel = tk.Label(self.frames2[1], text = "Deleted!", font = ('Arial', 20))
            deletedLabel.grid()

            currdate = item_to_delete.date_to_review
            currdate = re.search("\d{1,2}/\d{1,2}/\d{4}", currdate)
            
            #finding exact term
            termx = None
            for item in itemFinder[deleteItem.item_level]:
                if item.item_name == deleteItem.item_name:
                    termx = item

            #if dates are the same remove from today's lineup
            if currdate.group() == (re.search("\d{1,2}/\d{1,2}/\d{4}", datetime.now().strftime("%d/%m/%Y %H:%M:%S"))).group():
                dailyLoadUp[str(deleteItem.hour_to_review)]

            print("list: ", itemFinder[deleteItem.item_level])
            allTerms.remove(deleteItem)
            itemFinder[deleteItem.item_level].remove(termx)
            
            print("allTerms: ", allTerms)
            print("itemFinder for specific level: ", itemFinder[deleteItem.item_level])
        
        
        itemToFind = self.term_entry.get()
        for item_to_delete in allTerms:
            if item_to_delete.item_name == itemToFind:
                deleteItem = item_to_delete
                button = tk.Button(self.frames2[1], text = f"Delete {itemToFind}", font = ('Arial', 20), command = delete)
                button.grid()
                self.frames2[1].pack()
        return self.frames2[1]

非常感谢您的帮助。编辑:需要更多的代码,所以在这里

luaexgnf

luaexgnf1#

TKinter无效帧错误,窗口路径错误“。!框架”
除了“家”,我只是想带我回到我原来的开始屏幕。
编辑:

tkinter.TclError: cannot use geometry manager grid inside .!frame which already has slaves managed by pack

基本上,我使用了pack()

  • 创建show_homw()函数。并放置在self.root.mainloop()之外
  • 从第57行复制并删除到第71行。并复制到show_homw()函数中。
  • 在第100行,替换此self.curr_frame = self.show_home()
  • 注解掉showFrame函数中的第101行self.curr_frame.pack()

我把这个问题留给你在下面的case 'review':中进行故障排除。

line 120, in startPractice
    if dailyLoadUp[str(hr)] == []:
       ^^^^^^^^^^^
NameError: name 'dailyLoadUp' is not defined

剩下的部分由addItem来解决。
片段:

def show_home(self):        
    # starting screen
    self.frame = tk.Frame(self.root)

    #prompt
    self.prompt = tk.Label(self.frame, text = "What would you like to do?", font = ('Arial', 18))
    self.prompt.pack(padx = 10, pady = 10)
    # review button
    practiceButton = tk.Button(self.frame, text = f"Practice terms", font = ('Arial, 20'), command=self.startPractice)
    #practiceButton.grid(row = 0, column=0)
    practiceButton.pack()
    #add button
    addItems = tk.Button(self.frame, text = "Add Items", font = ('Arial', 20), command= self.addItem)
    addItems.pack()
    #delete button
    deleteItems = tk.Button(self.frame, text = "Delete Items", font = ('Arial', 20), command = self.deleteItems)
    deleteItems.pack()
    self.frame.pack()

截图:

相关问题