i have this code and i get an error like this.
Creating an ndarray from ragged nested sequences (which is a list-or-tuple of lists-or-tuples-or ndarrays with different lengths or shapes) is deprecated. If you meant to do this, you must specify 'dtype=object' when creating the ndarray.
training = np.array(training)
import threading
import speech_recognition
import pyttsx3 as tts
import tkinter as tk
from neuralintents import GenericAssistant
class Assistant:
def __init__(self):
self.recognizer=speech_recognition.Recognizer()
self.speaker= tts.init()
self.speaker.setProperty("rate",150)
self.assistant=GenericAssistant("intent.json",intent_methods={"file": self.create_file})
self.assistant.train_model()
self.root=tk.Tk()
self.label=tk.label(text="j",font=("Arial",120,"bold"))
self.label.pack()
threading.Thread(target=self.run_assistant).start()
self.root.mainloop()
def create_file(self):
with open("somefile.text","w") as f:
f.write("hellow")
def run_assistant(self):
while True:
try:
with speech_recognition.Microphone() as mic:
self.recognizer.adjust_for_ambient_noise(mic,duration=0.2)
audio = self.recognizer.listen(mic)
text= self.recognizer.recognize_google(audio)
text=text.lower()
if "hey" in text:
self.label.config(fg="red")
audio=self.recognizer.listen(mic)
text=self.recognizer.recogni(audio)
text=text.lower()
if text == "stop":
self.speaker.say("Good Bye")
self.speaker.runAndWait()
self.speaker.stop()
self.root.destroy()
sys.exit()
else:
if text is not None:
response= self.assistant.request(text)
if response is not None:
self.speaker.say(response)
self.speaker.runAndWait()
self.label.config(fg="black")
except:
self.label.config(fg="black")
continue
Assistant()
Related
I have a customtkinter (CTk) button widget that, when pressed, sends an encoded message to a client depending on the button's "text" value; in this case, if the button's text is "Off", it sends the message "On" and vice versa to the client.
import tkinter as tk
import traceback
import customtkinter as cust
import socket
from threading import Thread
from tkinter import messagebox
class GUI2(cust.CTk): #second window; not the root
def __init__(self):
super().__init__()
self.PORT = 5000
self.SERVER = socket.gethostbyname(socket.gethostname())
self.ADDRESS = (self.SERVER, self.PORT)
self.FORMAT = "utf-8"
self.clients = [] #list to store all client connections
self.server = socket.socket(socket.AF_INET,
socket.SOCK_STREAM)
self.server.bind(self.ADDRESS)
self.master2 = cust.CTkToplevel()
self.ecdpower = cust.CTkButton(self.master2, text = "Off", fg_color = "Black", text_color = "White", hover_color = "Silver", command = lambda: Thread(target = self.startstream).start())
self.ecdpower.grid(row = 0, column = 0) #button to send message to client connections
self.thread = Thread(target = self.startChat)
self.thread.start() #starts function to accept client connections
def startChat(self): #function to accept client connections
self.server.listen(30)
try:
while True:
self.conn, self.addr = self.server.accept()
self.clients.append(self.conn) #stores all client connections
except:
pass
def startstream(self):
try:
if not self.clients: #checks if list is empty
messagebox.showerror("No Connections!", "No clients connected to host!")
else:
for x in self.clients:
if self.ecdpower["text"] == "Off": #ecdpower button widget acts like a "power button"
self.ecdpower.configure(text = "On", fg_color = "Green")
x.send(("On").encode(self.FORMAT))
else:
self.ecdpower.configure(text = "Off", fg_color = "Red")
x.send(("Off").encode(self.FORMAT))
except:
print (traceback.format_exc())
Error is as follows:
Traceback (most recent call last):
File "f:\project\mainmenu.py", line 390, in startstream
File "F:\Program Files (x86)\Python\lib\tkinter\__init__.py", line 1681, in cget
return self.tk.call(self._w, 'cget', '-' + key)
_tkinter.TclError: unknown option "-text"
I have also tried if self.ecdpower.cget("text") == "Off: and tried other values like fg_color; both result in the same error. When I removed the if condition, the message sending works correctly so the only problem is how to verify the button "text" value.
Any help to fix this or possible other alternatives is greatly appreciated.
Per #jasonharper's comment above, CTkButton is
not actually a Tkinter Button at all (it's made from a Frame containing a Canvas and a Label), so the normal Tkinter attribute-getting functions don't apply.
Instead of using self.ecdpower["text"] or self.ecdpower.cget("text"): I should use
self.ecdpower.text
to get the CTKbutton's text value.
The same can be applied with fg_color; use self.ecdpower.fg_color to get the value.
I'm new to asyncio, threading, subrocess and I'm trying to build an app that reads data from the serial continuesly, put them inot a queue used by another process/thread/asyncio function to consume them and show into a tkinter GUI.
I was able to make the GUI non blocking while continue reading the data with the code below.
import tkinter as tk
import time
import queue
import logging
import serial
import sys
class SampleApp(tk.Tk):
def __init__(self, *args, **kwargs):
tk.Tk.__init__(self, *args, **kwargs)
self.serial_text_label = tk.Label(self, text="String")
self.serial_text_label.pack()
self.serial_text = tk.Text(self, height=1, width=21)
self.serial_text.pack()
self.port = 'COM3'
self.baud = 38400
self.ser = serial.Serial(self.port, self.baud, timeout=0)
if self.ser.isOpen():
self.ser.close()
self.ser.open()
self.ser.reset_input_buffer()
self.ser.reset_output_buffer()
logging.info("created serial port")
# start the serial_text_label "ticking"
self.update_screen()
def update_screen(self):
self.serial_text.delete('1.0', tk.END)
data = ""
data_raw = self.ser.read(1)
if data_raw == b'\x02':
data_raw = self.ser.read(6)
data = "02-" + str(data_raw.hex('-'))
self.ser.reset_input_buffer()
self.ser.reset_output_buffer()
self.serial_text.insert(tk.END, data)
# self.serial_text_label.configure(text=data)
# call this function again when want to refresh
self.after(500, self.update_screen)
if __name__== "__main__":
logging.basicConfig(stream=sys.stdout, level=logging.DEBUG,
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s (%(filename)s:%(lineno)d)', )
app = SampleApp()
app.mainloop()
The only issue with my code is that all the reading and the elaboration of thedata coming from the serial port are inside the refresh cycle that update the screen. I would like to detach the function to some sort of thread/subprocess that works concurrently with the refresh of the GUI.
What I've tried is to create an async def do_serial() function inside class SampleApp(tk.Tk) as below:
async def do_serial():
logging.debug("do serial")
data = ""
data_raw = ser.read(1)
if data_raw == b'\x02':
data_raw = ser.read(6)
data = "02-" + str(data_raw.hex('-'))
ser.reset_input_buffer()
ser.reset_output_buffer()
# add data to queue
if data != "":
logging.debug('put:' + str(data))
incoming_serial_queue.put(data)
await asyncio.sleep(1)
and inside the update_screen function I call asyncio.run(do_serial())
if not incoming_serial_queue.empty():
data = incoming_serial_queue.get()
Unfortunately it doesn't work and the code doesn't even show the GUI
Is there a way to process the data from the serial in an asyncronus/parallel way without having to write all the function inside the refresh GUI function?
Try making a blocking calls in a separate thread. Inside update_screen, you should make calls fast enough to not no freeze GUI. That means, you should not read the input there.
import tkinter as tk
import time
import queue
import logging
import serial
import sys
import threading
from concurrent.futures import ThreadPoolExecutor
class SampleApp(tk.Tk):
def __init__(self, *args, **kwargs):
tk.Tk.__init__(self, *args, **kwargs)
self.serial_text_label = tk.Label(self, text="String")
self.serial_text_label.pack()
self.serial_text = tk.Text(self, height=1, width=21)
self.serial_text.pack()
self.port = 'COM3'
self.baud = 38400
self.ser = serial.Serial(self.port, self.baud, timeout=0)
if self.ser.isOpen():
self.ser.close()
self.ser.open()
self.ser.reset_input_buffer()
self.ser.reset_output_buffer()
logging.info("created serial port")
# start the serial_text_label "ticking"
self._update_scheduled = threading.Condition()
self._terminating = threading.Event()
self.update_screen()
def mainloop(self):
with ThreadPoolExecutor() as executor:
future = executor.submit(self._do_update_screen_loop)
try:
return super().mainloop()
finally:
# letting the thread to know we're done
self._terminating.set()
with self._update_scheduled:
self._update_scheduled.notify_all()
def update_screen(self):
with self._update_scheduled:
self._update_scheduled.notify_all()
self.after(500, self.update_screen)
def _do_update_screen_loop(self):
while True:
with self._update_scheduled:
self._update_scheduled.wait()
if self._terminating.is_set():
return
self._do_update_screen()
def _do_update_screen(self):
self.serial_text.delete('1.0', tk.END)
data = ""
data_raw = self.ser.read(1)
if data_raw == b'\x02':
data_raw = self.ser.read(6)
data = "02-" + str(data_raw.hex('-'))
self.ser.reset_input_buffer()
self.ser.reset_output_buffer()
self.serial_text.insert(tk.END, data)
# self.serial_text_label.configure(text=data)
if __name__== "__main__":
logging.basicConfig(stream=sys.stdout, level=logging.DEBUG,
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s (%(filename)s:%(lineno)d)', )
app = SampleApp()
app.mainloop()
Usually, you would use root.mainloop() as the funtion, but for async, you'll have to use something else, however you'll have to create a loop yourself if you want the window to update every frame. The async function is simply root.update().
Hope this helped!
I wrote this program with Python:
import os
from kivy.app import App
from kivy.uix.label import Label
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.textinput import TextInput
from kivy.uix.button import Button
from time import sleep
import pytube
import scrapetube
from pathlib import Path
save_addr = f"{os.environ['USERPROFILE']}\Downloads\Youtube DL"
print(save_addr)
layout = BoxLayout
def youtube_dl(video,addr):
#yt = pytube.YouTube(f"{link.text}")
#ys = yt.streams.get_highest_resolution()
#ys.download()
video = str(video.text)
try:
yt = pytube.YouTube(video)
ys = yt.streams.get_highest_resolution()
ys.download(output_path=addr)
except pytube.exceptions.RegexMatchError:
print('The Regex pattern did not return any matches for the video: {}'.format(video))
except pytube.exceptions.ExtractError:
print('An extraction error occurred for the video: {}'.format(video))
except pytube.exceptions.VideoUnavailable:
print('The following video is unavailable: {}'.format(video))
class cd:
"""Context manager for changing the current working directory"""
def __init__(self, newPath):
self.newPath = os.path.expanduser(newPath)
def __enter__(self):
self.savedPath = os.getcwd()
os.chdir(self.newPath)
def __exit__(self, etype, value, traceback):
os.chdir(self.savedPath)
class MyGrid(layout):
def __init__(self, **kwargs):
super().__init__(**kwargs)
self.orientation = "vertical"
self.spacing = 20
self.padding = [10, 10]
self.cols = 1
self.label = Label(text="Enter link of Video You Want to Download!")
self.add_widget(self.label)
self.link = TextInput(hint_text="Example: youtube.com/watch?v=MXDHK_MqRsk", multiline=False)
self.add_widget(self.link)
self.btn = Button(text="OK!")
self.btn.bind(on_press=lambda x:self.callback())
self.add_widget(self.btn)
sleep(3)
def callback(self):
def dl(video,addr,DL=True):
try:
yt = pytube.YouTube(video)
if DL:
ys = yt.streams.get_highest_resolution()
cd(addr)
ys.download(output_path=addr)
except pytube.exceptions.RegexMatchError:
print('The Regex pattern did not return any matches for the video: {}'.format(video))
except pytube.exceptions.ExtractError:
print('An extraction error occurred for the video: {}'.format(video))
except pytube.exceptions.VideoUnavailable:
print('The following video is unavailable: {}'.format(video))
return yt
video = str(self.link.text)
title = str(dl(video,self.link,DL=False).title)
self.label.text = f"Download : \"{title}\" , Save in:"
self.link.text = f"{save_addr}"
self.btn.text = "Download video!"
self.btn.bind(on_press=lambda x:dl(video,self.link.text))
class MyKivy(App):
def build(self):
return MyGrid()
if __name__ == "__main__":
MyKivy().run()
My problem is that when I put the video link to the program and click on download, when downloading the video from YouTube, the message not responding is displayed, but after the download is complete, the program returns to normal:
image of this error
What can I do to prevent the message not responding from being displayed?
To prevent this, you have to use multithreading, that means you can do multiple tasks simulatiously, that will prevent the UI from freezing because it will running in a thread that is not in the same thread that the downloader is running on. you will make a function to run the downloader in threading like this:
import threading
def run_thread(self,*args):
thread_dl = thrading.Thread(target = self.downloader,args = (arg1,arg2,arg3))
thread_dl.start()
you will edit this function to be the button on_press function
I'm doing a project on speech recognition and am trying to use Tkinter to create a GUI for my project...the SR part works well but when I integrate it with Tkinter it doesn't work...please help. (am new to programming so please don't mind my code:) )
#MY CODE
import speech_recognition as sr
import tkinter as tk
obj = tk.Tk()
obj.title("SpeechToText")
obj.geometry('400x200')
obj.resizable(0,0)
def rec():
r = sr.Recognizer()
msg.configure(text="Say something")
while True:
with sr.Microphone() as source:
r.adjust_for_ambient_noise(source)
audio = r.listen(source)
try:
txt = "".format(r.recognize_google(audio).get())
msg.configure(text=txt)
except Exception as e:
print(e)
break
msg = tk.Label()
msg.grid(row=0,column=0)
btn = tk.Button(text="Start",command=rec)
btn.grid(row=2,column=0)
obj.mainloop()
I would like it to display the translated text in the label but it doesn't. It only shows "say something" even after speaking.
Try this, I blocked out the msg.configure(text='Say Somethin'). This line makes the recorded text being reformatted to 'Say Something' and not the text that was recorded. Hope this helps.
import speech_recognition as sr
import tkinter as tk
obj = tk.Tk()
obj.title("SpeechToText")
obj.geometry('400x200')
obj.resizable(0,0)
def rec():
r = sr.Recognizer()
#msg.configure(text="Say something")
while True:
with sr.Microphone() as source:
r.adjust_for_ambient_noise(source)
audio = r.listen(source)
try:
txt = r.recognize_google(audio)
msg.configure(text=txt)
print(txt)
except Exception as e:
print(e)
break
msg = tk.Label()
msg.grid(row=0,column=0)
btn = tk.Button(text="Start",command=rec)
btn.grid(row=2,column=0)
obj.mainloop()
I'm trying to write a small python app, using PySide for the GUI and Twython as a Twitter API library, to catch a stream from Twitter.
The problem that I am having is that when I click "Start Monitoring Twitter" button, the UI freezes until the stream is complete, at which point the code continues to execute and disables the Start button and enables the Stop button. Here's the UI:
Everything else seems to work -- if I leave it, then the CSV file is created as I suspect -- the Twython components seem to be working as expected.
Line 151 is where the streaming from Twitter is engaged when I click start:
self.stream.statuses.filter(track=self.search_term)
How can I move the streaming to a separate thread and then use the Stop button on the UI to tell Twython to complete capturing the stream and exit?
I need to be able to send the MyStreamer instance to another thread and then send it the .disconnect() signal to have it terminate capturing the stream.
Here's the full code:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import sys
import platform
import PySide
from PySide.QtGui import QApplication, QMainWindow, QPushButton, QCheckBox, QTextEdit
from time import sleep
from ui_tweetstream import Ui_MainWindow
from twython import Twython
from twython import TwythonStreamer
import csv
class MainWindow(QMainWindow, Ui_MainWindow):
def __init__(self, parent=None):
super(MainWindow, self).__init__(parent)
self.setupUi(self)
# Set up Variables
self.tweet_fav_count = True
self.tweet_geocoordinates = True
self.tweet_id = True
self.tweet_language = True
self.tweet_orig_tweet_id = True
self.tweet_orig_username = True
self.tweet_retweeted = True
self.tweet_sensitive = True
self.tweet_source_app = True
self.tweet_timestamp = True
self.tweet_user_name = True
self.search_term = "#bigdata"
self.tweets_to_get = 1000
# Bind the interface
self.check_tweet_fav_count.clicked.connect(self.setTweetFavCount)
self.check_tweet_geocoordinates.clicked.connect(self.setTweetGeocoordinates)
self.check_tweet_id.clicked.connect(self.setTweetID)
self.check_tweet_language.clicked.connect(self.setTweetLanguage)
self.check_tweet_orig_tweet_id.clicked.connect(self.setTweetOrigTweetID)
self.check_tweet_orig_username.clicked.connect(self.setTweetOrigUsername)
self.check_tweet_retweeted.clicked.connect(self.setTweetRetweeted)
self.check_tweet_sensitive.clicked.connect(self.setTweetSensitive)
self.check_tweet_source_app.clicked.connect(self.setTweetSourceApp)
self.check_tweet_timestamp.clicked.connect(self.setTweetTimestamp)
self.check_tweet_user_name.clicked.connect(self.setTweetUsername)
self.button_start.clicked.connect(self.streamStart)
self.button_stop.clicked.connect(self.streamStop)
# Set the initial states
self.button_stop.setEnabled(False)
APP_KEY = ''
APP_SECRET = ''
OAUTH_TOKEN = ''
OAUTH_TOKEN_SECRET = ''
self.t = Twython(APP_KEY, APP_SECRET, OAUTH_TOKEN, OAUTH_TOKEN_SECRET)
self.stream = MyStreamer(APP_KEY,APP_SECRET,OAUTH_TOKEN,OAUTH_TOKEN_SECRET)
self.stream.init_mainWindow(self)
def streamStop(self):
print "Stopping stream"
# Enable other controls here
self.button_stop.setEnabled(False)
self.button_start.setEnabled(True)
self.setControlStates(True)
self.stream.stopStream()
def setControlStates(self, state):
self.check_tweet_fav_count.setEnabled(state)
self.check_tweet_geocoordinates.setEnabled(state)
self.check_tweet_id.setEnabled(state)
self.check_tweet_language.setEnabled(state)
self.check_tweet_orig_tweet_id.setEnabled(state)
self.check_tweet_orig_username.setEnabled(state)
self.check_tweet_retweeted.setEnabled(state)
self.check_tweet_sensitive.setEnabled(state)
self.check_tweet_source_app.setEnabled(state)
self.check_tweet_timestamp.setEnabled(state)
self.check_tweet_user_name.setEnabled(state)
self.search_box.setEnabled(state)
self.num_tweets_box.setEnabled(state)
# Functions for determining what to track
def setTweetFavCount(self):
self.tweet_fav_count = not self.tweet_fav_count
print "tweet_fav_count:", self.tweet_fav_count
def setTweetGeocoordinates(self):
self.tweet_geocoordinates = not self.tweet_geocoordinates
print "tweet_geocoordinates:", self.tweet_geocoordinates
def setTweetID(self):
self.tweet_id = not self.tweet_id
print "tweet_id:", self.tweet_id
def setTweetLanguage(self):
self.tweet_language = not self.tweet_language
print "tweet_language:", self.tweet_language
def setTweetOrigTweetID(self):
self.tweet_orig_tweet_id = not self.tweet_orig_tweet_id
print "tweet_orig_tweet_id:", self.tweet_orig_tweet_id
def setTweetOrigUsername(self):
self.tweet_orig_username = not self.tweet_orig_tweet_id
print "tweet_orig_username:", self. tweet_orig_username
def setTweetRetweeted(self):
self.tweet_retweeted = not self.tweet_retweeted
print "tweet_retweeted:", self.tweet_retweeted
def setTweetSensitive(self):
self.tweet_sensitive = not self.tweet_sensitive
print "tweet_sensitive:", self.tweet_sensitive
def setTweetSourceApp(self):
self.tweet_source_app = not self.tweet_source_app
print "tweet_source_app:", self.tweet_source_app
def setTweetTimestamp(self):
self.tweet_timestamp = not self.tweet_timestamp
print "tweet_timestamp:", self.tweet_timestamp
def setTweetUsername(self):
self.tweet_user_name = not self.tweet_user_name
print "tweet_user_name:", self.tweet_user_name
# Functions for starting and stopping the stream
def streamStart(self):
print "Starting stream"
self.setControlStates(False)
# Disable other controls here
self.button_start.setEnabled(False)
self.button_stop.setEnabled(True)
# Hack to try to disable the UI
# sleep(0.25)
# Get the active search term
self.search_term = self.search_box.text()
# Get the number of tweets
self.tweets_to_get = int(self.num_tweets_box.text())
# Set the streamer
self.stream.set_start_criteria(self.tweets_to_get)
self.stream.statuses.filter(track=self.search_term)
class MyStreamer(TwythonStreamer):
def init_mainWindow(self, the_main_window):
self.main_window = the_main_window
self.stop = False
self.header_done = False
def set_start_criteria(self, numTweets):
self.maxTweets = numTweets
self.tweetCount = 0
print "Number of tweets to get:", self.maxTweets
def stopStream(self):
self.stop = True
def on_success(self, data):
if 'text' in data:
self.tweetCount += 1
print "tweetCount:", self.tweetCount
#tweet = data['text'].encode('utf-8')
theTweet = data
writer = TweetMonkey()
writer.assignMainWindow(self.main_window, self.header_done)
self.header_done = True
writer.process(theTweet)
# Want to disconnect after the first result?
if self.stop is True or self.tweetCount >= self.maxTweets:
self.disconnect()
def on_error(self, status_code, data):
print status_code, data
class TweetMonkey:
def assignMainWindow(self,the_main_window, is_header_done):
self.main_window = the_main_window
self.header_done = is_header_done
def clean(self,text):
text = text.replace("\n","; ")
text = text.replace('"', "'")
text = text.replace(','," ")
return text
def create_header(self):
header = []
tweets = open("tweets.csv", 'ab+')
wr = csv.writer(tweets, dialect='excel')
if self.main_window.tweet_id is True:
header.append("id")
if self.main_window.tweet_language is True:
header.append("lang")
if self.main_window.tweet_user_name is True:
header.append("user_name")
header.append("tweet")
if self.main_window.tweet_retweeted is True:
header.append("retweeted")
if self.main_window.tweet_fav_count is True:
header.append("favorite_count")
if self.main_window.tweet_source_app is True:
header.append("source")
if self.main_window.tweet_orig_tweet_id is True:
header.append("in_reply_to_status_id")
if self.main_window.tweet_orig_username is True:
header.append("in_reply_to_screen_name")
# header.append("in_reply_to_user_id")
if self.main_window.tweet_sensitive is True:
header.append("possibly_sensitive")
if self.main_window.tweet_geocoordinates is True:
header.append("geo")
if self.main_window.tweet_timestamp is True:
header.append("created_at")
wr.writerow(header)
tweets.close()
def process(self, tweet):
if not self.header_done:
self.create_header()
self.header_done = True
# Create the file or append to the existing
theOutput = []
tweets = open("tweets.csv", 'ab+')
wr = csv.writer(tweets, dialect='excel')
if self.main_window.tweet_id is True:
theOutput.append(tweet['id'])
if self.main_window.tweet_language is True:
theOutput.append(tweet['lang'].encode('utf-8'))
if self.main_window.tweet_user_name is True:
theOutput.append(tweet['user']['name'].encode('utf-8', 'replace'))
theOutput.append(self.clean(tweet['text']).encode('utf-8', 'replace'))
if self.main_window.tweet_retweeted is True:
theOutput.append(tweet['retweeted'])
if self.main_window.tweet_fav_count is True:
theOutput.append(tweet['favorite_count'])
if self.main_window.tweet_source_app is True:
theOutput.append(self.clean(tweet['source']).encode('utf-8', 'replace'))
if self.main_window.tweet_orig_tweet_id is True:
theOutput.append(tweet['in_reply_to_status_id'])
if self.main_window.tweet_orig_username is True:
theOutput.append(tweet['in_reply_to_screen_name'])
#theOutput.append(tweet['in_reply_to_user_id'])
if self.main_window.tweet_sensitive is True:
if tweet.get('possibly_sensitive'):
theOutput.append(tweet['possibly_sensitive'])
else:
theOutput.append("False")
if self.main_window.tweet_geocoordinates is True:
if tweet['geo'] is not None:
if tweet['geo']['type'] == 'Point':
lat = str(tweet['geo']['coordinates'][0]) + " "
lon = str(tweet['geo']['coordinates'][1])
theOutput.append(lat + lon)
else:
theOutput.append(tweet['geo'])
else:
theOutput.append(tweet['geo'])
if self.main_window.tweet_timestamp is True:
theOutput.append(tweet['created_at'])
wr.writerow(theOutput)
tweets.close()
if __name__ == '__main__':
app = QApplication(sys.argv)
frame = MainWindow()
frame.show()
app.exec_()
I know this is an old post but I ran into a similar problem in a simple app I recently wrote, my solution was to use threading.
I used the worker from:
https://pymotw.com/2/threading/
and the method described in:
http://aadrake.com/using-twitter-as-a-stream-processing-source.html
Basically running the Twython stream as a separate thread feeding text to a queue then I run the rest of the program in a separate loop reading from the queue.