如何成功地提取以下代码行?(Python Tkinter GUI)

如何成功地提取以下代码行?(Python Tkinter GUI),python,user-interface,tkinter,abstraction,Python,User Interface,Tkinter,Abstraction,我正在尝试用Python为名为“巧克力自动售货机”的类分配创建GUI。要求学生使用Python的Tkinter。我们列出了几个巧克力品牌,如Snickers、Twix和Mars,并在每个品牌上贴上价格标签。用户将完成以下步骤: 输入他有多少钱的浮动值(可以是任意值) 他选择每种巧克力要多少 该值将打印到控制台的“总成本”下 原始余额(他原来有多少钱)减去总成本打印出新的余额 请参考下面的代码如何提取以下代码行以使其仍能工作,但限制行数?请注意,我没有粘贴应用程序的全部代码,因为代码行太多了。因此

我正在尝试用Python为名为“巧克力自动售货机”的类分配创建GUI。要求学生使用Python的Tkinter。我们列出了几个巧克力品牌,如Snickers、Twix和Mars,并在每个品牌上贴上价格标签。用户将完成以下步骤:

  • 输入他有多少钱的浮动值(可以是任意值)
  • 他选择每种巧克力要多少
  • 该值将打印到控制台的“总成本”下
  • 原始余额(他原来有多少钱)减去总成本打印出新的余额
  • 请参考下面的代码如何提取以下代码行以使其仍能工作,但限制行数?请注意,我没有粘贴应用程序的全部代码,因为代码行太多了。因此,这里有一个片段可以缩小范围:

    #----------------------Chocolate---------------------
    
    Twix=DoubleVar()
    Snickers=DoubleVar()
    MarsBar=DoubleVar()
    Godiva=DoubleVar()
    
    lblTwix = Label(f1, font=('arial', 16, 'bold'), text='Twix',bg = 'powder blue',bd=19,anchor='w')
    lblTwix.grid(row=2,column=0)
    txtTwix = Entry(f1,font=('arial',16,'bold'),textvariable=Twix,bd=10,insertwidth=4,
                    bg='powder blue',justify='right')
    txtTwix.grid(row=2,column=1)
    
    lblSnickers = Label(f1, font=('arial', 16, 'bold'), text='Snickers', bg = 'powder blue',bd=19,anchor='w')
    lblSnickers.grid(row=4,column=0)
    txtSnickers = Entry(f1,font=('arial',16,'bold'),textvariable=Snickers,bd=10,insertwidth=4,
                    bg='powder blue',justify='right')
    txtSnickers.grid(row=4,column=1)
    
    lblMarsBar = Label(f1, font=('arial', 16, 'bold'), text='Mars Bar', bg = 'powder blue',bd=19,anchor='w')
    lblMarsBar.grid(row=6,column=0)
    txtMarsBar = Entry(f1,font=('arial',16,'bold'),textvariable=MarsBar,bd=10,insertwidth=4,
                    bg='powder blue',justify='right')
    txtMarsBar.grid(row=6,column=1)
    
    lblGodiva = Label(f1,font=('arial',16,'bold'), text="Godiva", bg = 'powder blue',bd=19, anchor='w')
    lblGodiva.grid(row=9, column=0)
    txtGodiva = Entry(f1,font=('arial',16,'bold'),textvariable=Godiva,bd=10,insertwidth=4,
                    bg='powder blue',justify='right')
    txtGodiva.grid(row=9,column=1)
    
    #==================================Balance, Cost=======================================
    
    InitialBalance=DoubleVar()
    Cost=StringVar()
    FinalBalance=StringVar()
    
    lblInitialBalance = Label(f1,font=('arial',20,'bold'), text="Initial Balance", bg = 'powder blue', bd=29, anchor='w')
    lblInitialBalance.grid(row=2, column=10)
    txtInitialBalance=Entry(f1,font=('arial',20,'bold'), textvariable=InitialBalance, bd=28, insertwidth=4,
                       bg='steel blue', justify='right')
    txtInitialBalance.grid(row=2, column=12)
    
    lblCost = Label(f1,font=('arial',20,'bold'), text="Total Cost", bg = 'powder blue',bd=29, anchor='w')
    lblCost.grid(row=4, column=10)
    txtCost=Entry(f1,font=('arial',20,'bold'), textvariable=Cost, bd=28, insertwidth=4,
                       bg='powder blue', justify='right')
    txtCost.grid(row=4, column=12)
    
    lblFinalBalance = Label(f1,font=('arial',20,'bold'), text="Final Balance", bg = 'powder blue',bd=29, anchor='w')
    lblFinalBalance.grid(row=6, column=10)
    txtFinalBalance=Entry(f1,font=('arial',20,'bold'), textvariable=FinalBalance, bd=28, insertwidth=4,
                       bg='powder blue', justify='right')
    txtFinalBalance.grid(row=6, column=12)
    
    修订守则:

    Twix=DoubleVar()
    Snickers=DoubleVar()
    MarsBar=DoubleVar()
    Godiva=DoubleVar()
    
    def make_entry(frame, text, variable, row, col1, col2):
        label = Label(frame, font=('arial',20,'bold'), text=text, textvariable = variable, bg = 'powder blue', bd=19, anchor='w')
        label.grid(row=row, column=col1)
        entry=Entry(f1,font=('arial',20,'bold'), textvariable=variable, bd=28, insertwidth=4,
                           bg='steel blue', justify='right')
        entry.grid(row=row, column=col2)
        return label, entry
    
        make_entry(f1, "Twix", Twix, 2, 0, 1)
        make_entry(f1, "Snickers", Snickers, 4, 0, 1)
        make_entry(f1, "MarsBar", MarsBar, 6, 0, 1)
        make_entry(f1, "Godiva", Godiva, 9, 0, 1)
    
    下面是完整的非抽象代码的链接:

    如您所见,上面粘贴的每一行代码都与按钮和框的样式有关,用户可以为程序输入必要的信息以完成其工作。话虽如此,我重申这个问题:

    将所有这些代码压缩成更少的行并使其仍能工作的最有效方法是什么?如何使用类和def语句以更高效的方式重写代码?


    我试图抽象上面的代码,但没有成功。非常感谢您的帮助。

    您可以定义一个函数,使用给定参数创建
    标签
    条目

    def make_entry(frame, text, variable, row, col1, col2):
        font = ('arial',16,'bold')
        label = Label(frame, font=font, text=text, bg='powder blue', bd=19, anchor='w')
        label.grid(row=row, column=col1)
        entry = Entry(frame, font=font, textvariable=variable, bg='powder blue', bd=10, insertwidth=4, justify='right')
        entry.grid(row=row, column=col2)
    
    然后,只需为不同的糖果调用该函数

    make_entry(f1, "Twix", Twix, 2, 0, 1)
    make_entry(f1, "Snickers", Snickers, 4, 0, 1)
    ...
    
    如果以后需要,还可以使用函数
    返回标签、条目
    ,但看起来变量已经足够了

    第二组中的参数有点不同:较大的字体大小、较厚的边框、不同的蓝色阴影。您可以将这些附加参数添加到函数中,或者为这些按钮创建与第一个类似的第二个函数

    或者,您也可以只创建两个循环,而不是定义一个函数。特别是如果第一组和第二组条目之间的差异更显著,这可能比使用两个非常相似的函数或一个参数非常多的函数更简单

    candies = [("Twix", Twix), ("Snickers", Snickers),
               ("Mars Bar", MarsBar), ("Godiva", Godiva)]
    font = ('arial',16,'bold')
    for i, (name, var) in enumerate(candies, start=1):
        label = Label(f1, font=font, text=name, bg='powder blue', bd=19, anchor='w')
        label.grid(row=2*i, column=0)
        entry = Entry(f1, font=font, textvariable=var, bg='powder blue', bd=10, insertwidth=4, justify='right')
        entry.grid(row=2*i, column=1)
    
    此外,与实际问题无关,
    DoubleVar
    对于巧克力这样的可计数数量似乎不是一个明智的选择。你的用户应该能够购买3.14火星酒吧吗?相反,我建议使用
    IntVar



    关于您的“修订代码”:有两个问题:第一,函数
    make_entry(f1,…)
    的使用不应该在函数内部,而是在根级别(无缩进)。其次,您意外地将
    textvariable=variable
    添加到
    标签
    构造函数中,它不属于该构造函数;仅对
    条目

    我看到了代码背后的逻辑,但由于某些原因,它不起作用。当我运行程序时,它似乎没有打印糖果名称,也没有打印用户输入数量的框。@user8244818刚刚注意到,字体大小和
    bd
    属性对于这两种类型的按钮也是不同的,因此您也可以为这两种按钮的函数添加参数。除此之外,当我尝试时,标签和条目看起来都很好。嗯,这很奇怪。我不明白为什么我的不行。您是否复制并粘贴了完整的代码?我还真的被卡住了。@user8244818我从链接复制了整个代码,用函数替换了四个巧克力条目中的两个,它们看起来都一样,并且工作正常。您确定您的代码没有与您在此期间发布的内容发生偏离吗?你到底看到了什么?您是否遇到错误,或者UI中缺少小部件?在我继续之前,我非常感谢您尝试帮助我,即使我仍然遇到困难。