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

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何成功抽象以下代码行? (Python Tkinter GUI)相关的知识,希望对你有一定的参考价值。

我正在尝试在Python中创建一个名为“Chocolate Vending Machine”的类赋值GUI。学生必须使用Python的Tkinter。我们列出了一些巧克力品牌,如士力架,Twix和火星,并在每个品牌上加上价格标签。用户完成以下步骤:

  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语句以更有效的方式重写代码?

我试图抽象上面的代码,但它没有用。任何帮助表示赞赏。

答案

您可以使用给定参数定义用于创建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

以上是关于如何成功抽象以下代码行? (Python Tkinter GUI)的主要内容,如果未能解决你的问题,请参考以下文章

python10行代码,让你成功伪装逃过反爬虫程序

如何从 python 脚本成功调用 gsutil rsync?

Python图形用户界面

Python3 - 如何从现有抽象类定义抽象子类?

Python---计算器

如何从用 C# 编写的抽象基类继承