我正在尝试创建一个包含多个类的tkinter GUI来管理代码。但是,当我尝试在pack()
上使用Label
时,会出现错误,即已经有grid
管理的从属设备。 Label
位于tk.Frame
内,tk.Frame
在主窗口中使用grid()
,因此我不明白为什么pack()
无效。
代码:
import tkinter as tk
from tkinter import ttk
class TextIO(tk.Frame):
def __init__(self, parent):
tk.Frame.__init__(self, parent)
self.parent = parent
inputLabel = ttk.Label(parent, text = "Input:")
inputLabel.pack(side = "top")
inputString = tk.Text(parent)
inputString.pack(side = "top")
outputLabel = ttk.Label(parent, text = "Output:")
outputLabel.pack(side = "bottom")
output = tk.Text(parent)
output.insert("0.0", "Type -1 in shift if you want all shifts when decrypting")
output.pack(side = "bottom")
class ButtonBox(tk.Frame):
def __init__(self, parent):
tk.Frame.__init__(self, parent)
self.parent = parent
shiftLabel = ttk.Label(parent, text = "Shift:")
shiftLabel.grid(row = 0, column = 0)
amountShift = ttk.Entry(parent, width = 5)
amountShift.grid(row = 0, column = 1)
encryptButton = ttk.Button(parent, text = "Encrypt", width = 20)
encryptButton.config(command = lambda: respondToUser('E'))
encryptButton.grid(row = 0, column = 2)
decryptButton = ttk.Button(parent, text = "Decrypt", width = 20)
decryptButton.config(command = lambda: respondToUser('D'))
decryptButton.grid(row = 0, column = 3)
class MainWindow(tk.Frame):
def __init__(self, parent):
tk.Frame.__init__(self, parent)
self.parent = parent
self.UserIO = TextIO(self)
self.UserIO.grid(row = 0, column = 0)
self.Buttons = ButtonBox(self)
self.Buttons.grid(row = 1, column = 0)
root = tk.Tk()
MainWindow(root).pack()
root.mainloop()
错误讯息:
Traceback (most recent call last):
File "/home/pi/Documents/Code Projects/Caesar Cipher.py", line 122, in <module>
MainWindow(root).pack()
File "/home/pi/Documents/Code Projects/Caesar Cipher.py", line 94, in __init__
self.UserIO.grid(row = 0, column = 0)
File "/usr/lib/python3.4/tkinter/__init__.py", line 2060, in grid_configure
+ self._options(cnf, kw))
_tkinter.TclError: cannot use geometry manager grid inside .1960274768 which already has slaves managed by pack
答案 0 :(得分:1)
错误位于TextIO
,因为其子窗口小部件的父级是TextIO
本身 [1] ,而不是parent
,因此您应该更正:
inputLabel = ttk.Label(parent, text = "Input:")
与
inputLabel = ttk.Label(self, text = "Input:")
inputString
,outputLabel
和output
也是如此。
我的意思是,TextIO
对象的当前实例。
答案 1 :(得分:0)
在TextIO
中,您使用parent
(已由grid
管理)而不是self
作为按钮的父级。因此错误。
但也许同样重要:
混合grid
和pack
几何管理器并不是一个好主意。这些工作根本不同,在同一窗口中混合grid
和pack
时也会出现一些严重的边缘情况。 TK可以做一些奇怪的事情,试图协商布局,导致奇怪的布局,无限循环等。你真的不想这样做。
在我个人看来,最理智的情况是始终使用grid
。这是最简单,最灵活的。 pack
有时候很快就会开始,但有些事情以后很难做到。