如何成功地抽象出以下代码行?(Python Tkinter GUI)

2024-05-08 02:32:18 发布

您现在位置:Python中文网/ 问答频道 /正文

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

  1. 输入他有多少钱的浮动值(可以是任何值)
  2. 他选择每种巧克力要多少
  3. 该值被打印到控制台的“总成本”下
  4. 原始余额(他原来有多少钱)减去总成本打印出新的余额

请参考下面的代码。如何提取以下代码行,使其仍然有效,但限制行数?请注意,我没有粘贴整个应用程序的代码,因为它的代码行太多了。所以这里有一个小片段来缩小范围:

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

以下是完整的非抽象代码的链接:

https://docs.google.com/document/d/1tMJxmFAMWyc6qhTFnhoedQmj49Qkf56rJxhxB8Z3fSM/edit?usp=sharing

如您所见,上面粘贴的每一行代码都与按钮和框的样式有关,用户可以输入程序执行其任务所需的信息。话虽如此,我重申一个问题:

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

我试图抽象上面的代码,但它没有工作。感谢您的帮助。你知道吗


Tags: 代码textcolumnbluebdgridrowf1
1条回答
网友
1楼 · 发布于 2024-05-08 02:32:18

您可以定义一个函数,用给定的参数创建LabelEntry

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

如果以后需要的话,您可能还拥有函数return label, entry,但是看起来变量已经足够了。你知道吗

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

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

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添加到Label构造函数中,它不属于该构造函数;只属于Entry。你知道吗

相关问题 更多 >