在这里,我试图在Python中创建一个GUI计算器,用于名为“Chocolate Machine”的类赋值。
但我遇到了一个问题;下面的代码不打印GUI中的按钮!要查看我在说什么,请查看注释行下面的代码:
#CODE打印按钮不在下面
它基本上是按钮7,8,9和添加按钮,它应该出现在每个简单计算器的顶行。
有人可以协助并帮助我理解为什么这不起作用?我曾尝试使用包语句但它们也不起作用。
The tutorial I have been using是由DJ Oamen在YouTube上播出的。 附上两张图片,DJ Oamen的工作GUI之一,以及我不能使用的图片。
DJ Oamen的工作GUI计算器:
不工作的GUI计算器(无按钮):
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()
答案 0 :(得分:1)
对于每个按钮,您需要为每个按钮设置一个网格以显示它们。 例如:
btn7.grid(row=0, column=0)
答案 1 :(得分:0)
在您的情况下,我建议您避免在与.grid()
命令相同的句子中使用.Buttton()
。
制作计算器按钮的步骤如下:
.grid()
方法定位Button小部件。当您制作多个类似的按钮小部件时,您可以编写一个函数来制作.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)
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(...)
这是可怕的,因为btn7
,btn8
,btn9
和Addition
都是None
。更好地分离布局方法:
btn7=Button(...)
btn8=Button(...)
btn9=Button(...)
Addition=Button(...)
...
btn7.grid(...)
btn8.grid(...)
btn9.grid(...)
Addition.grid(...)
答案 4 :(得分:0)
您可以用更少的代码行使更好的 ui 更好的颜色。看看我的Calculator_PRO。
这是生成按钮并将其放置在相应坐标处的部分
示例代码:
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()