当前位置: 首页 > 面试题库 >

Tkinter与我的主循环一起管理我的事件循环

谭景明
2023-03-14
问题内容

我一直在慢慢学习Tkinter和面向对象的编程,但是我已经将自己编程与此有关。请原谅我对这一观点缺乏批判性思考,但是我已经问过我认识的每个人,谁比我更了解python,所以我们不能在这里找到可行的解决方案

我有一个正在运行的gui应用程序,它允许用户输入股票代码,为每个代码创建新标签,然后定期更新每个标签。(有点像一个非常基本的电子商务应用程序之类的东西)。我发现没有gui做到这一点真的很容易,因为我可以说:

while True:
   sPrice = get_stock_price(s)
   print sPrice

但是我已经将我的get_stock_price(s)函数绑定到了一个按钮,该按钮产生了一个子框架和其中包含的标签。我遇到的问题是标签不会更新。一位朋友建议添加仅用于更新标签的另一种方法,但是我知道如何不断更新标签的唯一方法是

while True:
    # get new price
    # update the label
    # time.sleep(~1 minute?)

这会使我的GUI窗口永久冻结并旋转。我一直在阅读与该特定情况相关的所有其他线程,并且看到了许多不同的建议。不要在您的主线程中调用sleep,不要使用root.update,不要使用事件,不要调用root.something.after(500,function)并且我已经尝试实现。我剩下的是一个弗兰肯斯坦代码,仍然可以检索我的股票价值,但不会更新它们,还有一些我不知道如何更新或在代码中调用的方法。

我所希望的是(可能很长,我知道。很抱歉!)我做错了什么的解释,以及有关如何解决它的建议。我真的想亲自理解和解决该问题,但是只要能解释它们,代码解决方案就很棒。

提前非常感谢!!!

PS:到目前为止,这是我的代码:

from Tkinter import *
import urllib
import re
import time

class MyApp(object):
    def __init__(self, parent):
        self.myParent = parent
        self.myContainer1 = Frame(parent)
        self.myContainer1.pack()
        self.createWidgets()
        button1 = Button(self.myContainer1, command = self.addStockToTrack)
        self.myContainer1.bind("<Return>", self.addStockToTrack)
        button1.configure(text = "Add Symbol")
        button1.pack()

    def createWidgets(self):
        # title name
        root.title("Stock App")
        # creates a frame inside myContainer1
        self.widgetFrame = Frame(self.myContainer1)
        self.widgetFrame.pack()
        # User enters stock symbol here:
        self.symbol = Entry(self.widgetFrame) 
        self.symbol.pack()
        self.symbol.focus_set()

    def addStockToTrack(self):
        s = self.symbol.get()
        labelName = str(s) + "Label"
        self.symbol.delete(0, END)
        stockPrice = get_quote(s)
        self.labelName = Label(self.myContainer1, text = s.upper() + ": " + str(stockPrice))
        self.labelName.pack()
        self.myContainer1.after(500, self.get_quote)

    def updateStock(self):
        while True:
            labelName = str(s) + "Label"
            stockPrice = get_quote(s)
            self.labelName = Label(self.myContainer1, text = s.upper() + ": " + str(stockPrice))
            self.labelName.pack()
            time.sleep(10)

def get_quote(symbol):
    base_url = 'http://finance.google.com/finance?q='
    content = urllib.urlopen(base_url + symbol).read()
    m = re.search('id="ref_\d*_l".*?>(.*?)<', content)
    if m:
        quote = m.group(1)
    else:
        quote = 'Not found: ' + symbol
    return quote

root = Tk()
myapp = MyApp(root)
root.mainloop()

问题答案:

您已经在运行一个无限循环,因此您不应该尝试添加另一个循环。相反,您可以使用该after方法使函数被如此频繁地重复调用。在您的情况下,您可以替换为:

def updateStock(self):
   while True:
        labelName = str(s) + "Label"
        stockPrice = get_quote(s)
        self.labelName = Label(self.myContainer1, text = s.upper() + ": " + str(stockPrice))
        self.labelName.pack()
        time.sleep(10)

… 有了这个:

def updateStock(self):
    labelName = str(s) + "Label"
    stockPrice = get_quote()
    self.labelName = Label(self.myContainer1, text = s.upper() + ": " + str(stockPrice))
    self.labelName.pack()
    self.after(10000, self.updateStock)

这将得到报价,添加标签,然后安排自己在10秒(10,000毫秒)内再次被调用。

但是,我怀疑您想每10秒创建一个新标签吗?最终,窗口将充满标签。相反,您可以创建一次标签,然后在每次迭代中更新标签。例如,self.label在init中创建一次,然后在循环中可以执行以下操作:

self.labelName.configure(text=s.upper() + ": " + str(stockPrice))


 类似资料:
  • 问题内容: 如何从单独的对象调用tkinter ? 我在寻找类似wxWidgets的东西。例如,如果我创建一个对象,并将其根实例传递给它,然后尝试从我的对象中调用该根窗口的方法,则我的应用程序将锁定。 我能想到的最好的方法是使用该方法并从单独的对象检查状态,但这似乎很浪费。 问题答案: 要回答“如何从单独的对象调用TkInter事件”这一特定问题,请使用命令。它允许您将事件注入到根窗口的事件队列中

  • 现在我们已经初步了解了libevent的Reactor组件——event_base和事件管理框架,接下来就是libevent事件处理的中心部分——事件主循环,根据系统提供的事件多路分发机制执行事件循环,对已注册的就绪事件,调用注册事件的回调函数来处理事件。 1 阶段性的胜利 Libevent将I/O事件、定时器和信号事件处理很好的结合到了一起,本节也会介绍libevent是如何做到这一点的。   

  • 问题内容: 我有以下代码: 这里的主要循环是: 但是我不确定这是做到这一点的最佳方法(如果我想输入一些信息,这将不起作用) 然后我尝试了这个: 但是,正如我已经意识到的那样,它并没有达到我的预期。所以问题是:创建主循环的最佳方法是什么? 问题答案: Tkinter为此提供了一个强大的工具,它被称为after。它旨在用作同步睡眠命令,但可以通过调用自身在mainloop内建立一个循环。 之后,是一个

  • 问题内容: 到现在为止,我以前以:结束我的Tkiter程序,否则什么都不会出现!参见示例: 但是,当尝试该程序的下一步(使球随着时间移动)时,该书正在阅读,并说要执行以下操作。将绘图功能更改为: 并将以下代码添加到我的程序中: 但是我注意到,添加此代码块使之无用,因为即使没有它,所有内容也会显示出来!!! 此时,我应该提到我的书从未谈论过(也许是因为它使用了Python 3),但是由于我的程序无法

  • 我有以下代码: 这里的主要循环是: 但是我不确定这是最好的方法(如果我想输入什么,这是行不通的) 然后我试了这个: 但正如我所意识到的,这并不像我预期的那么快。所以问题是:创建主循环的最佳方法是什么?

  • //问题本身(之后的代码) 变量n是随机生成的整数。输出字符“*”和“#”,使第一行只包含星号,最后一行只包含数字符号。在每一个连续的行中,恒星的数量减少。行中的字符总数为n,有n+1行。