我遇到运行Client.py时出现额外GUI的问题。我想这是因为我在Menu.py的第9行设置了myMenu = Toplevel()
,但如果我不在那里,那么在第10行之前,第10行会抛出错误(并且菜单GUI永远不会弹出因为它):
Exception in Tkinter callback
Traceback (most recent call last):
File "C:\Users\Pat\AppData\Local\Programs\Python\Python35-32\lib\tkinter\__init__.py", line 1549, in __call__
return self.func(*args)
File "C:\Users\Pat\Documents\GitHub\DunderMifflinSales\DunderMifflinClient.py", line 48, in _login_btn_clicked
Menu.create_menu()
File "C:\Users\Pat\Documents\GitHub\DunderMifflinSales\Menu.py", line 53, in create_menu
mf = MenuFrame(root)
File "C:\Users\Pat\Documents\GitHub\DunderMifflinSales\Menu.py", line 11, in __init__
mainframe = ttk.Frame(myMenu,padding="3 3 12 12")
NameError: name 'myMenu' is not defined
我是python和Tkinter的新手,想要解释一下我做错了什么以及我能做些什么来解决它。谢谢!
Client.py:
import socket
from tkinter import *
import tkinter.messagebox as tm
from tkinter import ttk
import Menu
serverName = 'localhost'
serverPort = 12000
clientSocket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
class LoginFrame(Frame):
def __init__(self, master):
super().__init__(master)
self.label_1 = Label(self, text="Username")
self.label_2 = Label(self, text="Password")
self.entry_1 = Entry(self)
self.entry_2 = Entry(self, show="*")
self.label_1.grid(row=0, sticky=E)
self.label_2.grid(row=1, sticky=E)
self.entry_1.grid(row=0, column=1)
self.entry_2.grid(row=1, column=1)
self.logbtn = Button(self, text="Login", command = self._login_btn_clicked)
self.logbtn.grid(columnspan=2)
self.pack()
def _login_btn_clicked(self):
username = self.entry_1.get()
clientSocket.sendto(username.encode('UTF-8'),(serverName, serverPort))
password = self.entry_2.get()
clientSocket.sendto(password.encode('UTF-8'),(serverName, serverPort))
message, address = clientSocket.recvfrom(1024)
message = message.decode('UTF-8')
if message == "200 OK":
Menu.create_menu()
else:
tm.showinfo("Login error", message)
def main():
root = Tk()
root.title("Dunder Mifflin GUI")
root.geometry('{}x{}'.format(270, 80))
lf = LoginFrame(root)
root.mainloop()
if __name__ == "__main__":
main()
Menu.py:
from tkinter import *
from tkinter import ttk
class MenuFrame(Frame):
def __init__(self, master):
super().__init__(master)
myMenu = Toplevel()
mainframe = ttk.Frame(myMenu,padding="3 3 12 12")
mainframe.grid(column = 0, row = 0, sticky = (N, W, E, S))
mainframe.columnconfigure(0, weight = 1)
mainframe.rowconfigure(0, weight = 1)
name = "John"
sales = StringVar()
moreSales = StringVar()
sales.set("1")
welcome = "Welcome, " + name + "!"
sales_entry = ttk.Entry(mainframe, width = 7, textvariable = moreSales)
ttk.Label(mainframe, text = welcome).grid(column = 2, row = 1, sticky = W)
ttk.Label(mainframe, text = "Current Sales:").grid(column = 1, row = 2, sticky = W)
ttk.Label(mainframe, textvariable = sales).grid(column = 2, row = 2, sticky = (E))
ttk.Label(mainframe, text = "sales").grid(column = 3, row = 2, sticky = W)
ttk.Label(mainframe, text = "Add Sales").grid(column = 1, row = 3, sticky = W)
sales_entry.grid(column = 2, row = 3, sticky = (W, E))
ttk.Button(mainframe, text = "Add", command = MenuFrame.add(sales, moreSales)).grid(column = 3, row = 3, sticky = W)
ttk.Button(mainframe, text = "Log Out", command = MenuFrame.logout).grid(column = 2, row = 4, sticky = W)
def add(sales, moreSales):
try:
value1 = int(sales.get())
value2 = int(moreSales.get())
sales.set(value1 + value2)
except ValueError:
pass
def logout():
myMenu.destroy()
def create_menu():
root = Tk()
root.title("Dunder Mifflin GUI")
mf = MenuFrame(root)
root.mainloop()
root.destroy()
if __name__ == "__create_menu__":
create_menu()
答案 0 :(得分:1)
您问题中的堆栈跟踪似乎与您问题中的代码无关,因为堆栈跟踪显示代码mf = Menu.MenuFrame(mymenu)
,但该代码在您发布的代码中不存在。
您的代码正在创建一个“额外的GUI”,因为您正在告诉它。您只能创建Tk
的单个实例,但您要创建两个。{1}}。您可以在Client.py(方法main
)中创建一个,在Menu.py中创建一个(方法create_menu
)。
通常应用于Tk
实例的名称是root
,因为这是(并且必须是)窗口小部件层次结构的根。你不能在树上有两个根。
与手头的问题无关,您是否知道if __name__ == "__create_menu__"
始终是False
?