【问题标题】:Tkinter GUI: Adding new entry boxes using .grid() when button is pressedTkinter GUI:按下按钮时使用 .grid() 添加新的输入框
【发布时间】:2017-08-21 03:58:41
【问题描述】:

当“添加条目”用于我的程序时,我正在尝试创建新的输入框。我确实意识到“打包代码”在我单独运行时有效,但是当我与grid() 中的现有程序结合使用时,当我运行我的程序时,窗口没有显示。

我也明白,当我在同一个程序中使用.grid() 有其他事情时,我们不应该同时使用.pack()。因此,我的问题是,如何在网格中创建新的输入框。

我尝试在其他地方寻找,但他们都建议打包。例如:我看过herehere等等等等,仅举几例;但找不到与我类似的东西。我想在第 3 行的当前输入框下方添加输入框。

我对 Python 有点陌生; (我在这个程序中使用 Python 2.7 和 tkinter 模块。非常感谢您的帮助! 我的简化错误代码如下:

from Tkinter import *
import tkFileDialog
import tkMessageBox
import Tkinter
import os

class Window:

 def __init__(self, master):

    self.filename3=""
    csvfile=Label(root, text="NUMBERS").grid(row=3, column=0)
    bar=Entry(master).grid(row=3, column=3)
    self.entryText3 = StringVar()
    self.bar = Entry(root, textvariable=self.entryText3).grid(row=3, column=3)

    #BUTTONS
    self.cbutton= Button(root, text="OK", command=self.process_csv)
    self.cbutton.grid(row=15, column=6, sticky = W + E)

####PROBLEM FROM HERE#####
    all_entries = []
    addboxButton = Button(root, text='ADD', fg="BLUE", command=self.addBox)
    addboxButton.pack()

#I have also tried replacing the last 2 lines with the following 2 lines instead but to no avail:     
#self.addboxButton = Button(root, text='ADD THA-ID', fg="BLUE", command=self.addBox)
#self.addboxButton.grid(row=3, column=6)

    frame_for_boxes = Frame(root)
    frame_for_boxes.pack()

 def addBox(self):
    print "ADD"
    next_row = len(all_entries)
    lab = Label(frame_for_boxes, text=str(next_row+1))
    lab.grid(row=next_row, column=0)
    ent = Entry(frame_for_boxes)
    ent.grid(row=next_row, column=0)
    all_entries.append( ent )

 def process_csv(self):
    #own program here
    print "program"
root = Tk()
window=Window(root)
root.mainloop()

【问题讨论】:

  • “我也明白,当我在同一个程序中使用 .grid() 有其他东西时,我们不应该同时使用 .pack()。” - 那不是一个正确的陈述。您可以在同一个程序中同时使用gridpack,但不能用于共享同一个parent的两个或多个小部件。

标签: python python-2.7 user-interface layout tkinter


【解决方案1】:

你必须做什么来创建一个创建条目并将新条目存储在变量中的命令。 就我而言,我使用 Entry_i 并存储在 Entries 中,但您可以使用 self.Entries 来简化沟通。 (python 3.5)

def Make_Entry(self, root, Entries, x, y):

    Entry_i = Entry(root, bd = 5)
    Entry_i.grid(row = x, column = y, sticky = W+E+N+S)
    Entries.append(Entry_i)
    return(Entries, x+1, y+1)

【讨论】:

    【解决方案2】:

    除了您所说的之外,您的程序几乎没有问题:

    1. 在初始化程序 (__init__()) 中,您将小部件附加到 root,这在 Window 类的范围内未定义。解决此问题的合理方法是,当您在Window 类中使用Tk() 的实例,id est root id est master 时,将其设为实例变量。这意味着您必须在初始化程序中做的第一件事是:self.master = master。这将导致您必须将__init__() 中出现的所有root 替换为self.master

    2. 要解决的第二个问题是您在问题标题中指定的问题:您不能将grid()pack() 布局管理器混合用于同一个小部件容器。你必须决定哪一个。由于您使用grid() 放置了大多数小部件,我建议您摆脱pack()。这意味着:

      • 例如,addboxButton.pack() 变为 addboxButton.grid(row=0, column=1)
      • 例如,frame_for_boxes.pack() 变为 frame_for_boxes.grid(row=0, column=0)
    3. 上一个列表项修复了问题,但它会让您发现程序中的其他相关问题:

      • NameError: global name 'all_entries' is not defined
      • NameError: global name 'frame_for_boxes' is not defined

      这是因为这些小部件变量在addBox() 函数的范围内是不可访问的。要解决此问题,您必须将这 2 个元素设为 实例变量。这意味着:

      • all_entries = [] 变为 self.all_entries = []
      • frame_for_boxes = Frame(root) 变为 self.frame_for_boxes = Frame(self.master)(请记住,我们在 1. 中将 root 替换为 self.master

      此错误修复的后果是您必须在程序中使用所有内容:

      • self.all_entries 而不是 all_entries
      • self.frame_for_boxes 而不是 frame_for_boxes
    4. 出于可扩展性的原因,我认为您至少必须将其余小部件设为实例变量(i.d. 在它们前面加上 self 关键字)

    5. 由于您的实际项目比您在此 MCVE 中展示的更复杂,因此我鼓励您在创建和放置小部件元素时采用SaYa idiom。这意味着您需要更换:

        csvfile=Label(root, text="NUMBERS").grid(row=3, column=0)
      

      通过

        self.csvfile = Label(self.master, text="NUMBERS")
        self.csvfile.grid(row=3, column=0)
      

      为避免程序中出现意外错误,您必须对在初始化程序中声明的其余小部件执行相同操作。

    6. 我还想提一些其他的东西,但大部分都可以在PEP8上找到

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-09-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-08-19
      • 1970-01-01
      • 2013-06-16
      • 2021-07-02
      相关资源
      最近更新 更多