I am trying to stream tweets with python/tweepy using tkinter GUI. Ideally, I would have a "Start" button that would start the stream, and a "Stop" button that would stop the stream. The next example (from stackoverflow) shows in a simplified way what I try to achieve:
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()
I am trying to apply this to my code, the Start button works properly and does everything that it is supposed to do, but the Stop button does not do anything. The window does not freeze or anything, its just that the stop button has no effect. The stream continues as nothing had happened. Here I post my code:
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()
Any idea on what I have to change to get this working?
Thank you very much!
The problem I guess with your code is that, you initialised a stream object inside the while
loop, You must understand that the Stream
objects contains an infinite loop within itself, which continuously looks for new streaming tweets. So Once you initialise a Stream
object, It will automatically run until you kill the process manually, so there is no point in initialising the Stream
object under the while
loop
The strategy you need to follow is:
Stream
object when the start button is pressed. This behaviour can be easily achieved by editing your on_data()
method, you may add the following lines in your on_data()
method at the end where return True
is being written:
if isrecording: #Initialise a variable named isrecording.
return True
else:
return False
I don't have much knowledge about tkinter but I can tell you the reason your "stop" button isn't working because you're not stopping the stream.
Within class listener(StreamListener):
you need to specify twitterStream.disconnect()
. What this will do is stop the connection between you and the Streaming API.
This can be added with:
while isrecording:
## enter code here
else:
## anything that might apply
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.