[英]Tkinter grid manager can't manage 'top level window' menu
So I've got a Python 3 and Tkinter app. 所以我有一个Python 3和Tkinter应用程序。 I'm currently trying to add a menu bar to the top of the window it pops up in. It's fine creating, but as soon as I try to grid()
it, it all goes haywire and throws me this error: 我目前正在尝试在弹出窗口的顶部添加一个菜单栏。创建起来很好,但是一旦我尝试将它grid()
起来,一切就变得一团糟,并向我抛出此错误:
[first line omitted]
File "C:\Users\Me\Documents\sync.py", line 13 in __init__
self.createWidgets()
File "C:\Users\Me\Documents\sync.py", line 21, in createWidgets
self.menubar.grid(column = 0, comlumnspan = 3)
File "C:\Program Files (x86)\Python34\lib\tkinter\__init__.py", line 2020, in grid_configure + self._options(cnf,kw))
_tkinter.TclError: can't manage ".41452544.49048880": it's a top-level window
So from that, it's fairly obvious that the flow is working: __init__
calls createWidgets
creates self.menubar
, adds submenus, calls self.menubar.grid
. 因此,由此可见,该流程正在正常工作: __init__
调用createWidgets
创建self.menubar
,添加子菜单,调用self.menubar.grid
。
What I can't figure out is why Tkinter thinks the menubar it's being called to grid is a top-level window. 我不明白的是,为什么Tkinter认为被称为网格的菜单栏是顶层窗口。 self.menubar.grid()
, being listed in the trace, is clearly the cause of the problem rather than the root window, so that must be what it's thinking. 在跟踪中列出的self.menubar.grid()
显然是问题的原因,而不是根窗口,因此这一定是它的想法。
Here's the bit of code in question: 这是有问题的代码:
def createWidgets(self):
self.menubar = tk.Menu(self)
self.menubar.grid(column = 0, columnspan = 3)
SyncMenu = tk.Menu(self.menubar, tearoff = 0)
SyncMenu.add_command(label = "Connect", command = self.Sync.Connect)
SyncMenu.add_command(label = "Disconnect", command = self.Sync.Disconnect)
FileMenu = tk.Menu(self.menubar, tearoff = 0)
FileMenu.add_command(label = "Upload File", command = self.File.Upload)
FileMenu.add_command(label = "Browse Online Files", command = self.File.Browse)
self.menubar.add_cascade(label = "Sync", menu = SyncMenu)
self.menubar.add_cascade(label = "File", menu = FileMenu)
The same error comes up no matter where I put the call to grid()
. 无论我在哪里调用grid()
都会出现相同的错误。
The other part of this problem is that I'm in Python 3 and the updated Tkinter, so no tk.Tk()
for me. 这个问题的另一部分是我使用的是Python 3和更新的Tkinter,所以对我来说没有tk.Tk()
。 Instead, to initialise, I have this: 相反,要初始化,我有这个:
class Application(tk.Frame):
def __init__(self, master=None):
tk.Frame.__init__(self,master)
self.grid()
self.createWidgets()
self.master.geometry("500x500")
You can't use grid on menus. 您不能在菜单上使用网格。 Tkinter considers them a top-level window because they float above other windows. Tkinter认为它们是顶级窗口,因为它们漂浮在其他窗口之上。
The normal way to create a traditional menubar is to associate it with the menu
attribute of the root window: 创建传统菜单栏的通常方法是将其与根窗口的menu
属性相关联:
root = tk.Tk()
menubar = tk.Menu(root)
...
root.configure(menu=menubar)
I've figured it out. 我知道了。 When I edited the question to add the second code block, I noticed the self.master.geometry
line, to which I thought "That line affects the main window, couldn't I use that?" 当我编辑问题以添加第二个代码块时,我注意到self.master.geometry
行,我认为“该行会影响主窗口,我不能使用它吗?”
The answer was yes, so the solution to finding the root window was just to use self.master
, which is defined in my __init__
method by the supercall to tk.Frame.__init__
: 答案是肯定的,因此找到根窗口的解决方案只是使用self.master
,它是在我的__init__
方法中通过对tk.Frame.__init__
的超级tk.Frame.__init__
:
class Application(tk.Frame):
def __init__(self, master=None):
tk.Frame.__init__(self,master) # This line defines self.master
self.grid()
self.createWidgets()
self.master.geometry("500x500") # This line uses it
So the solution to get my menubar into the correct window is now this: 因此,使菜单栏进入正确窗口的解决方案是:
self.master["menu"] = self.menubar
which is in the code after creating all the menu and menu items. 创建所有菜单和菜单项之后的代码中。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.