【问题标题】:After using .destroy() method on Scrolled text widget in Tkinter the Scrollbar doesn't disappear [closed]在 Tkinter 的滚动文本小部件上使用 .destroy() 方法后,滚动条不会消失 [关闭]
【发布时间】:2020-06-09 11:07:53
【问题描述】:


我在 Tkinter 中使用 Scrolled Text 小部件,但是当我在其上调用 destroy() 方法时,Box 消失了,但滚动条仍然存在。我提供了一些图片,以便您更好地理解我在说什么。
我该如何解决这个问题?

这里是代码,我说的是 item_description 小部件。

def add_item():

  global options
  global add
  global remove
  global display

  add.config(state = "disabled", relief = "sunken")
  remove.config(state = "disabled")
  display.config(state = "disabled")

  name_label = Label(options, text = "Item Name")
  name_label.grid(row = 1, column = 0, columnspan = 3, sticky = "w")
  item_name = Entry(options, width = 35)
  item_name.grid(row = 2, column = 0, columnspan = 3, sticky = "w")

  description_label = Label(options, text = "Item Description")
  description_label.grid(row = 3, column = 0, columnspan = 3, sticky = "w")
  item_description = ScrolledText(options, width = 25, height = 5)
  item_description.grid(row = 4, column = 0, columnspan = 3, sticky = "w")

  price_label = Label(options, text = "Item Price")
  price_label.grid(row = 5, column = 0, columnspan = 3, sticky = "w")
  item_price = Entry(options, width = 5)
  item_price.grid(row = 6, column = 0, sticky = "w", columnspan = 3)
  item_price.insert(0, "$0.00")

  stock_label = Label(options, text = "Stock")
  stock_label.grid(row = 7, column = 0, columnspan = 3, sticky = "w")
  item_stock = Entry(options, width = 5)
  item_stock.grid(row = 8, column = 0, sticky = "w", columnspan = 3)

  calories_label = Label(options, text = "Calories")
  calories_label.grid(row = 9, column = 0, sticky = "w", columnspan = 3)
  item_calories = Entry(options, width = 5)
  item_calories.grid(row = 10, column = 0, sticky = "w", columnspan = 3)

  date_label = Label(options, text = "Expiry Date")
  date_label.grid(row = 11, column = 0, sticky = "w", columnspan = 3)
  item_expiry_date = Entry(options, width = 12)
  item_expiry_date.grid(row = 12, column = 0, sticky = "w", columnspan = 3)
  item_expiry_date.insert(0, "dd/mm/yyyy")

  stock_add = Button(options, text = "Add", borderwidth = 2, relief = "groove",
    command = lambda: add_to_stock(item_name.get(),
      item_description.get("1.0", "end-1c"),
        item_price.get(),
          item_stock.get(),
            item_calories.get(),
              item_expiry_date.get()))

  stock_add.grid(row = 13, column = 0, sticky = "w", columnspan = 3)

  global widgets_add
  widgets_add = [name_label, item_name, description_label, item_description, price_label, item_price,
    stock_label, item_stock, calories_label, item_calories, date_label, item_expiry_date, stock_add]

这是我从 widgets_add 列表中删除所有小部件的代码,它是在前面代码的末尾制作的。

def remove_add():
  # Remove item adding dialog

  global widgets_add
  for widget in widgets_add:
    widget.destroy()

【问题讨论】:

  • tkinter 模块在销毁文本区域时不会销毁滚动条。如果要销毁滚动条,可以重绘整个窗口。我会尝试寻找其他解决方案。
  • ScrolledText 在内部创建一个 Frame 来保存 Text 和 Scrollbar 小部件。所以 destroy() 只会破坏 Text 小部件。您需要改用item_description.frame.destroy()

标签: python python-3.x list tkinter scrollbar


【解决方案1】:

问题在于 ScrolledText 小部件实际上创建了

Frame
    Scrollbar
    ScrolledText

但只返回对ScrolledText 的引用。当您destroy() 时,FrameScrollbar 就会被抛在后面。

最简单的解决方案是将所有控件添加到 Frame 实例和 destroy() 中。这样您就不必在单独的列表中跟踪它们。

所以,假设 options 是您的 Tk 实例:

def add_item():

  global options
  global add
  global remove
  global display

  add.config(state = "disabled", relief = "sunken")
  remove.config(state = "disabled")
  display.config(state = "disabled")

  options_frame = Frame(options)

  name_label = Label(options_canvas, text = "Item Name")
  name_label.grid(row = 1, column = 0, columnspan = 3, sticky = "w")
  item_name = Entry(options_canvas, width = 35)
  item_name.grid(row = 2, column = 0, columnspan = 3, sticky = "w")

  description_label = Label(options_canvas, text = "Item Description")
  description_label.grid(row = 3, column = 0, columnspan = 3, sticky = "w")
  item_description = ScrolledText(options_canvas, width = 25, height = 5)
  item_description.grid(row = 4, column = 0, columnspan = 3, sticky = "w")

  price_label = Label(options_canvas, text = "Item Price")
  price_label.grid(row = 5, column = 0, columnspan = 3, sticky = "w")
  item_price = Entry(options_canvas, width = 5)
  item_price.grid(row = 6, column = 0, sticky = "w", columnspan = 3)
  item_price.insert(0, "$0.00")

  stock_label = Label(options_canvas, text = "Stock")
  stock_label.grid(row = 7, column = 0, columnspan = 3, sticky = "w")
  item_stock = Entry(options_canvas, width = 5)
  item_stock.grid(row = 8, column = 0, sticky = "w", columnspan = 3)

  calories_label = Label(options_canvas, text = "Calories")
  calories_label.grid(row = 9, column = 0, sticky = "w", columnspan = 3)
  item_calories = Entry(options_canvas, width = 5)
  item_calories.grid(row = 10, column = 0, sticky = "w", columnspan = 3)

  date_label = Label(options_canvas, text = "Expiry Date")
  date_label.grid(row = 11, column = 0, sticky = "w", columnspan = 3)
  item_expiry_date = Entry(options_canvas, width = 12)
  item_expiry_date.grid(row = 12, column = 0, sticky = "w", columnspan = 3)
  item_expiry_date.insert(0, "dd/mm/yyyy")

  stock_add = Button(options_canvas, text = "Add", borderwidth = 2, relief = "groove",
    command = lambda: add_to_stock(item_name.get(),
      item_description.get("1.0", "end-1c"),
        item_price.get(),
          item_stock.get(),
            item_calories.get(),
              item_expiry_date.get()))

  stock_add.grid(row = 13, column = 0, sticky = "w", columnspan = 3)

def remove_add():
  # Remove item adding dialog

  global options_frame
  options_frame.destroy()

【讨论】:

  • 为什么不使用 Frame 而不是 Canvas?此外,ScrolledText 由 Frame、Text(不是 ScrolledText)和 Scrollbar 小部件组成。
  • 你说得对,Frame 更有意义。我不确定 Text 与 ScrolledText 的问题,但实际上我看到了这个:i.imgur.com/AOXLn0I.png
猜你喜欢
  • 2015-08-11
  • 2015-08-19
  • 2015-04-22
  • 1970-01-01
  • 2013-05-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-04-03
相关资源
最近更新 更多