【问题标题】:Stop tweepy streaming in Tkinter在 Tkinter 中停止 tweepy 流式传输
【发布时间】:2026-01-22 13:35:01
【问题描述】:

我正在尝试使用 tkinter GUI 使用 python/tweepy 流式传输推文。理想情况下,我会有一个“开始”按钮来启动流,以及一个“停止”按钮来停止流。下一个示例(来自 *)以简化的方式展示了我尝试实现的目标:

import Tkinter as tk
import threading

class App():
    def __init__(self, master):
        self.isrecording = False
        self.button1 = tk.Button(main, text='start')
        self.button2 = tk.Button(main, text='stop')

        self.button1.bind("<Button-1>", self.startrecording)
        self.button2.bind("<Button-1>", self.stoprecording)
        self.button1.pack()
        self.button2.pack()

    def startrecording(self, event):
        self.isrecording = True
        t = threading.Thread(target=self._record)
        t.start()

    def stoprecording(self, event):
        self.isrecording = False
        print "\nStopped"

    def _record(self):
        while self.isrecording:
            print "Downloading tweets"

main = tk.Tk()
app = App(main)
main.mainloop()

我正在尝试将此应用到我的代码中,“开始”按钮可以正常工作并执行它应该执行的所有操作,但“停止”按钮不执行任何操作。窗口不会冻结或任何东西,只是停止按钮没有效果。溪流继续,因为什么都没发生。在这里我发布我的代码:

from Tkinter import *
import threading
import codecs
import urllib, json, tweepy,time
from datetime import datetime
from tweepy import Stream
from tweepy import OAuthHandler
from tweepy.streaming import StreamListener

consumer_key = ""
consumer_secret = ""
access_key = ""
access_secret = ""
auth = OAuthHandler(consumer_key, consumer_secret)
auth.set_access_token(access_key, access_secret)
keyword = "Poland"

class App():
    def __init__(self, master):
        self.isrecording = False
        self.button1 = Button(main, text='start')
        self.button2 = Button(main, text='stop')
        self.button1.bind("<Button-1>", self.startrecording)
        self.button2.bind("<Button-1>", self.stoprecording)
        self.button1.pack()
        self.button2.pack()

    def startrecording(self,event):
        self.isrecording = True
        t = threading.Thread(target=self._record)
        t.start()

    def stoprecording(self, event):
        self.isrecording = False

    def _record(self):
        while self.isrecording:
            class listener(StreamListener):
                def on_data(self,data):
                    imageFolder = "H:\Bogdan\imageFolder"
                    decoded = json.loads(data)
                    encoded = decoded['text'].encode('ascii','ignore')
                    if "http" not in encoded:
                        encodedStrip = encoded.translate(None, '@,/,\\,",<,>,:,|,?,*').replace("\n","")
                        print encodedStrip
                        if "media" in decoded['entities']:
                            for value in decoded['extended_entities']['media']:
                                imageLink = value['media_url']
                                urllib.urlretrieve(imageLink, imageFolder+"\\"+encodedStrip+"_"+str(time.time())+".jpg")
                        print 'downloading...'
                        return True

                    else:
                        encodedHTTP = encoded[:encoded.index("http")-2]
                        encodedStrip = encodedHTTP.translate(None, '@,/,\\,",<,>,:,|,?,*').replace("\n","")
                        print encodedStrip
                        if "media" in decoded['entities']:
                            for value in decoded['extended_entities']['media']:
                                imageLink = value['media_url']
                                urllib.urlretrieve(imageLink, imageFolder+"\\"+encodedStrip+"_"+str(time.time())+".jpg")
                        print 'downloading...'
                        return True
                def on_error(self,status):
                    print status

            twitterStream = Stream(auth,listener())
            twitterStream.filter( track = [keyword] )



main = Tk()
app = App(main)
main.mainloop()

知道我必须进行哪些更改才能使其正常工作吗?

非常感谢!

【问题讨论】:

    标签: python loops tkinter tweepy


    【解决方案1】:

    我猜你的代码的问题是,你在while 循环中初始化了一个流对象,你必须明白Stream 对象本身包含一个无限循环,它不断寻找新的流推文。所以一旦你初始化了一个Stream对象,它会自动运行,直到你手动终止进程,所以在while循环下初始化Stream对象是没有意义的

    您需要遵循的策略是:

    • 按下开始按钮时初始化Stream对象。
    • 按下停止按钮时停止流式传输。

    此行为可以通过编辑您的 on_data() 方法轻松实现,您可以在 on_data() 方法中添加以下行到 return True 的末尾:

    if isrecording: #Initialise a variable named isrecording.
        return True
    else:
        return False
    

    【讨论】:

    • 感谢您的评论。不幸的是,侦听器类中无法识别“isrecording”属性。我收到此错误:AttributeError: 'listener' object has no attribute 'isrecording'
    • 如果你创建一个名为isrecording的全局变量会更好。
    【解决方案2】:

    我对 tkinter 了解不多,但我可以告诉你“停止”按钮不起作用的原因,因为你没有停止流。

    class listener(StreamListener): 中,您需要指定twitterStream.disconnect()。这将停止您与 Streaming API 之间的连接。

    这可以添加:

    while isrecording:
        ## enter code here
    else:
        ## anything that might apply
    

    【讨论】: