鱼C论坛

 找回密码
 立即注册
查看: 546|回复: 3

[已解决]tkinter中的Button

[复制链接]
发表于 2018-12-5 17:40:44 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
想实现一个计算器,代码如下:
  1. from tkinter import *

  2. def verify(content):
  3.     if content.find(".")!=-1:
  4.         part1,dot,part2 = content.partition(".")
  5.         return (part1.isdigit()and part2.isdigit()) or( part1.isdigit()and part2=="")
  6.     return content.isdigit() or content==""


  7. root = Tk()

  8. testCMD = root.register(verify)
  9. #分开写不会影响内部元素的放置
  10. frame1 = Frame(root)
  11. frame1.pack(side=TOP,padx=10,pady=10)
  12. frame2 = Frame(root)
  13. frame2.pack(side=BOTTOM,padx=10,pady=10)

  14. label1 = Label(frame1,text="第一个数").grid(row=0,column=0,padx=5,pady=5)
  15. var1 = StringVar()
  16. #每次内容修改的时候,触发验证,如果返回True,就把内容给var1;%P表示当前内容
  17. entry1 = Entry(frame1,textvariable=var1,validate="key",
  18.                validatecommand=(testCMD,'%P'))
  19. entry1.grid(row=0,column=1,padx=5,pady=5)

  20. label2 = Label(frame1,text="第二个数").grid(row=1,column=0,padx=5,pady=5)
  21. var2 = StringVar()
  22. #每次内容修改的时候,触发验证,如果返回True,就把内容给var1;%P表示当前内容
  23. entry2 = Entry(frame1,textvariable=var2,validate="key",
  24.                validatecommand=(testCMD,'%P')).grid(row=1,column=1,padx=5,pady=5)

  25. label3 = Label(frame1,text="运算结果").grid(row=2,column=0,padx=5,pady=5)
  26. var3 = StringVar()
  27. #每次内容修改的时候,触发验证,如果返回True,就把内容给var1;%P表示当前内容
  28. entry3 = Entry(frame1,textvariable=var3,state="readonly").grid(row=2,column=1,padx=5,pady=5)

  29. def getvalue(value):
  30.     entry1.insert(END,value.get())
  31.     pass
  32. ''' if :       #entry1获得焦点
  33.         str1 = str(var1)+str(value.get())
  34.         var1.set(str1)
  35.     elif:       #entry2获得焦点
  36.         str1 = str(var2)+str(value.get())
  37.         var2.set(str1)'''
  38.    
  39.    
  40. buttonlist = []
  41. for i in range(16):
  42.     var = StringVar()
  43.     if i==3:
  44.         var.set("+")
  45.     elif i==7:
  46.         var.set("-")
  47.     elif i==11:
  48.         var.set("*")
  49.     elif i==12:
  50.         var.set(".")
  51.     elif i==13:
  52.         var.set("0")
  53.     elif i==14:
  54.         var.set("=")
  55.     elif i==15:
  56.         var.set("/")
  57.     elif i==0:
  58.         var.set("7")
  59.     elif i==1:
  60.         var.set("8")
  61.     elif i==2:
  62.         var.set("9")
  63.     elif i==8:
  64.         var.set("1")
  65.     elif i==9:
  66.         var.set("2")
  67.     elif i==10:
  68.         var.set("3")
  69.     else:
  70.         var.set(str(i))
  71.     button = Button(frame2,textvariable=var,command=getvalue(var),
  72.                     activebackground = "pink",activeforeground="yellow",width=5,height=3)
  73.     button.grid(row=(i//4),column=(i%4))
  74.     buttonlist.append(button)

  75. def add():
  76.     var3.set(str(float(var1.get())+float(var2.get())))
  77. button1 =Button(frame2,text="+",command=add).grid(row=4)

  78. def sub():
  79.     var3.set(str(float(var1.get())-float(var2.get())))
  80. button2 =Button(frame2,text="-",command=sub).grid(row=4,column=1)

  81. def mul():
  82.     var3.set(str(float(var1.get())*float(var2.get())))
  83. button3 =Button(frame2,text="*",command=mul).grid(row=4,column=2)

  84. def div():
  85.     var3.set(str(float(var1.get())/float(var2.get())))
  86. button4 =Button(frame2,text="/",command=div).grid(row=4,column=3)

  87. root.mainloop()
复制代码

(最下面的四个按钮可以正常执行)
现在的问题是,程序一开始运行,我还没有点击按钮(for循环中的按钮),它就调用了command的回调函数。
然后我再点击按钮就无效。这个是怎么回事?

效果图:
emmmm
放不上来


最佳答案
2018-12-5 22:03:39
本帖最后由 ba21 于 2018-12-5 22:04 编辑

花了个把小时来复习研究tkinter才算搞定。
tkinter只是简单的界面,复杂点的功能难以实现。不过你这个问题算是解决了。

command 如何传参:
command = lambda:test(i)


注意点:
循环动态生成的button都因有
  1、个自的 StringVar (多个button使用同1个值,另当别论)
  2、个自的 绑定的事件 (多个button使用同1个事件做一样的事,另当别论)
  3、循环生成的button应用一个list来存放;以便使用的时候调用。
  
4、最重要的一点, 你如何判断你点了哪一个button?
      我这里通过实践发现 button实例 等于 bind事件中 event.widget
      也就是 button1 == event.widget

  1. def test(event):
  2.     for i, b in enumerate(buttonList):        
  3.         if b == event.widget: # 通过绑定相同的事件,在事件中判断 button 是否等于 event.widget 判断按了哪个button
  4.             entry1.insert(END,buttonVar[i].get())
  5.    
  6. buttonList = []
  7. buttonVar = [] # 每个button都有各自的StringVar
  8. for i in range(16):
  9.     buttonVar.append(StringVar()) # 为减少循环次数,直接这里添加
  10.     if i==3:
  11.         buttonVar[i].set("+")
  12.     elif i==7:
  13.         buttonVar[i].set("-")
  14.     elif i==11:
  15.         buttonVar[i].set("*")
  16.     elif i==12:
  17.         buttonVar[i].set(".")
  18.     elif i==13:
  19.         buttonVar[i].set("0")
  20.     elif i==14:
  21.         buttonVar[i].set("=")
  22.     elif i==15:
  23.         buttonVar[i].set("/")
  24.     elif i==0:
  25.         buttonVar[i].set("7")
  26.     elif i==1:
  27.         buttonVar[i].set("8")
  28.     elif i==2:
  29.         buttonVar[i].set("9")
  30.     elif i==8:
  31.         buttonVar[i].set("1")
  32.     elif i==9:
  33.         buttonVar[i].set("2")
  34.     elif i==10:
  35.         buttonVar[i].set("3")
  36.     else:
  37.         buttonVar[i].set(str(i))
  38.     button = Button(frame2,textvariable=buttonVar[i],
  39.                     activebackground = "pink",activeforeground="yellow",width=5,height=3)
  40.     button.grid(row=(i//4),column=(i%4))
  41.     button.bind("<Button-1>",test)
  42.     buttonList.append(button)
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2018-12-5 22:03:39 | 显示全部楼层    本楼为最佳答案   
本帖最后由 ba21 于 2018-12-5 22:04 编辑

花了个把小时来复习研究tkinter才算搞定。
tkinter只是简单的界面,复杂点的功能难以实现。不过你这个问题算是解决了。

command 如何传参:
command = lambda:test(i)


注意点:
循环动态生成的button都因有
  1、个自的 StringVar (多个button使用同1个值,另当别论)
  2、个自的 绑定的事件 (多个button使用同1个事件做一样的事,另当别论)
  3、循环生成的button应用一个list来存放;以便使用的时候调用。
  
4、最重要的一点, 你如何判断你点了哪一个button?
      我这里通过实践发现 button实例 等于 bind事件中 event.widget
      也就是 button1 == event.widget

  1. def test(event):
  2.     for i, b in enumerate(buttonList):        
  3.         if b == event.widget: # 通过绑定相同的事件,在事件中判断 button 是否等于 event.widget 判断按了哪个button
  4.             entry1.insert(END,buttonVar[i].get())
  5.    
  6. buttonList = []
  7. buttonVar = [] # 每个button都有各自的StringVar
  8. for i in range(16):
  9.     buttonVar.append(StringVar()) # 为减少循环次数,直接这里添加
  10.     if i==3:
  11.         buttonVar[i].set("+")
  12.     elif i==7:
  13.         buttonVar[i].set("-")
  14.     elif i==11:
  15.         buttonVar[i].set("*")
  16.     elif i==12:
  17.         buttonVar[i].set(".")
  18.     elif i==13:
  19.         buttonVar[i].set("0")
  20.     elif i==14:
  21.         buttonVar[i].set("=")
  22.     elif i==15:
  23.         buttonVar[i].set("/")
  24.     elif i==0:
  25.         buttonVar[i].set("7")
  26.     elif i==1:
  27.         buttonVar[i].set("8")
  28.     elif i==2:
  29.         buttonVar[i].set("9")
  30.     elif i==8:
  31.         buttonVar[i].set("1")
  32.     elif i==9:
  33.         buttonVar[i].set("2")
  34.     elif i==10:
  35.         buttonVar[i].set("3")
  36.     else:
  37.         buttonVar[i].set(str(i))
  38.     button = Button(frame2,textvariable=buttonVar[i],
  39.                     activebackground = "pink",activeforeground="yellow",width=5,height=3)
  40.     button.grid(row=(i//4),column=(i%4))
  41.     button.bind("<Button-1>",test)
  42.     buttonList.append(button)
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 1 反对 0

使用道具 举报

 楼主| 发表于 2018-12-7 23:18:04 | 显示全部楼层
ba21 发表于 2018-12-5 22:03
花了个把小时来复习研究tkinter才算搞定。
tkinter只是简单的界面,复杂点的功能难以实现。不过你这个问题 ...

大佬,那我应该如何判断当前是哪个输入框获得了焦点呢
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2018-12-8 00:05:19 | 显示全部楼层
ba21 发表于 2018-12-5 22:03
花了个把小时来复习研究tkinter才算搞定。
tkinter只是简单的界面,复杂点的功能难以实现。不过你这个问题 ...

按你说的改了之后,是没有问题的,然后自己又弄了点又开始报错了
AttributeError: 'NoneType' object has no attribute 'insert'

  1. from tkinter import *

  2. def verify(content,name):
  3.     #print(name)
  4.     if name == ".!frame.!entry":
  5.         var12.set(1)
  6.     elif name == ".!frame.!entry2":
  7.         #print("123")
  8.         var12.set(2)
  9.    
  10.     if content.find(".")!=-1:
  11.         part1,dot,part2 = content.partition(".")
  12.         return (part1.isdigit()and part2.isdigit()) or( part1.isdigit()and part2=="")
  13.     return content.isdigit() or content==""


  14. root = Tk()
  15. var12 = IntVar()#判断是entry1和entry2

  16. testCMD = root.register(verify)
  17. #分开写不会影响内部元素的放置
  18. frame1 = Frame(root)
  19. frame1.pack(side=TOP,padx=10,pady=10)
  20. frame2 = Frame(root)
  21. frame2.pack(side=BOTTOM,padx=10,pady=10)

  22. label1 = Label(frame1,text="第一个数").grid(row=0,column=0,padx=5,pady=5)
  23. var1 = StringVar()
  24. #每次内容修改的时候,触发验证,如果返回True,就把内容给var1;%P表示当前内容
  25. entry1 = Entry(frame1,textvariable=var1,validate="key",
  26.                validatecommand=(testCMD,'%P','%W'))
  27. entry1.grid(row=0,column=1,padx=5,pady=5)

  28. label2 = Label(frame1,text="第二个数").grid(row=1,column=0,padx=5,pady=5)
  29. var2 = StringVar()
  30. #每次内容修改的时候,触发验证,如果返回True,就把内容给var1;%P表示当前内容
  31. entry2 = Entry(frame1,textvariable=var2,validate="key",
  32.                validatecommand=(testCMD,'%P','%W')).grid(row=1,column=1,padx=5,pady=5)

  33. label3 = Label(frame1,text="运算结果").grid(row=2,column=0,padx=5,pady=5)
  34. var3 = StringVar()
  35. #每次内容修改的时候,触发验证,如果返回True,就把内容给var1;%P表示当前内容
  36. entry3 = Entry(frame1,textvariable=var3,state="readonly").grid(row=2,column=1,padx=5,pady=5)


  37. def test(event):
  38.     for i, b in enumerate(buttonList):        
  39.         if b == event.widget: # 通过绑定相同的事件,在事件中判断 button 是否等于 event.widget 判断按了哪个button
  40.             #entry2.insert(END,buttonVar[i].get())
  41.             if var12.get()==2:            
  42.                 entry2.insert(END,buttonVar[i].get())#????
  43.             else:
  44.                 entry1.insert(END,buttonVar[i].get())
  45.    
  46. buttonList = []
  47. buttonVar = [] # 每个button都有各自的StringVar
  48. for i in range(16):
  49.     buttonVar.append(StringVar()) # 为减少循环次数,直接这里添加
  50.     if i==3:
  51.         buttonVar[i].set("+")
  52.     elif i==7:
  53.         buttonVar[i].set("-")
  54.     elif i==11:
  55.         buttonVar[i].set("*")
  56.     elif i==12:
  57.         buttonVar[i].set(".")
  58.     elif i==13:
  59.         buttonVar[i].set("0")
  60.     elif i==14:
  61.         buttonVar[i].set("=")
  62.     elif i==15:
  63.         buttonVar[i].set("/")
  64.     elif i==0:
  65.         buttonVar[i].set("7")
  66.     elif i==1:
  67.         buttonVar[i].set("8")
  68.     elif i==2:
  69.         buttonVar[i].set("9")
  70.     elif i==8:
  71.         buttonVar[i].set("1")
  72.     elif i==9:
  73.         buttonVar[i].set("2")
  74.     elif i==10:
  75.         buttonVar[i].set("3")
  76.     else:
  77.         buttonVar[i].set(str(i))
  78.     button = Button(frame2,textvariable=buttonVar[i],
  79.                     activebackground = "pink",activeforeground="yellow",width=5,height=3)
  80.     button.grid(row=(i//4),column=(i%4))
  81.     button.bind("<Button-1>",test) #这里??
  82.     buttonList.append(button)




  83. def add():
  84.     var3.set(str(float(var1.get())+float(var2.get())))
  85. button1 =Button(frame2,text="+",command=add).grid(row=4)

  86. def sub():
  87.     var3.set(str(float(var1.get())-float(var2.get())))
  88. button2 =Button(frame2,text="-",command=sub).grid(row=4,column=1)

  89. def mul():
  90.     var3.set(str(float(var1.get())*float(var2.get())))
  91. button3 =Button(frame2,text="*",command=mul).grid(row=4,column=2)

  92. def div():
  93.     var3.set(str(float(var1.get())/float(var2.get())))
  94. button4 =Button(frame2,text="/",command=div).grid(row=4,column=3)

  95. root.mainloop()
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-4-29 00:10

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表