Python Tkinter 变量未在其他线程中更新
Python Tkinter variable not updating in other thread
import tkinter as tk
import threading
import urllib.request
import pyperclip
import datetime
import time
import winsound
window = tk.Tk()
window.title("Pinger")
window.protocol("WM_DELETE_WINDOW", window.destroy)
mainvar = tk.StringVar(window) #creation of a variable
mainvar.set('realm') #set variable
window.iconbitmap('icon1.ico')
menu = tk.OptionMenu(window, mainvar, "1", "2", "3", "4", "5") #drop down
menu.pack()
global current_event_id
current_event_id = '-1'
def change_dropdown(*args):
#print(mainvar.get()) #no need for flush
if (mainvar.get() == "1"):
window.iconbitmap('icon1.ico')
current_event_id = '-1'
elif (mainvar.get() == "2"):
window.iconbitmap('icon2.ico')
current_event_id = '-2'
elif (mainvar.get() == "3"):
window.iconbitmap('icon3.ico')
current_event_id = '-3'
elif (mainvar.get() == "4"):
window.iconbitmap('icon4.ico')
current_event_id = '-4'
elif (mainvar.get() == "5"):
window.iconbitmap('icon5.ico')
current_event_id = '-5'
mainvar.trace('w', change_dropdown) #add an event listener to the main variable and link it to the change_dropdown function
def run():
link = "https://website"
m2 = ''
while True:
m1 = str(datetime.datetime.now().minute)
s1 = datetime.datetime.now().second
if (s1 == 59 and m1 != m2):
m2 = m1
f = urllib.request.urlopen(link)
myfile = f.read()
text = myfile.decode('utf-8')
events = text.split('\n')
i = 0
while True:
keys = events[i].split('|')
time = keys[5].split(':')[1]
key = keys[6]
if (time != m1):
break
if (event_id == current_event_id):
winsound.Beep(440,500)
pyperclip.copy(key)
print(key)
i += 1
control_thread = threading.Thread(target=run)
control_thread.start()
window.mainloop()
所以我有一个 python 脚本,它每分钟访问一个网站,读取页面,如果特定数据在那一分钟被放置在网站上,就会通知我。我正在扩展此脚本以包含一个菜单和一种在不同数据点之间切换的方法。 GUI 和脚本独立运行良好。但是,变量 current_event_id
在我的 control_thread
中没有正确更新。我可以正确地弄乱 GUI;例如,图标会正确更改。但是,run()
中的循环并未反映 current_event_id
中的更改。我希望有一些简单的解决方法。
Python中全局变量的经典陷阱:
在你的 change_dropdown
函数中,你需要在设置它之前声明 global curent_event_id
,否则你实际上是在设置一个局部变量,一旦函数退出就会忘记它。
一个简单的演示:
x = "old x"
y = "old y"
def changeX():
x = "new x"
def changeY():
global y
y = "new y"
changeX()
changeY()
print(x, y)
这将打印 old x new y
。
此外,据我所知,在函数外使用 global
在 Python 中没有任何效果,因为它只说:“在模块变量命名空间中使用或创建此变量”。如果您要在模块中引入变量,则不需要将其作为附加声明。因此,在您的情况下,如果您只是将变量初始化为:
current_event_id = '-1'
这与旧的
具有相同的效果
global current_event_id
current_event_id = '-1'
import tkinter as tk
import threading
import urllib.request
import pyperclip
import datetime
import time
import winsound
window = tk.Tk()
window.title("Pinger")
window.protocol("WM_DELETE_WINDOW", window.destroy)
mainvar = tk.StringVar(window) #creation of a variable
mainvar.set('realm') #set variable
window.iconbitmap('icon1.ico')
menu = tk.OptionMenu(window, mainvar, "1", "2", "3", "4", "5") #drop down
menu.pack()
global current_event_id
current_event_id = '-1'
def change_dropdown(*args):
#print(mainvar.get()) #no need for flush
if (mainvar.get() == "1"):
window.iconbitmap('icon1.ico')
current_event_id = '-1'
elif (mainvar.get() == "2"):
window.iconbitmap('icon2.ico')
current_event_id = '-2'
elif (mainvar.get() == "3"):
window.iconbitmap('icon3.ico')
current_event_id = '-3'
elif (mainvar.get() == "4"):
window.iconbitmap('icon4.ico')
current_event_id = '-4'
elif (mainvar.get() == "5"):
window.iconbitmap('icon5.ico')
current_event_id = '-5'
mainvar.trace('w', change_dropdown) #add an event listener to the main variable and link it to the change_dropdown function
def run():
link = "https://website"
m2 = ''
while True:
m1 = str(datetime.datetime.now().minute)
s1 = datetime.datetime.now().second
if (s1 == 59 and m1 != m2):
m2 = m1
f = urllib.request.urlopen(link)
myfile = f.read()
text = myfile.decode('utf-8')
events = text.split('\n')
i = 0
while True:
keys = events[i].split('|')
time = keys[5].split(':')[1]
key = keys[6]
if (time != m1):
break
if (event_id == current_event_id):
winsound.Beep(440,500)
pyperclip.copy(key)
print(key)
i += 1
control_thread = threading.Thread(target=run)
control_thread.start()
window.mainloop()
所以我有一个 python 脚本,它每分钟访问一个网站,读取页面,如果特定数据在那一分钟被放置在网站上,就会通知我。我正在扩展此脚本以包含一个菜单和一种在不同数据点之间切换的方法。 GUI 和脚本独立运行良好。但是,变量 current_event_id
在我的 control_thread
中没有正确更新。我可以正确地弄乱 GUI;例如,图标会正确更改。但是,run()
中的循环并未反映 current_event_id
中的更改。我希望有一些简单的解决方法。
Python中全局变量的经典陷阱:
在你的 change_dropdown
函数中,你需要在设置它之前声明 global curent_event_id
,否则你实际上是在设置一个局部变量,一旦函数退出就会忘记它。
一个简单的演示:
x = "old x"
y = "old y"
def changeX():
x = "new x"
def changeY():
global y
y = "new y"
changeX()
changeY()
print(x, y)
这将打印 old x new y
。
此外,据我所知,在函数外使用 global
在 Python 中没有任何效果,因为它只说:“在模块变量命名空间中使用或创建此变量”。如果您要在模块中引入变量,则不需要将其作为附加声明。因此,在您的情况下,如果您只是将变量初始化为:
current_event_id = '-1'
这与旧的
具有相同的效果global current_event_id
current_event_id = '-1'