使用Python计算器应用程序的GUI //为什么按钮不显示?

时间:2018-02-20 09:10:13

标签: python tkinter

在这里,我试图在Python中创建一个GUI计算器,用于名为“Chocolate Machine”的类赋值。

但我遇到了一个问题;下面的代码不打印GUI中的按钮!要查看我在说什么,请查看注释行下面的代码:

  

#CODE打印按钮不在下面

它基本上是按钮7,8,9和添加按钮,它应该出现在每个简单计算器的顶行。

有人可以协助并帮助我理解为什么这不起作用?我曾尝试使用包语句但它们也不起作用。

The tutorial I have been using是由DJ Oamen在YouTube上播出的。 附上两张图片,DJ Oamen的工作GUI之一,以及我不能使用的图片。

DJ Oamen的工作GUI计算器:

Working GUI Calculator by DJ Oamen

不工作的GUI计算器(无按钮):

Unworking GUI Calculator (no buttons)

from tkinter import *
import random
import time;

root = Tk()
root.geometry("1600x800+0+0")
root.title("Cameron's Chocolate Machine")

text_Input = StringVar()
operator = ""

Tops = Frame(root, width=1600, height=50, bg="powder 
blue",relief=SUNKEN)
Tops.pack(side=TOP)

f1 = Frame(root, width=800, height=700, bg="powder blue",relief=SUNKEN)
f1.pack(side=LEFT)

f2 = Frame(root, width=300, height=700, bg="powder blue",relief=SUNKEN)
f2.pack(side=RIGHT)

localtime = time.asctime(time.localtime(time.time()))
lblInfo = Label(Tops, font=('simplifica', 50, 'bold'), text="Cameron's Chocolate Machine",
    fg="Steel Blue",bd=10, anchor='w')
lblInfo.grid(row=0,column=0)

lblInfo = Label(Tops, font=('simplifica', 20), text=localtime,fg="Steel Blue",
    bd=10,anchor='w')
lblInfo.grid(row=1,column=0)

def btnClick(numbers):
    global operator
    operator= operator + str(numbers)
    text_Input.set(operator)

txtDisplay = Entry(f2, font=('arial',20,'bold'),textvariable=text_Input, bd=30, 
    insertwidth=4,bg='powder blue', justify='right')
txtDisplay.grid(columnspan=4)

#CODE THAT IS NOT PRINTING THE BUTTON IS BELOW
btn7=Button(f2,padx=16,pady=16,bd=8,fg="black",font=('arial', 20, 
    'bold'),text="7",bg="powder blue",command=lambda:btnClick(7).grid(row=2,column=0))

btn8=Button(f2,padx=16,pady=16,bd=8,fg="black",font=('arial', 20, 'bold'),
    text="8",bg="powder blue",command=lambda: btnClick(8).grid(row=2,column=1))

btn9=Button(f2,padx=16,pady=16,bd=8,fg="black",font=('arial', 20, 'bold'),
    text="9",bg="powder blue",command=lambda: btnClick(9).grid(row=2,column=2))

Addition=Button(f2,padx=16,pady=16,bd=8,fg="black",font=('arial', 20, 'bold'),
    text="9",bg="powder blue",command=lambda: btnClick("+").grid(row=2,column=3))

root.mainloop()

5 个答案:

答案 0 :(得分:1)

对于每个按钮,您需要为每个按钮设置一个网格以显示它们。 例如:

btn7.grid(row=0, column=0)

答案 1 :(得分:0)

在您的情况下,我建议您避免在与.grid()命令相同的句子中使用.Buttton()

制作计算器按钮的步骤如下:

  1. 首先创建Button小部件。
  2. 使用.grid()方法定位Button小部件。
  3. 当您制作多个类似的按钮小部件时,您可以编写一个函数来制作.Button()小部件,并选择定义按钮的文本显示。

    您还应该在in_=方法中添加.grid()选项,告诉tkinter按钮位于框架f2内。

    修订代码:

    from tkinter import *
    import random
    import time
    
    root = Tk()
    root.geometry("1600x800+0+0")
    root.title("Cameron's Chocolate Machine")
    
    text_Input = StringVar()
    operator = ""
    
    Tops = Frame(root, width=1600, height=50, bg="powder blue",relief=SUNKEN)
    Tops.pack(side=TOP)
    
    f1 = Frame(root, width=800, height=700, bg="powder blue",relief=SUNKEN)
    f1.pack(side=LEFT)
    
    f2 = Frame(root, width=300, height=700, bg="powder blue",relief=SUNKEN)
    f2.pack(side=RIGHT)
    
    localtime = time.asctime(time.localtime(time.time()))
    lblInfo = Label(Tops, font=('simplifica', 50, 'bold'), text="Cameron's Chocolate Machine",
        fg="Steel Blue",bd=10, anchor='w')
    lblInfo.grid(row=0,column=0)
    
    lblInfo = Label(Tops, font=('simplifica', 20), text=localtime,fg="Steel Blue",
        bd=10,anchor='w')
    lblInfo.grid(row=1,column=0)
    
    def btnClick(numbers):
        global operator
        operator= operator + str(numbers)
        text_Input.set(operator)
    
    txtDisplay = Entry(f2, font=('arial',20,'bold'),textvariable=text_Input, bd=30, 
        insertwidth=4,bg='powder blue', justify='right')
    txtDisplay.grid(columnspan=4)
    
    #CODE THAT IS NOT PRINTING THE BUTTON IS BELOW - AMENDED
    def btnCreate(number):
        """Function to make calculator button."""
        return Button(f2, padx=16, pady=16, bd=8, fg="black", bg="powder blue", 
                      font=('arial', 20,'bold'), text=str(number),
                      command=lambda:btnClick(number))
    
    btn7= btnCreate(7)
    btn8= btnCreate(8)
    btn9= btnCreate(9)
    badd= btnCreate('+')
    
    btn7.grid(in_=f2, row=2,column=0)
    btn8.grid(in_=f2, row=2,column=1)
    btn9.grid(in_=f2, row=2,column=2)
    badd.grid(in_=f2, row=2,column=3)
    
    #Below syntax is more cluttered  
    """Button(f2,padx=16,pady=16,bd=8,fg="black",font=('arial', 20, 
        'bold'),text="7",bg="powder blue",command=lambda:btnClick(7))
    btn7.grid(row=2,column=0)
    
    btn8=Button(f2,padx=16,pady=16,bd=8,fg="black",font=('arial', 20, 'bold'),
        text="8",bg="powder blue",command=lambda: btnClick(8))
    btn8.grid(row=2,column=1)
    
    btn9=Button(f2,padx=16,pady=16,bd=8,fg="black",font=('arial', 20, 'bold'),
        text="9",bg="powder blue",command=lambda: btnClick(9))
    btn9.grid(row=2,column=2)
    
    Addition=Button(f2,padx=16,pady=16,bd=8,fg="black",font=('arial', 20, 'bold'),
        text="9",bg="powder blue",command=lambda: btnClick("+"))
    Additional.grid(row=2,column=3)"""
    
    root.mainloop()
    

答案 2 :(得分:0)

单独使用计算器

enter image description here

from tkinter import *


def iCalc(source, side):
    storeObj = Frame(source, borderwidth=4, bd=4, bg="black")
    storeObj.pack(side=side, expand=YES, fill=BOTH)
    return storeObj


def button(source, side, text, command=None):
    storeObj = Button(source, text=text, command=command)
    storeObj.pack(side=side, expand=YES, fill=BOTH)
    return storeObj


class app(Frame):
    def __init__(self):
        Frame.__init__(self)
        self.option_add("*Font", "arial 20 bold")
        self.pack(expand=YES, fill=BOTH)
        self.master.title("Calculator")

        display = StringVar()
        # relief can be FLAT or RIDGE or RAISED or SUNKEN GROOVE
        Entry(self, relief=RIDGE, textvariable=display, justify='right', bd=30, bg='darkgray').pack(side=TOP, expand=YES, fill=BOTH)

        for clearBut in (["CE"], ["C"]):
            erase = iCalc(self, TOP)
            for ichar in clearBut:
                button(erase, LEFT, ichar, lambda storeObj=display, q=ichar: storeObj.set(""))
        for numBut in ("789/", "456*", "123-", "0.+"):
            functionNum = iCalc(self, TOP)
            for char in numBut:
                button(functionNum, LEFT, char, lambda storeObj=display, q=char: storeObj.set(storeObj.get() + q))
        equalButton = iCalc(self, TOP)
        for iEqual in "=":
            if iEqual == "=":
                btniEqual = button(equalButton, LEFT, iEqual)
                btniEqual.bind("<ButtonRelease-1>", lambda e, s=self, storeObj=display: s.calc(storeObj), '+')
            else:
                btniEqual = button(equalButton, LEFT, iEqual, lambda storeObj=display, s='%s' % iEqual: storeObj.set(storeObj.get() + s))

    def calc(self, display):
        try:
            display.set(eval(display.get()))
        except:
            display.set("ERROR")


if __name__ == '__main__':
    app().mainloop()

右框中的计算器......

from tkinter import *
import random
import time

root = Tk()
root.geometry("1600x800+0+0")
root.title("Cameron's Chocolate Machine")

text_Input = StringVar()
operator = ""

Tops = Frame(root, width=1600, height=50, bg="powder blue", relief=SUNKEN)
Tops.pack(side=TOP)

f1 = Frame(root, width=1200, height=700, bg="powder blue", relief=SUNKEN)
f1.pack(side=LEFT)


localtime = time.asctime(time.localtime(time.time()))
lblInfo = Label(Tops, font=('simplifica', 50, 'bold'), text="Cameron's Chocolate Machine", fg="Steel Blue", bd=10, anchor='w')
lblInfo.grid(row=0, column=0)

lblInfo = Label(Tops, font=('simplifica', 20), text=localtime, fg="Steel Blue",
                bd=10, anchor='w')
lblInfo.grid(row=1, column=0)


def btnClick(numbers):
    global operator
    operator = operator + str(numbers)
    text_Input.set(operator)


def iCalc(source, side):
    storeObj = Frame(source, borderwidth=4, bd=4, bg="black")
    storeObj.pack(side=side, expand=YES, fill=BOTH)
    return storeObj


def button(source, side, text, command=None):
    storeObj = Button(source, text=text, command=command)
    storeObj.pack(side=side, expand=YES, fill=BOTH)
    return storeObj


class app(Frame):
    def __init__(self):
        Frame.__init__(self)
        self.option_add("*Font", "arial 20 bold")
        self.pack(expand=YES, fill=BOTH)
        self.master.title("Calculator")

        display = StringVar()
        # relief can be FLAT or RIDGE or RAISED or SUNKEN GROOVE
        Entry(self, relief=RIDGE, textvariable=display, justify='right', bd=30, bg='darkgray').pack(side=TOP, expand=YES, fill=BOTH)

        for clearBut in (["CE"], ["C"]):
            erase = iCalc(self, TOP)
            for ichar in clearBut:
                button(erase, LEFT, ichar, lambda storeObj=display, q=ichar: storeObj.set(""))
        for numBut in ("789/", "456*", "123-", "0.+"):
            functionNum = iCalc(self, TOP)
            for char in numBut:
                button(functionNum, LEFT, char, lambda storeObj=display, q=char: storeObj.set(storeObj.get() + q))
        equalButton = iCalc(self, TOP)
        for iEqual in "=":
            if iEqual == "=":
                btniEqual = button(equalButton, LEFT, iEqual)
                btniEqual.bind("<ButtonRelease-1>", lambda e, s=self, storeObj=display: s.calc(storeObj), '+')
            else:
                btniEqual = button(equalButton, LEFT, iEqual, lambda storeObj=display, s='%s' % iEqual: storeObj.set(storeObj.get() + s))

    def calc(self, display):
        try:
            display.set(eval(display.get()))
        except:
            display.set("ERROR")


app().mainloop()
root.mainloop()

代码说明

  

我按照C S.的要求在这里放了一些代码的解释。我稍后会回来添加更详细的解释,也许还有一个视频。

from tkinter import *
import time


# initialize the window
root = Tk()
# we put the dimension and position of left corner of the window
root.geometry("1600x800+0+0")
# the title of the window
root.title("Cameron's Chocolate Machine")

# variable to be used later
text_Input = StringVar()
operator = ""

# we have a frame inside the window object root, width 1600 and 50 height
Tops = Frame(root, width=1600, height=50, bg="powder blue", relief=SUNKEN)
# this makes it visible
Tops.pack(side=TOP)

# another frame of 1200 x 700
f1 = Frame(root, width=1200, height=700, bg="powder blue", relief=SUNKEN)
f1.pack(side=LEFT)

# this gets the time
localtime = time.asctime(time.localtime(time.time()))
# here is the big title into a label
lblInfo = Label(Tops, font=('simplifica', 50, 'bold'), text="Cameron's Chocolate Machine", fg="Steel Blue", bd=10, anchor='w')
# this shows the label and put it at row 0, col 0
lblInfo.grid(row=0, column=0)
# This is another label for the time in the row 1, same column as befor
lblInfo = Label(Tops, font=('simplifica', 20), text=localtime, fg="Steel Blue",
                bd=10, anchor='w')
lblInfo.grid(row=1, column=0)

# this puts the digit into the text_Input variable = StringVar() we saw before
def btnClick(numbers):
    global operator
    operator = operator + str(numbers)
    text_Input.set(operator)

# This function creates a frame and makes it visible
def iCalc(source, side):
    storeObj = Frame(source, borderwidth=4, bd=4, bg="black")
    storeObj.pack(side=side, expand=YES, fill=BOTH)
    return storeObj

# This is a constructor for each button of the calculator
# when you call this function it returns a button
def button(source, side, text, command=None):
    storeObj = Button(source, text=text, command=command)
    storeObj.pack(side=side, expand=YES, fill=BOTH)
    return storeObj

# this is the main app for the calculator
class app(Frame):
    def __init__(self):
        # this creates the frame for the calculator
        Frame.__init__(self)
        self.option_add("*Font", "arial 20 bold")
        self.pack(expand=YES, fill=BOTH)
        self.master.title("Calculator")
        # this is a variable to get the value of the following entry object
        display = StringVar()
        # relief can be FLAT or RIDGE or RAISED or SUNKEN GROOVE
        Entry(self, relief=RIDGE, textvariable=display, justify='right', bd=30, bg='darkgray').pack(side=TOP, expand=YES, fill=BOTH)

        for clearBut in (["CE"], ["C"]):
            erase = iCalc(self, TOP)
            for ichar in clearBut:
                button(erase, LEFT, ichar, lambda storeObj=display, q=ichar: storeObj.set(""))
        # here we create all the buttons passing
        for numBut in ("789/", "456*", "123-", "0.+"): # for each of this strings
            functionNum = iCalc(self, TOP) # this is the frame for each string of three symmbols
            for char in numBut: # for every number of symbol in each line ("789" for ex.)
                # a button is created
                button(functionNum, LEFT, char, lambda storeObj=display, q=char: storeObj.set(storeObj.get() + q))
        equalButton = iCalc(self, TOP)
        for iEqual in "=":
            if iEqual == "=":
                btniEqual = button(equalButton, LEFT, iEqual)
                btniEqual.bind("<ButtonRelease-1>", lambda e, s=self, storeObj=display: s.calc(storeObj), '+')
            else:
                btniEqual = button(equalButton, LEFT, iEqual, lambda storeObj=display, s='%s' % iEqual: storeObj.set(storeObj.get() + s))

    def calc(self, display):
        try:
            display.set(eval(display.get()))
        except:
            display.set("ERROR")


app().mainloop()
root.mainloop()

答案 3 :(得分:0)

您在以下几行中遇到同样的错误:

btn7=Button(...,command=lambda:btnClick(7).grid(...))

btn8=Button(...,command=lambda: btnClick(8).grid(...))

btn9=Button(...,command=lambda: btnClick(9).grid(...))

Addition=Button(...,command=lambda: btnClick("+").grid(...))

错误是布局管理器方法调用(grid(...))包含在命令引用中,而不是在小部件上调用。只需修复移动最后一个右括号的错误,就在grid调用之前:

btn7=Button(...,command=lambda:btnClick(7)).grid(...)

btn8=Button(...,command=lambda: btnClick(8)).grid(...)

btn9=Button(...,command=lambda: btnClick(9)).grid(...)

Addition=Button(...,command=lambda: btnClick("+")).grid(...)

这是可怕的,因为btn7btn8btn9Addition都是None。更好地分离布局方法:

btn7=Button(...)
btn8=Button(...)
btn9=Button(...)
Addition=Button(...)
...
btn7.grid(...)
btn8.grid(...)
btn9.grid(...)
Addition.grid(...)

答案 4 :(得分:0)

您可以用更少的代码行使更好的 ui 更好的颜色。看看我的Calculator_PRO

这是生成按钮并将其放置在相应坐标处的部分

click here to see the demo

示例代码:

from tkinter import *

# Caculator GUI
window = Tk()
window.title("Calculator PRO v"+str(version))
window.geometry("270x430")
window.configure(background='#1F2937')


Input = Label(window,bg = '#1F2937', text = "0", anchor="e", justify=RIGHT, width=11, font=('', 36))
Input.place(x=0, y=30)

btns = []
btn_names = ['DEL', 'C', 'x²', '√','1', '2', '3', '+', '4', '5', '6', '-', '7', '8', '9', 'x', '.', '0', '=', '÷']

# Generate Buttons
for btn in btn_names:
    if btn in "1234567890.": color = "#10B981"
    if btn in ('+', '-', 'x', '÷', '√', 'x²'): color = "#F59E0B"
    if btn in "=": color = "#047857"
    if btn in ("C", "DEL"): color = "#2563EB"
    btns.append(Button(window, text=btn, width=55, height=55, font=('', 18), bg = color, command=lambda btn=btn: getInput(btn)))

# Place those buttons
row = 0
col = 0
top_pad = 100
left_pad = 10
for btn in btns:
    if col >= 4:
        col = 0
        row += 1
    if row >= 5: break
    btn.place(x = (col*65+left_pad), y = (row*65+top_pad))
    col += 1


window.mainloop()