繁体   English   中英

关于 tkinter 小部件错误的“包装”或“网格”的问题

[英]A question about 'pack' or 'grid' for tkinter widgets error

我正在学习 python。我遵循本书示例代码。 此代码使 SumGrid class 可以附加到正在网格化或打包其他小部件的容器。 作者说它使自己的几何管理模棱两可,并要求调用者对其实例进行打包或网格化。 容器可以为自己的孩子选择任何一种方案,因为它们有效地封闭了包装或网格的选择。 但是旨在在两个几何管理器下重用的可附加组件类无法管理自己,因为它们无法预测其父级的策略。

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()

当我在 window shell 中运行 this.py 文件时。 它行不通。 如下所示的错误消息。 我认为 SumGrid 是一个框架。 调用者可以决定对这个 Frame 进行打包或网格化。 但它不能在我的电脑上运行。 为什么? 谢谢你。

Traceback (most recent call last):
  File "C:\Users\hp\PP4E-Examples-1.4\Examples\PP4E\Gui\Tour\Grid\grid5c.py", line 84, in <module>
    SumGrid(root).pack()    # .grid() works here too
  File "C:\Users\hp\PP4E-Examples-1.4\Examples\PP4E\Gui\Tour\Grid\grid5c.py", line 12, in __init__
    self.makeWidgets(numrow, numcol)           # else only usable one way
  File "C:\Users\hp\PP4E-Examples-1.4\Examples\PP4E\Gui\Tour\Grid\grid5c.py", line 35, in makeWidgets
    Quitter(self).grid(row=0, column=4)    # fails: Quitter(self).pack()
  File "C:\Users\hp\PP4E-Examples-1.4\Examples\PP4E\Gui\Tour\quitter.py", line 12, in __init__
    self.pack()
  File "C:\Users\hp\AppData\Local\Programs\Python\Python310\lib\tkinter\__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

就像错误所说的那样,您不能在具有相同父级的小部件上同时使用gridpack

让我们看看这两行代码:

Button(self, text='Load',  command=self.onLoad).grid(row=0, column=3)
Quitter(self).grid(row=0, column=4)    # fails: Quitter(self).pack()

注意QuitterButton是如何使用self作为父级的。 这意味着您只能对两个小部件(以及以self作为父级的其他小部件)使用gridpack之一。 如果您使用grid作为按钮,则不能将pack用于Quitter ,这正是错误告诉您的内容。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM