如何将在计算器中按下的数字正确插入到最后一个索引的文本小部件中?

问题描述

例如,当我按下“ 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()

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...