创建一个用python自身更新信息的GUI

2024-09-22 20:30:00 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在为一个竞赛创建一个python程序,显示股票价格,股票价格每分钟都要更新。我有一个excel表,通过它我需要每分钟同步价格。为了实现这一点,我使用了openpyxl外部库。你知道吗

我已经成功地创建了核心程序,但是在GUI上实现它时,我被严重地卡住了。我不知道如何创建tkinter GUI,在每次while循环迭代结束时更新price

这是到目前为止的代码(我知道它可以更好,但我必须在明天交付,这只是一次性的事情,所以它不会有关系)—

更新 不需要用户与软件交互。我只需要格式化光滑的外观。你知道吗

#GUI
app = Tk()
app.title("Trading Times 2016")
app.geometry('768x720')

#Execution
Raw = 3
timer = 1
int(Raw)
while Raw != 141:
os.system('CLS')
#timer
print("Time - %i" %timer)
timer += 1
#Currency
print("\n")
print("Dollar -", currency["C%d" %Raw].value)
print("Pound -", currency["E%d" %Raw].value)
print("Euro -", currency["G%d" %Raw].value)
print("Yuan -", currency["I%d" %Raw].value)
#Commodity
print("\n")
print("Gold per 100gm -", commodity["C%d" %Raw].value)
print("Wheat per Quintal -", commodity["E%d" %Raw].value)
print("Silver per Kg -", commodity["G%d" %Raw].value)
print("Crude per Barrel -", commodity["I%d" %Raw].value)
#Bonds
print("\n")
print("Bonds -", bonds["C%i" %Raw].value)
percent =  bonds["E%i" %Raw].value
int(percent)
print("RBI Bonds Yield(In Per Cent) - %i" %percent)
#ETF's
print("\n")
print("Small Cap Index -", etf["B%d" %Raw].value)  
print("Junior BEES -", etf["C%d" %Raw].value)
print("Bank BEES -", etf["D%d" %Raw].value)
print("PSUBNK BEES -", etf["E%d" %Raw].value)
print("CPSTTEF -", etf["F%d" %Raw].value)
print("Infra BEES -", etf["G%d" %Raw].value)           
print("Nifty BEES -", etf["H%d" %Raw].value)
print("SENSEX -", etf["I%d" %Raw].value)
#Mutual Funds
print("\n")
print("ABC -", mutual_funds["B%d" %Raw].value)
print("DEF -", mutual_funds["C%d" %Raw].value)
print("TNC -", mutual_funds["D%d" %Raw].value)     
print("KFJ -", mutual_funds["E%d" %Raw].value)
print("YWU -", mutual_funds["F%d" %Raw].value)
print("QNV -", mutual_funds["G%d" %Raw].value)
print("NBV -", mutual_funds["H%d" %Raw].value)
print("KAS -", mutual_funds["I%d" %Raw].value)
print("AYD -", mutual_funds["J%d" %Raw].value)
print("IT FUND -", mutual_funds["K%d" %Raw].value)
print("PHARMA -", mutual_funds["L%d" %Raw].value)
print("FMCG -", mutual_funds["M%d" %Raw].value)
#Shift Raw
Raw += 1
time.sleep(60)
app.mainloop()

谁能帮我实现一个GUI,它可以随时更新自己。 谢谢


Tags: apprawvalueguicurrencyfundsprinttimer
3条回答

您似乎对GUI程序的工作方式有一个基本的误解。你不应该创建自己的while循环。Tkinter(和其他GUI工具包)有一个需要运行的自定义while循环。你知道吗

原因是,为了让GUI工作,它需要能够处理事件。即使是像在另一个窗口移动时重新绘制窗口这样简单的事情,也是对事件的响应。你知道吗

在Tkinter中,这个事件处理器是mainloop。如果mainloop没有运行(在调用它之前,如果您的程序正在休眠,如果您有自己的长时间运行的代码正在执行,…),它就不能处理事件。如果它不能处理事件,那么它就不能更新屏幕。你知道吗

你可以把mainloop看作是一个无限循环,看起来像这样:

while the_app_is_running:
    event = wait_for_next_event()
    process_event(event)

注意:实际上您并没有编写上面的代码,但打个比方,调用mainloop就是这么做的。你知道吗

在您的情况下,似乎希望显示每分钟更新一次。通过利用这个事件循环,很容易做到这一点。事件循环已经在运行,所以您需要做的就是告诉它每分钟醒来一次并更新其数据。您可以使用after方法来实现这一点。给这个方法一个要调用的函数名和一个延迟,它将在延迟之后调用这个函数。它通过在事件队列中放置一个基于时间的事件来实现。你知道吗

第一步是用所有小部件设置显示。例如:

app = Tk()
...
dollar_label = Label(app, text="")
pound_label = Label(app, text="")
...

下一步是创建一个函数,用您想要的值填充所有标签。从创建标签开始,在一个单独的步骤中执行此操作非常重要,因为您希望能够每分钟都执行此操作。你知道吗

def refresh_display():
    # First, get the new data
    currency = ...
    commodity = ...
    ...
    # next, update the widgets
    dollar_label.configure(text="Dollar: %s" % currency["dollar"]
    pound_label.configure(text="Pound: %s" % currency["pound"]
    ...

最后,您希望每分钟都调用这个函数。您可以编写一个调用refresh_display函数的函数,然后将自己安排在60秒内再次运行:

def call_every_60_seconds():
    refresh_display()
    app.after(60000, call_every_60_seconds)

最后一步是在启动主循环之前,通过调用此函数一次来启动更新。这将用初始值更新显示,然后每分钟启动一次计划。你知道吗

call_every_60_seconds()
app.mainloop()

这是你必须做的基本工作。这很简单,只需要对代码进行一点组织。你知道吗

使用Tkinter的after命令在X毫秒数之后运行函数(参见thisthis)。至于GUI本身,您需要使用一系列更新的标签,或者最好使用ttk.TreeView小部件,这样看起来更好。你知道吗

Tkinter小部件支持一个方法,在该方法之后,在给定的间隔im毫秒后调用函数。这只是一个近似值,但对你来说可能已经足够了。这也许能让你明白我的意思。请原谅任何格式问题-这是我在这里的第一篇文章。你知道吗

将tkinter作为tk导入

类应用程序(tk。tk)地址:

def __init__(self):
    tk.Tk.__init__(self)

    self.counter  = 0
    self.str_counter = tk.StringVar()
    tk.Label(self,textvariable = self.str_counter).pack()

    self.after(1000,self.bump)
    self.mainloop()

def bump(self):
    self.counter += 1
    self.str_counter.set(str(self.counter))

    self.after(1000,self.bump)

应用程序()

相关问题 更多 >