V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
chaoyj
V2EX  ›  Python

关于 python.tkinter. 函数执行的疑惑

  •  
  •   chaoyj · 2015-03-14 21:26:14 +08:00 · 4521 次点击
    这是一个创建于 3546 天前的主题,其中的信息可能已经有所发展或是发生改变。

    代码部分:

    from Tkinter import *
    import tkMessageBox
    
    def getcode(mes):
        tkMessageBox.showinfo("get code", 'this code:'+mes)
    
    def win2(self):
        root2=Toplevel()
        aa = Entry(root2,width=5)
        aa.pack()
        bb=Button(root2,text='get')
        bb.pack()
        mes=aa.get()
        bb.bind("<Button-1>",getcode(mes))
        root2.mainloop()
    
    root = Tk()
    root.wm_title("TEST")
    
    zh = Button(root,text="Test")
    zh.bind("<Button-1>",win2)
    zh.pack()
    
    root.mainloop()
    

    刚开始学习GUI编程,但是想获得tkinter子窗口的数据时候发生了奇怪的错误。
    当点击Button:Test的时候,root2窗口弹出的同时触发了getcode函数,但是在root2窗口中点击Button:get无效。
    求解!

    13 条回复    2015-03-15 12:43:06 +08:00
    iptux
        1
    iptux  
       2015-03-14 22:38:12 +08:00   ❤️ 1
    bb.bind("<Button-1>",lambda obj,aa=aa:getcode(aa.get()))
    muzuiget
        2
    muzuiget  
       2015-03-14 22:45:39 +08:00   ❤️ 1
    bb.bind("<Button-1>",getcode(mes))

    注意,getcode(mes) 是传递了getcode(mes) 的返回结果,不是 getcode 函数本身,这段代码在进入 root.mainloop() 的时候就执行了,应该改成这样

    bb.bind("<Button-1>",getcode)
    chaoyj
        3
    chaoyj  
    OP
       2015-03-15 08:31:48 +08:00
    @iptux 谢谢,问题解决了。

    http://www.ssmys.com/wp-content/uploads/2015/03/ss.jpg

    但是点击之后为什么按钮一直处于按下状态,不会弹起呢?
    chaoyj
        4
    chaoyj  
    OP
       2015-03-15 08:33:12 +08:00
    提示
    TypeError: cannot concatenate 'str' and 'instance' objects
    chaoyj
        5
    chaoyj  
    OP
       2015-03-15 08:54:58 +08:00
    @muzuiget
    提示
    TypeError: cannot concatenate 'str' and 'instance' objects
    chaoyj
        6
    chaoyj  
    OP
       2015-03-15 09:18:17 +08:00
    @iptux
    经测试:bb.bind("<Button-1>",lambda obj:getcode(aa.get()))
    这样的语句也可用,
    但是为什么bb.bind("<Button-1>",lambda obj:getcode(mes))
    这样就获取不了值呢?
    上一句已经有了mes=aa.get()。
    lambda既然可以获取aa.get(),为什么不能获取mes呢?
    oott123
        7
    oott123  
       2015-03-15 10:23:57 +08:00 via Android   ❤️ 1
    虽然我不懂 tkinter ,但我只想说,楼主你需要明白变量作用域的问题。
    在 lambda 中也好,或者在 getcode 函数也好,他们本身是在另一个函数的作用域里,mes 这个变量是进不去的。
    oott123
        8
    oott123  
       2015-03-15 10:25:18 +08:00 via Android   ❤️ 1
    抱歉,我又仔细的看了看你的问题,作用域似乎并不能解释你的问题。

    我对 Python 并不熟悉,可能理解错了…
    oott123
        9
    oott123  
       2015-03-15 10:30:05 +08:00 via Android   ❤️ 1
    查了一些资料,考虑你的问题可能是 aa.get() 执行的时机不一样导致的。
    chaoyj
        10
    chaoyj  
    OP
       2015-03-15 10:47:30 +08:00
    @oott123 开始受到困扰的时候,我也想到了这方面,在一个函数中调用另一个函数和我想象的不一样。谢谢。
    oott123
        11
    oott123  
       2015-03-15 11:25:57 +08:00
    其实我想的是“原来 Python 也有闭包”……

    我的 Python 一直学得一知半解的2333
    muzuiget
        12
    muzuiget  
       2015-03-15 12:41:08 +08:00
    @chaoyj 你要搞清楚每一行什么时候才会运行,lambda 其实就是定义一个匿名函数。
    muzuiget
        13
    muzuiget  
       2015-03-15 12:43:06 +08:00
    @chaoyj 因为 mes 要是一个 tk 的 Event 对象,你用下 print 语句,在每行关键地方 print 一下,就知道整个程序代码的执行顺序了。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1162 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 24ms · UTC 18:42 · PVG 02:42 · LAX 10:42 · JFK 13:42
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.