简体   繁体   中英

Why does tkinter say that I have slaves managed by a grid?

I am trying to create a tkinter GUI with multiple classes to manage the code. However, when I try to use pack() on a Label , it gives an error that there is already a slave managed by grid . The Label is inside a tk.Frame , and the tk.Frame is using grid() in the main window, so I do not understand why the pack() is not working.

Code:

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

Error Message:

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

The error is in TextIO , because the parent of its children widgets is TextIO itself [1] , not its parent , so you should correct:

inputLabel = ttk.Label(parent, text = "Input:")

with

inputLabel = ttk.Label(self, text = "Input:")

Same thing for inputString , outputLabel and output .

I mean, the current instance of a TextIO object.

In TextIO you're using parent (which is already managed by grid ) and not self as the parent for the buttons. Hence the error.

But perhaps equally important:

Mixing the grid and pack geometry managers is not a good idea. These work fundamentally different and there can also be some serious edge-cases when mixing grid and pack in the same window. TK can do some strange things trying to negotiate the layout, causing strange layouts, infinite loops, etc. You really don't want to do it.

The most sane case, in my personal opinion, is to just always use grid . It's the easiest and most flexible. pack is sometimes nice to quickly get started, but there are some things that can be difficult to do later on.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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