如何停止while循环以使用Tkinter从用户那里获取输入? [英] How to stop a while loop to get input from user using Tkinter?

查看:47
本文介绍了如何停止while循环以使用Tkinter从用户那里获取输入?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

令人难以置信的是,如此基本的知识如何被埋葬在一个如此难以找到的地方.我花了将近一个月的时间在谷歌上搜索答案——观看视频、阅读文档、书籍等——关于如何停止 while 循环以从使用 Tkinter 的用户那里获取输入.

it is incredible how the knowledge of something so basic can be buried in a so hard to find place. I have spent close to a month googling for an answer--watching videos, reading documents, books, etc--of how to stop a while loop to get input from an user using Tkinter.

我下面的代码循环了两次并在我能够提供输入之前离开循环!!!

My code below is looping twice and leaving the loop before I am able to provide an input!!!

无论如何,理论是值得赞赏的,但示例代码将有更大的帮助.非常非常非常感谢.

Anyway, theory is appreciated, but a sample code will be of greater help. Thank you very, very much indeed.

# Python 3.5.1
from tkinter import *
from tkinter import ttk

loop = 0

while loop < 2:

    print ('loop')

    def user_data():
        user_input = data.get()
        print (user_input)

    lb=ttk.Label(root, text="Enter data")
    data=ttk.Entry(root)
    bt=ttk.Button(root, text='Ok', command=user_data)

    lb.grid(row=0, column=1)
    data.grid(row=0, column=2)
    bt.grid(row=0, column=3)

    loop += 1

print ('left loop')

root.mainloop()

推荐答案

好吧,我觉得这个笑话毕竟是在我身上.:-) 我花了三天时间告诉你这不容易做到,结果我错了.

Ok, I think the joke is on me after all. :-) I spent last three days telling you this can't be done easily, and it turns out I was wrong.

我很快就会给你代码,让我解释一下我哪里出错了.在我写最后一条评论时,我想向您解释的主要内容是,当您在 GUI 控制台中运行控制台 Python 程序时,这是两个不同的进程,而 GUI 的事件循环与如何内部 Python 程序有效.

I'll give you the code soon, just let me explain where I went wrong. While I was writing my last comment, the main thing I wanted to explain to you is that when you run a console Python program inside a GUI console, those are two different processes, and the event loop of a GUI has nothing to do with how the inner Python program works.

在 GUI 应用程序中,它会崩溃,因为只有一个进程,并且它的事件循环不能同时运行(响应正常的应用程序事件,如重新绘制窗口或处理点击/按键)并保持阻塞状态(等待供您单击按钮).我突然想到,如果 tkinter 能让用户创建额外的事件循环,事情就会变得非常简单.这并非不合理:因为 tkinter 已经为自己的目的构造了一个,它只需要向用户公开该构造函数(或其他一些构造方法).并且不会有任何 GIL 问题,因为另一个事件循环只是保持阻塞状态(只有一个在实际执行).

In a GUI application, it breaks down since there is just one process, and its event loop cannot at the same time run (being responsive to normal app events like repainting a window or handling clicks/keypresses) and stay blocked (wait for you to click a button). It occured to me the things would be very simple if tkinter would enable the user to make additional event loops. It's not unreasonable: since tkinter already constructs one for its own purposes, it just needs to expose that constructor (or some other means of construction) to the user. And there won't be any GIL problems, since the other event loop just stays blocked (only one is actually executing).

一旦我知道了我要搜索的内容,就不难找到了:您构造一个 Tk 变量(任何类型,布尔值都适用于这种语义),切换其值,然后在回调中将其切换回.与此同时,你等待它改变.非常简单.:-)

Once I knew what I was searching, it wasn't so hard to find: you construct a Tk variable (of any type, Boolean works nice for this semantics), toggle its value, and toggle it back in the callback. In the meantime you wait for it to change. Easy as pie. :-)

我尝试尽可能少地更改您的代码,但是当然,一旦您了解了该机制,您就可以做得更好.我希望我已经恢复了您对 tkinter 的信心.:-)

I tried to change your code as little as possible, but of course, once you know the mechanism, you can do it much more nicely. I hope I've returned your faith in tkinter. :-)

from tkinter import *
from tkinter import ttk

root = Tk()
loop = 0
block = BooleanVar(root, False)

while loop < 2:

    print ('loop')

    def user_data():
        user_input = data.get()
        print (user_input)
        block.set(False)

    lb=ttk.Label(root, text="Enter data")
    data=ttk.Entry(root)
    bt=ttk.Button(root, text='Ok', command=user_data)

    lb.grid(row=0, column=1)
    data.grid(row=0, column=2)
    bt.grid(row=0, column=3)

    block.set(True)
    root.wait_variable(block)
    loop += 1

print ('left loop')
root.mainloop()

这篇关于如何停止while循环以使用Tkinter从用户那里获取输入?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆