I want to interface pocketsphinx livespeech with Python tkinter GUI in such a way that GUI is visible on frontend and Livespeech works on Back-end.But when i merge tkinter code with livespeech code; livespeech code always runs first and GUI not shows till i stop the code;so i won't be able to perform my required task..,
#*********************************** IMPORTING MODULES*****************
import tkinter
from tkinter import*
import tkinter.messagebox
import sqlite3
import os
from pocketsphinx import LiveSpeech, get_model_path
conn = sqlite3.connect('portal.db')
c = conn.cursor()
window = tkinter.Tk()
window.title("Smart Notice Board")
top = Canvas(window,width=400,height=200)
top.pack(fill=X)
def portal():
print("2")
button_5 = Button(text='PORTAL SYSTEM', height = 2, width=17, activebackground = '#33B5e5', bg = 'brown', fg = 'white',command = portal )
top.create_window(80,80, anchor='nw', window = button_5)
#**************** TEXT TO SPEECH CODE***************
model_path = get_model_path()
speech = LiveSpeech(
verbose=False,
sampling_rate=16000,
buffer_size=2048,
no_search=False,
full_utt=False,
hmm=os.path.join(model_path, 'en-us'),
lm=os.path.join(model_path, '8582.lm'),
dic=os.path.join(model_path, '8582.dict')
)
for phrase in speech:
print(phrase)
a=str(phrase)
if a == "HOME":
print('ok')
portal()
print('1')
results are attached below;
Only live speech runs
GUI opens when code exit
Related
I am trying to create a python script that will trigger a tkinter window every time a certain event happens. The python script will have a while true loop and during the loop the tkinter event may or may not happen (if-else block). Right now the actual loop part isn't done, so I am currently testing the tkinter part but I can't seem to open more than tkinter window.
Below is the test script I am using.
from tkinter import *
from sys import exit
import os
onetwo = "C:/Users/I/Downloads/Transfer_Out_1016_Outlook.txt"
def popupError(s):
popupRoot = Tk()
##popupRoot.after(20000, exit)
popupButton = Button(popupRoot, text = s, font = ("Verdana", 12), bg = "yellow", command = lambda: os.system(onetwo))
popupButton.pack()
popupRoot.geometry('400x50+700+500')
popupRoot.mainloop()
popupError("HelloWORLD")
def popupTwo(s):
popupRoot = Tk()
##popupRoot.after(20000, exit)
popupButton = Button(popupRoot, text = s, font = ("Verdana", 12), bg = "yellow", command = lambda: os.system(onetwo))
popupButton.pack()
popupRoot.geometry('400x50+700+500')
popupRoot.mainloop()
popupTwo("HEWWWWWEWEWKOO")
I apologize for the lack of an actual piece of code but this is the best I can do right now given the dev status of the other parts of the overall python script.
Note that the tkinter window may be triggered more than once in a single loop session.
If any other details are needed, I'll try my best to add more in.
Here’s what you can do:
from tkinter import *
def popup(winName):
newWin = Toplevel()
btn2 = Button(newWin, text=winName)
btn2.pack()
root = Tk()
btn = Button(root, text=“Popup”, command=lambda: popup(“text”))
btn.pack()
root.mainloop()
I'm creating a Voice-Assistant in python and tkinter, and I use pyinstaller to convert it to an executable file. The command line is:
pyinstaller -F -w main.py
This is my code:
import pyttsx3
from pyttsx3.drivers import sapi5
import speech_recognition as sr
import time
from tkinter import *
from datetime import datetime
engine = pyttsx3.init()
rate = engine.getProperty("rate")
engine.setProperty("rate", 175)
volume = engine.getProperty("volume")
engine.setProperty("volume", 0.75)
voices = engine.getProperty("voices")
engine.setProperty("voice", voices[2].id)
window = Tk()
var = StringVar()
var1 = StringVar()
class App:
def __init__(self):
window.title("Voice-Assistant")
window.geometry("1280x720")
window.resizable(False, False)
window.iconbitmap(r"C:\Users\itsju\Documents\KarenDef\Projects\Karen10\IconofKaren.ico")
karenW = Frame(window, bg="#3498db")
karenW.place(relwidth=1, relheight=0.5, x=5, y=365)
spokeW = Frame(window, bg="#1a5276")
spokeW.place(relwidth=1, relheight=0.5, x=5)
karenT = Label(karenW, bg="#3498db", fg="white", font=("Consolas", 16), textvariable=var1, wraplength=1230, justify="left")
karenT.place(x=10, y=28)
spokeT = Label(spokeW, bg="#1a5276", fg="white", font=("Consolas", 16), textvariable=var, wraplength=1230, justify="left")
spokeT.place(x=10, y=28)
karenL = Label(karenW, bg="#3498db", fg="white", font=("Calibri 11 bold underline"), text="Karen")
karenL.pack()
spokeL = Label(spokeW, bg="#1a5276", fg="light blue", font=("Calibri 11 bold underline"), text="You")
spokeL.pack()
def talk(self, audio):
var1.set(audio)
window.update()
engine.say(audio)
engine.runAndWait()
def get_command(self):
r = sr.Recognizer()
with sr.Microphone() as source:
var1.set("Listening...")
window.update()
audio = r.listen(source)
spoke = ""
try:
var1.set("Recognizing...")
window.update()
spoke = r.recognize_google(audio, language='nl')
var.set(spoke)
except sr.UnknownValueError:
var1.set("Couldn't get that!")
window.update()
time.sleep(0.25)
var.set("")
except sr.RequestError:
var1.set("Check your internet connection!")
window.update()
time.sleep(0.5)
var.set("")
return spoke.lower()
a = App()
while True:
spoke = get_command()
if 'hello' in spoke:
a.talk("Hello there!")
break
So when this is converted, and I run the program, and it prints 'listening...' into my application. Then if I said something like 'Hello', my program should recognize it and say 'Hello there!' back. Though, it get's into one of the exceptions! If I convert my program with a terminal, command line: pyinstaller -F main.py without -w it works fine! But I don't want a terminal and my tkinter application opened.
Hope someone can help me with this weird problem! Thanks.
I used this code to hide the console with the speech_recognition library:
import ctypes
ctypes.windll.user32.ShowWindow( ctypes.windll.kernel32.GetConsoleWindow(), 0 ) # Hide the console.
Tkinter GUI don't shows up when running in parallel with another infinity loop;i have tried Threading and multiprocessing techniques, whereas used GUI in main code and calling livespeech code or vice versa ; and defining both codes in function and calling from the main thread.But the problem remains; different result are attached below although u find it comment but have tried that method too,
#*********************************** IMPORTING MODULES*****************
import tkinter
from tkinter import*
import tkinter.messagebox
import sqlite3
import os
from multiprocessing import Process
from pocketsphinx import LiveSpeech, get_model_path
import threading
from time import sleep
model_path = get_model_path()
#*************** TKINTER GUI CODE******************
def gui():
window = tkinter.Tk()
window.title("Smart Notice Board")
top = Canvas(window,width=400,height=200)
top.pack(fill=X)
button_5 = Button(text='PORTAL SYSTEM', height = 2, width=17, activebackground = '#33B5e5', bg = 'brown', fg = 'white',command = portal )
top.create_window(80,80, anchor='nw', window = button_5)
def portal():
print("2")
#**************** speech TO text CODE***************
def speech():
speech = LiveSpeech(
verbose=False,
sampling_rate=16000,
buffer_size=2048,
no_search=False,
full_utt=False,
hmm=os.path.join(model_path, 'en-us'),
lm=os.path.join(model_path, '8582.lm'),
dic=os.path.join(model_path, '8582.dict')
)
for phrase in speech:
print(phrase)
a=str(phrase)
print(a)
#************************** MAIN LOOP************************
if __name__ == "__main__":
#************ FOR THREADING************
#thread1 = threading.Thread(target=gui)
#thread2 = threading.Thread(target=speech)
#thread1.daemon = True
#thread1.start()
#thread2.start()
#thread1.join()
#thread2.join()
#************ FOR MULTIPROCESSING****************
#processes=[]
#P1 = Process(target=gui)
#P2 = Process(target=speech)
#processes.append(P1)
#processes.append(P2)
#P2.daemon = True
# Will execute both in parallel
#P1.start()
#P2.start()
# Joins threads back to the parent process, which is this
# program
#P1.join()
#P2.join()
#****************** live speech code*************
window = tkinter.Tk()
window.title("Smart Notice Board")
top = Canvas(window,width=400,height=200)
top.pack(fill=X)
button_5 = Button(text='PORTAL SYSTEM', height = 2, width=17, activebackground = '#33B5e5', bg = 'brown', fg = 'white',command = portal )
top.create_window(80,80, anchor='nw', window = button_5)
IN multiprocessing case; no error but nothing works
This is the code I use to get mouse move event's cursor position from queue and act accordingly:
def check_mouse(self):
while True:
item = self.mouse.get_item()
if item is None:
break
else:
self.master.after_idle(self.mouse_move, *item)
self.master.after(INTERVAL, self.check_mouse)
and it's first time called just before mainloop call, with yet another self.master.after(INTERVAL, self.check_mouse).
So make you Tkinter GUI do its work in the mainloop and you should create another loop with a task that will run after INTERVAL (in miliseconds) and it will call itself every INTERVAL period after its job is finished.
The error, 'cannot invoke 'button' command: application has been destroyed', and I do not understand why.
I have tried seperating the two root.mainloop()s in to two functions, however, this has not worked. This is for a game at school.
### PATHOGEN EVOLUTION ###
### IMPORT ###
import tkinter as tk #Imports the module, 'tkinter', as 'tk'
import random as r #Imports the module, 'random', as 'r'
import time as t #Imports the module, 'time', as 't'
### FUNCTION ###
def game ():
global startButton
global tuberculosisImage
startButton.destroy()
root.mainloop()
imageLoad()
def imageLoad ():
pathogen = tk.Button(root, image = tuberculosisImage)
pathogen.pack()
root.mainloop()
### CODE ###
global startButton
global tuberculosisImage
root = tk.Tk() #Creates a root window named 'root'
root.geometry("1020x720") #Sets the window size of the window, 'root', to 1020 x 720
root.title("Pathogen Evolution") #Changes the title of the window, 'root', to 'Pathogen Evolution'
root.iconbitmap("favicon(1).ico") #Changes the icon of the window, 'root'
startButton = tk.Button(root, text = "Start", border = 2, command = game)
tuberculosisImage = tk.PhotoImage(file = "pathogen1.gif")
startButton.pack()
root.mainloop() #Refreshes the window, 'root'
Middle aged dad (electrical engineer not programmer by trade) trying to teach my 13 year old daughter electronics and programming. So far, I love Python. I am building a program to display temperatures throughout our house with tkinter GUI and DS18B20 sensors.
We've pieced together the program below from reading books, online research and using Stack Overflow for trouble-shooting bugs (this site rocks!).
Now we're stumped, we keep getting an intermittent error, when we run the program the first time after loading idle on our Raspberry, it works fine.
The second time, and all subsequent times, we get this error message:
Traceback (most recent call last):
File "/home/pi/Code-working-library/stackoverflow-paste.py", line 140, in <module>
app.equipTemp.set(tempread)
File "/usr/lib/python2.7/lib-tk/Tkinter.py", line 203, in set
return self._tk.globalsetvar(self._name, value)
RuntimeError: main thread is not in main loop
Note, our understanding is that in order to have a static window and update labels updated temps read off our sensor (DS18B20) we needed to use a thread. The sample code we started with has the _init_ statements with only one underscore preceding and trailing - not sure why, if I add a second underscore, I get error messages. The updating window code we used as our basis came from Raspberry Pi forum
Here is our code:
from Tkinter import *
import tkFont
import os
import glob
import time
import subprocess
import re
import sys
import time
import threading
import Image
import ImageTk
os.system('modprobe w1-gpio')
os.system('modprobe w1-therm')
#28-000005c6ba08
sensors = ['28-000005c6ba08']
sensors1 = ['28-000005c70f69']
def read_temp_raw():
catdata = subprocess.Popen(['cat',device_file], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
out,err = catdata.communicate()
out_decode = out.decode('utf-8')
lines = out_decode.split('\n')
return lines
def read_temp():
lines = read_temp_raw()
while lines[0].strip()[-3:] != 'YES':
time.sleep(0.2)
lines = read_temp_raw()
equals_pos = lines[1].find('t=')
if equals_pos != -1:
temp_string = lines[1][equals_pos+2:]
temp_c = float(temp_string) / 1000.0
temp_f = temp_c * 9.0 / 5.0 + 32.0
return temp_f
########### build window ###################
bground="grey"
class App(threading.Thread):
def _init_(self):
threading.Thread._init_(self)
self.start()
def callback(self):
self.root.quit()
def run(self):
#Make the window
self.root = Tk()
self.root.wm_title("Home Management System")
self.root.minsize(1440,1000)
self.equipTemp = StringVar()
self.equipTemp1 = StringVar()
self.equipTemp2 = StringVar()
self.customFont = tkFont.Font(family="Helvetica", size=16)
# 1st floor Image
img = Image.open("HOUSE-PLANS-01.png")
photo = ImageTk.PhotoImage(img)
Label1=Label(self.root, image=photo)
Label1.place(x=100, y=100)
# 2nd floor
img2 = Image.open("HOUSE-PLANS-02.png")
photo2 = ImageTk.PhotoImage(img2)
Label1=Label(self.root, image=photo2)
Label1.place(x=600, y=100)
# Basement image
img3 = Image.open("HOUSE-PLANS-03.png")
photo3 = ImageTk.PhotoImage(img3)
Label1=Label(self.root, image=photo3)
Label1.place(x=100, y=500)
# Attic Image
img4 = Image.open("HOUSE-PLANS-04.png")
photo4 = ImageTk.PhotoImage(img4)
Label1=Label(self.root, image=photo4)
Label1.place(x=600, y=500)
# House Isometric Image
img5 = Image.open("house-iso.png")
photo5 = ImageTk.PhotoImage(img5)
Label1=Label(self.root, image=photo5)
Label1.place(x=1080, y=130)
#Garage Temp Label
Label2=Label(self.root, textvariable=self.equipTemp, width=6, justify=RIGHT, font=self.customFont)
Label2.place(x=315, y=265)
print "start monitoring and updating the GUI"
self.root.mainloop() #start monitoring and updating the GUI
########### Start Loop ###################
print "starting app"
app = App()
app.start()
print "app started"
################### Begin ds18b20 function ##############
while True:
# 28-000005c6ba08
i = "28-000005c6ba08"
base_dir = '/sys/bus/w1/devices/'
device_folder = glob.glob(base_dir + i)[0]
device_file = device_folder + '/w1_slave'
tempread=round(read_temp(),1)
app.equipTemp.set(tempread)
time.sleep(5)
##################### END ds18b20 Function ######
You need to run the GUI code in the main thread, and your temperature reading code needs to be in the background thread. It's only safe to update the GUI in the main thread, so you can pass the temperature data you're reading from the background thread back to the main thread via a Queue, and have the main thread periodically check for data in the queue using self.root.after():
from Tkinter import *
import tkFont
import os
import glob
import time
import threading
import Image
import Queue
def update_temp(queue):
""" Read the temp data. This runs in a background thread. """
while True:
# 28-000005c6ba08
i = "28-000005c6ba08"
base_dir = '/sys/bus/w1/devices/'
device_folder = glob.glob(base_dir + i)[0]
device_file = device_folder + '/w1_slave'
tempread=round(read_temp(),1)
# Pass the temp back to the main thread.
queue.put(tempread)
time.sleep(5)
class Gui(object):
def __init__(self, queue):
self.queue = queue
#Make the window
self.root = Tk()
self.root.wm_title("Home Management System")
self.root.minsize(1440,1000)
self.equipTemp = StringVar()
self.equipTemp1 = StringVar()
self.equipTemp2 = StringVar()
self.customFont = tkFont.Font(family="Helvetica", size=16)
# 1st floor Image
img = Image.open("HOUSE-PLANS-01.png")
photo = ImageTk.PhotoImage(img)
Label1=Label(self.root, image=photo)
Label1.place(x=100, y=100)
# 2nd floor
img2 = Image.open("HOUSE-PLANS-02.png")
photo2 = ImageTk.PhotoImage(img2)
Label1=Label(self.root, image=photo2)
Label1.place(x=600, y=100)
# Basement image
img3 = Image.open("HOUSE-PLANS-03.png")
photo3 = ImageTk.PhotoImage(img3)
Label1=Label(self.root, image=photo3)
Label1.place(x=100, y=500)
# Attic Image
img4 = Image.open("HOUSE-PLANS-04.png")
photo4 = ImageTk.PhotoImage(img4)
Label1=Label(self.root, image=photo4)
Label1.place(x=600, y=500)
# House Isometric Image
img5 = Image.open("house-iso.png")
photo5 = ImageTk.PhotoImage(img5)
Label1=Label(self.root, image=photo5)
Label1.place(x=1080, y=130)
#Garage Temp Label
Label2=Label(self.root, textvariable=self.equipTemp, width=6, justify=RIGHT, font=self.customFont)
Label2.place(x=315, y=265)
print "start monitoring and updating the GUI"
# Schedule read_queue to run in the main thread in one second.
self.root.after(1000, self.read_queue)
def read_queue(self):
""" Check for updated temp data"""
try:
temp = self.queue.get_nowait()
self.equipTemp.set(temp)
except Queue.Empty:
# It's ok if there's no data to read.
# We'll just check again later.
pass
# Schedule read_queue again in one second.
self.root.after(1000, self.read_queue)
if __name__ == "__main__":
queue = Queue.Queue()
# Start background thread to get temp data
t = threading.Thread(target=update_temp, args=(queue,))
t.start()
print "starting app"
# Build GUI object
gui = Gui(queue)
# Start mainloop
gui.root.mainloop()
Edit:
After actually taking a look at the tkinter source code, as well as the Python bug tracker, it appears that unlike almost every other GUI library out there, tkinter is intended to be thread-safe, as long you run the mainloop in the main thread of the application. See the answer I added here for more info, or go straight to the resolved issue about tkinter's thread safety on the Python bug tracker here. If the tkinter source and Python's bug tracker are correct, that would mean that as long as you run the mainloop in the main thread, you can happily call gui.equipTemp.set() directly from your temperature reading thread - no Queue required. And in my testing, that did indeed work just fine.
GUI toolkits are not threadsafe. You can only built and change your GUI from the main thread.
Since reading the temperature does not take that long, you can remove all the threading code and use the after-method from Tk.
Your read_temp_raw function is very complicated:
def read_temp_raw():
with open(device_file) as temp:
return temp.read().split('\n')