建议:在 tkinter 中启动递归函数



我这个程序的目标是创建一个Tweepy流,将推文汇集到带有tkinter的演示风格GUI中。此外,演示文稿将持续运行,直到我中断代码循环浏览推文。在我的 GUI 中,我有一个功能change(n)如果你想这样想,它有效地改变了推文幻灯片。

我正在寻找从哪里开始这个重复函数的建议。由于我在 tkinter 中运行,我需要在root.mainloop()之前完成它.但是,如果我在__init__initui()期间调用,它将永远不会root.mainloop()因为一旦调用应用程序实例,它就会触发。

代码如下:

from tweepy.streaming import StreamListener
from tweepy import OAuthHandler
from tweepy import Stream
from tkinter import *
from PIL import Image, ImageTk
from time import sleep
class listener(StreamListener):
def __init__(self, application):
self.application = application
def on_data(self, data):
self.application.add(data)
def on_error(self, status):
print(status)
class app(Frame):
def __init__(self, parent):
Frame.__init__(self, parent, bg="white")
self.parent = parent
global screen_h, screen_w
screen_h = self.parent.winfo_screenheight()
screen_w = self.parent.winfo_screenwidth()
global tweets
tweets = ["Tweet with #2017"]
self.parent.bind('<Escape><Escape>', self.close)
self.initui()

def initui(self):
self.parent.title("2017")
self.pack(fill=BOTH, expand=1)
t = Image.open("twitter.jpg")
t_ar = t.size[0]/t.size[1]
t_h = int(screen_h*.1)
t_w = int(t_h * t_ar)
t = t.resize((t_w,t_h),Image.ANTIALIAS)
t = ImageTk.PhotoImage(t)
logo = Label(self, image=t, bd=0, highlightthickness=0)
logo.image = t
position = ((screen_w*.1)-(t_w/2),(screen_h*.5)-(t_h/2))
logo.place(x=position[0], y=position[1])

def add(self, tweet):
tweets.append(tweet)
def change(self, n):
tweet = tweets[n]
label = Label(self, text=tweet, height=screen_h, width=int(screen_w*.75), anchor=CENTER, bg="white", font=("Helvetica", 24))
label.pack(side=RIGHT)
sleep(30)
if n+2 <= len(tweets):
label.destroy()
self.change(n+1)
else:
label.destroy()
self.change(0)
def close(self, event):
self.parent.destroy()

def run():
#start the app
root = Tk()
root.attributes("-fullscreen", True)
start = app(root)
#Twitter API keys
consumer_key=""
consumer_secret=""
access_token=""
access_token_secret=""
#Start Twitter Stream
l = listener(start)
auth = OAuthHandler(consumer_key, consumer_secret)
auth.set_access_token(access_token, access_token_secret)
stream = Stream(auth, l)
stream.filter(track=['basketball'], async=True)
root.mainloop()
run()

我无法测试您的代码,但您可以在没有递归和sleep(30)的情况下执行此操作,而是使用after(miliseconds, function_name, argument)- 如下所示:

def __init__(self, parent):
# create empty label only once
self.label = Label(self, height=screen_h, width=int(screen_w*.75), anchor=CENTER, bg="white", font=("Helvetica", 24))
self.label.pack(side=RIGHT)
def change(self, n):
# change only text
self.label['text'] = tweets[n]
n += 1
if n == len(tweets):
n = 0
# or in one line
# n = (n + 1) % len(tweets)
# run again after 30000ms = 30s
root.after(30000, self.change, n)
#self.parent.after(30000, self.change, n)

现在您可以在mainloop()之前启动它,它不会冻结Tkinter因为after将其发送到 30 秒后会调用change()mainloop()

最新更新