我正在学习python。我按照书中的示例代码。这段代码使SumGrid类可以附加到其他小部件正在网格化或打包的容器中。作者说,它让自己的几何图形管理变得模糊,并要求调用方对其实例进行打包或网格化。容器可以为自己的孩子选择其中一种方案,因为它们有效地阻止了包装或网格的选择。但是,目标是在两个几何图形管理器下重复使用的可连接零部件类无法自行管理,因为它们无法预测父级的策略。
from tkinter import *
from tkinter.filedialog import askopenfilename
from PP4E.Gui.Tour.quitter import Quitter # reuse, pack, and grid
class SumGrid(Frame):
def __init__(self, parent=None, numrow=5, numcol=5):
Frame.__init__(self, parent)
self.numrow = numrow # I am a frame container
self.numcol = numcol # caller packs or grids me
self.makeWidgets(numrow, numcol) # else only usable one way
def makeWidgets(self, numrow, numcol):
self.rows = []
for i in range(numrow):
cols = []
for j in range(numcol):
ent = Entry(self, relief=RIDGE)
ent.grid(row=i+1, column=j, sticky=NSEW)
ent.insert(END, '%d.%d' % (i, j))
cols.append(ent)
self.rows.append(cols)
self.sums = []
for i in range(numcol):
lab = Label(self, text='?', relief=SUNKEN)
lab.grid(row=numrow+1, column=i, sticky=NSEW)
self.sums.append(lab)
Button(self, text='Sum', command=self.onSum).grid(row=0, column=0)
Button(self, text='Print', command=self.onPrint).grid(row=0, column=1)
Button(self, text='Clear', command=self.onClear).grid(row=0, column=2)
Button(self, text='Load', command=self.onLoad).grid(row=0, column=3)
Quitter(self).grid(row=0, column=4) # fails: Quitter(self).pack()
def onPrint(self):
for row in self.rows:
for col in row:
print(col.get(), end=' ')
print()
print()
def onSum(self):
tots = [0] * self.numcol
for i in range(self.numcol):
for j in range(self.numrow):
tots[i] += eval(self.rows[j][i].get()) # sum current data
for i in range(self.numcol):
self.sums[i].config(text=str(tots[i]))
def onClear(self):
for row in self.rows:
for col in row:
col.delete('0', END) # delete content
col.insert(END, '0.0') # preserve display
for sum in self.sums:
sum.config(text='?')
def onLoad(self):
file = askopenfilename()
if file:
for row in self.rows:
for col in row: col.grid_forget() # erase current gui
for sum in self.sums:
sum.grid_forget()
filelines = open(file, 'r').readlines() # load file data
self.numrow = len(filelines) # resize to data
self.numcol = len(filelines[0].split())
self.makeWidgets(self.numrow, self.numcol)
for (row, line) in enumerate(filelines): # load into gui
fields = line.split()
for col in range(self.numcol):
self.rows[row][col].delete('0', END)
self.rows[row][col].insert(END, fields[col])
if __name__ == '__main__':
import sys
root = Tk()
root.title('Summer Grid')
if len(sys.argv) != 3:
SumGrid(root).pack() # .grid() works here too
else:
rows, cols = eval(sys.argv[1]), eval(sys.argv[2])
SumGrid(root, rows, cols).pack()
root.mainloop()
当我在窗口外壳中运行这个.py文件时。它不起作用。错误消息如下所示。我认为SumGrid是一个框架。调用方可以决定打包或网格化此帧。但是它不能在我的电脑上工作。为什么?非常感谢。
Traceback (most recent call last):
File "C:UsershpPP4E-Examples-1.4ExamplesPP4EGuiTourGridgrid5c.py", line 84, in <module>
SumGrid(root).pack() # .grid() works here too
File "C:UsershpPP4E-Examples-1.4ExamplesPP4EGuiTourGridgrid5c.py", line 12, in __init__
self.makeWidgets(numrow, numcol) # else only usable one way
File "C:UsershpPP4E-Examples-1.4ExamplesPP4EGuiTourGridgrid5c.py", line 35, in makeWidgets
Quitter(self).grid(row=0, column=4) # fails: Quitter(self).pack()
File "C:UsershpPP4E-Examples-1.4ExamplesPP4EGuiTourquitter.py", line 12, in __init__
self.pack()
File "C:UsershpAppDataLocalProgramsPythonPython310libtkinter__init__.py", line 2425, in pack_configure
self.tk.call(
_tkinter.TclError: cannot use geometry manager pack inside .!sumgrid which already has slaves managed by grid
正如错误所说,不能在具有相同父级的小部件上同时使用grid
和pack
。
让我们看看这两行代码:
Button(self, text='Load', command=self.onLoad).grid(row=0, column=3)
Quitter(self).grid(row=0, column=4) # fails: Quitter(self).pack()
请注意Quitter
和Button
是如何使用self
作为父级的。这意味着您必须仅将grid
或pack
中的一个用于两个小部件(以及将self
作为父部件的其他小部件(。如果使用grid
作为按钮,则不能使用pack
作为Quitter
,这正是错误告诉您的。