问题描述
例如,当我按下“ 100”时,在文本框中输出“ 001”。我尝试在索引中使用-1,但仍然发生同样的事情,我也尝试执行.insert(0。end,num),但是会引发错误。如何将数字始终输入到输出的末尾。另外,这是使用tkinter输出数字的最佳方法还是还有其他方法?
from tkinter import *
import operator
window = Tk()
window.title('Calculator')
def click(num):
output.insert(0.0,num) #numbers not properly inputted (bug)
#output for calculator
output = Text(window,font = 'none 12 bold',height = 4,width = 25,wrap = 'word')
output.grid(row = 0,column = 0,columnspan = 4,pady = 10)
###buttons
#clear and operators
b_clear = Button(window,text = 'C',width = 7,height = 3)
b_clear.grid(row = 1,column = 2,padx = (10,0))
b_div = Button(window,text = '/',height = 3)
b_div.grid(row = 1,column = 3,padx = 10)
b_mult = Button(window,text = '*',height = 3)
b_mult.grid(row = 2,column = 3)
b_subt = Button(window,text = '-',height = 3)
b_subt.grid(row = 3,column = 3)
b_add = Button(window,text = '+',height = 3)
b_add.grid(row = 4,column = 3)
b_equal = Button(window,text = '=',height = 3)
b_equal.grid(row = 5,pady = (0,10))
#numbers
b_9 = Button(window,text = '9',height = 3,command = lambda: click(9))
b_9.grid(row = 2,0),pady = 10)
b_8 = Button(window,text = '8',command = lambda: click(8))
b_8.grid(row = 2,column = 1)
b_7 = Button(window,text = '7',command = lambda: click(7))
b_7.grid(row = 2,padx = 10)
b_6 = Button(window,text = '6',command = lambda: click(6))
b_6.grid(row = 3,0))
b_5 = Button(window,text = '5',command = lambda: click(5))
b_5.grid(row = 3,column = 1)
b_4 = Button(window,text = '4',command = lambda: click(4))
b_4.grid(row = 3,column = 0)
b_3 = Button(window,text = '3',command = lambda: click(3))
b_3.grid(row = 4,pady = 10)
b_2 = Button(window,text = '2',command = lambda: click(2))
b_2.grid(row = 4,column = 1)
b_1 = Button(window,text = '1',command = lambda: click(1))
b_1.grid(row = 4,column = 0)
b_0 = Button(window,text = '0',command = lambda: click(0))
b_0.grid(row = 5,10))
b_decimal = Button(window,text = '.',height = 3)
b_decimal.grid(row = 5,column = 1,10))
b_negative = Button(window,height = 3)
b_negative.grid(row = 5,10))
#run calculator
window.mainloop()
解决方法
索引“ end”表示窗口小部件中最后一个字符之后的位置。
output.insert("end",num)
摘自官方文件:
,结尾-表示条目字符串中最后一个字符之后的字符。这等效于指定一个等于条目字符串长度的数字索引。
您的工作方式太辛苦了。从图形的角度来看,您必须考虑按钮完全相同。您只需几行就可以构建整个界面。由于每个按钮都将调用calc
,因此只需在calc
中编写条件语句即可处理各种可能性。您可以在一个功能中构建计算器的全部功能。
import tkinter as tk
window = tk.Tk()
window.title('Calculator')
#output for calculator
output = tk.Text(window,font = 'none 12 bold',height=4,width=25,wrap='word')
output.grid(row=0,column=0,columnspan=4,pady=10)
def calc(data):
if data.isnumeric() or data == '.':
output.insert('end',data)
elif data in ['-','+','*','/']:
#write code for handling operators
pass #delete this line
elif data == '=':
#write code for handling equals
pass #delete this line
elif data == 'pos':
if output.get('1.0','1.1') == '-':
output.delete('1.0','1.1')
elif data == 'neg':
if output.get('1.0','1.1') != '-':
output.insert('1.0','-')
elif data in 'CE':
if 'C' in data:
output.delete('1.0','end')
if 'E' in data:
#clear your storage
pass #delete this line
btn = dict(width=7,height=3)
pad = dict(padx=5,pady=5)
#all of your buttons
for i,t in enumerate(['pos','neg','C','CE','7','8','9','/','4','5','6','1','2','3','-','0','.','=']):
tk.Button(window,text=t,command=lambda d=t: calc(d),**btn).grid(row=i//4+1,column=i%4,**pad)
#run calculator
window.mainloop()
根据我刚才给您的示例,我制作了一个完全可用的OOP计算器版本。这可能并不完美。我只花了10分钟。我添加了按键绑定,因此您不必单击按钮。您可以扩展它,从中学习,忽略它……让您感到高兴的一切。
import tkinter as tk
class App(tk.Tk):
def __init__(self):
tk.Tk.__init__(self)
self.oper = ['/','+']
self.queue = []
self.result = 0
self.equate = False
self.output = tk.Text(self,font='Consolas 18 bold',height=2,width=20,wrap='word')
self.output.grid(row=0,pady=8,padx=4)
btn = dict(width=6,height=3,font='Consolas 12 bold')
pad = dict(pady=2)
special = dict(neg='<Shift-Key-->',pos='<Shift-Key-+>',C='<Key-Delete>',CE='<Key-End>')
for i,'=']):
tk.Button(self,command=lambda d=t: self.calc(d),**pad)
if t.isnumeric() or t in self.oper or t == '.':
self.bind_all(f'<Key-{t}>',lambda e,d=t: self.calc(d))
elif t == '=':
self.bind_all('<Return>',d=t: self.calc(d))
else:
self.bind_all(special[t],d=t: self.calc(d))
def calc(self,input):
print(input)
if input.isnumeric() or input == '.':
self.output.insert('end',input)
elif input == 'pos':
if self.output.get('1.0','1.1') == '-':
self.output.delete('1.0','1.1')
elif input == 'neg':
if self.output.get('1.0','1.1') != '-':
self.output.insert('1.0','-')
elif input in self.oper and (t := self.output.get('1.0','end-1c')):
if not self.equate:
self.queue.append(t)
self.queue.append(input)
self.output.delete('1.0','end')
self.equate = False
elif input == '=' and len(self.queue):
self.equate = True
if self.queue[-1] in self.oper:
self.queue.append(self.output.get('1.0','end-1c'))
elif len(self.queue) > 2:
self.queue = self.queue+self.queue[-2:]
self.result = str(eval(' '.join(self.queue)))
self.output.delete('1.0','end')
self.output.insert('end',self.result)
elif input in 'CE':
if 'C' in input:
self.output.delete('1.0','end')
if 'E' in input:
self.queue = []
if __name__ == '__main__':
app = App()
app.title('Calcsturbator')
app.resizable(width=False,height=False)
app.mainloop()