Python Forum
[PyQt] [Solved]Help getting out of loop
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
[PyQt] [Solved]Help getting out of loop
#1
Hello,

I have a GUI where I click a button and I want it to launch tmy "A.I" Assistant (BAXTER_V5.py) but when I click the button on my GUI I get stuck in this loop:
Output:
Online Mode Engaged B.A.X.T.E.R A.I System Systems Started... Defaulting to Keyboard Input... B.A.X.T.E.R System Online QCoreApplication::exec: The event loop is already running QCoreApplication::exec: The event loop is already running QCoreApplication::exec: The event loop is already running QCoreApplication::exec: The event loop is already running QCoreApplication::exec: The event loop is already running QCoreApplication::exec: The event loop is already running QCoreApplication::exec: The event loop is already running QCoreApplication::exec: The event loop is already running QCoreApplication::exec: The event loop is already running QCoreApplication::exec: The event loop is already running QCoreApplication::exec: The event loop is already running QCoreApplication::exec: The event loop is already running QCoreApplication::exec: The event loop is already running QCoreApplication::exec: The event loop is already running QCoreApplication::exec: The event loop is already running QCoreApplication::exec: The event loop is already running QCoreApplication::exec: The event loop is already running QCoreApplication::exec: The event loop is already running QCoreApplication::exec: The event loop is already running QCoreApplication::exec: The event loop is already running ...


How do I fix my code so this loop doesn't happen?
What I want to happen is, once I click the Online Mode Button I want to close my GUI and Run BAXTER_V5.py.
Any ideas on why this happens and how to fix it?

Thanks in advance.

BX_MainMenuGUI.py
import sys
from PyQt5 import QtCore, QtWidgets, QtGui
from PyQt5.QtSql import QSqlDatabase, QSqlTableModel
from PyQt5.QtWidgets import (QApplication, QWidget, QPushButton, QMainWindow, 
                                QLabel, QLineEdit, QTableWidget, QTableWidgetItem, 
                                QGridLayout, QVBoxLayout, QSizePolicy, QSpacerItem, 
                                QMessageBox,QSpinBox, QComboBox, QTableView,QStyledItemDelegate)
from PyQt5.QtCore import Qt, QMetaObject, QCoreApplication
from PyQt5.QtGui import QFont

import sqlite3

class Ui_MainMenu(QMainWindow):
    def __init__(self, parent = None):
        super(Ui_MainMenu, self).__init__(parent)
        self.setObjectName("MainMenu")
        self.resize(808, 594)
        self.setStyleSheet("background-color: rgb(0, 0, 0);")
        self.centralwidget = QtWidgets.QWidget(self)
        self.centralwidget.setObjectName("centralwidget")
        self.verticalLayout = QtWidgets.QVBoxLayout(self.centralwidget)
        self.verticalLayout.setObjectName("verticalLayout")
        self.TitleLabel = QtWidgets.QLabel(self.centralwidget)
        font = QtGui.QFont()
        font.setFamily("Android Insomnia")
        font.setPointSize(20)
        font.setBold(True)
        font.setWeight(75)
        self.TitleLabel.setFont(font)
        self.TitleLabel.setStyleSheet("color: rgb(0, 255, 0);")
        self.TitleLabel.setAlignment(QtCore.Qt.AlignCenter)
        self.TitleLabel.setObjectName("TitleLabel")
        self.verticalLayout.addWidget(self.TitleLabel)
        self.textBrowser = QtWidgets.QTextBrowser(self.centralwidget)
        font = QtGui.QFont()
        font.setFamily("Runlion")
        font.setPointSize(12)
        font.setBold(True)
        font.setWeight(75)
        self.textBrowser.setFont(font)
        self.textBrowser.setLayoutDirection(QtCore.Qt.LeftToRight)
        self.textBrowser.setStyleSheet("color: rgb(255, 170, 0);")
        self.textBrowser.setObjectName("textBrowser")
        self.verticalLayout.addWidget(self.textBrowser)
        self.textBrowser_2 = QtWidgets.QTextBrowser(self.centralwidget)
        font = QtGui.QFont()
        font.setFamily("Runlion")
        font.setPointSize(12)
        font.setBold(True)
        font.setWeight(75)
        self.textBrowser_2.setFont(font)
        self.textBrowser_2.setStyleSheet("color: rgb(0, 0, 255);")
        self.textBrowser_2.setObjectName("textBrowser_2")
        self.verticalLayout.addWidget(self.textBrowser_2)
        self.OnlineButton = QtWidgets.QPushButton(self.centralwidget)
        font = QtGui.QFont()
        font.setFamily("Lethal Injector")
        font.setPointSize(12)
        font.setBold(True)
        font.setWeight(75)
        self.OnlineButton.setFont(font)
        self.OnlineButton.setStyleSheet("background-color: rgb(0, 255, 0);\n"
"border-style: outset;\n"
"border-width: 2px;\n"
"border-color: black;\n"
"padding: 4px;")
        self.OnlineButton.setObjectName("OnlineButton")
        self.verticalLayout.addWidget(self.OnlineButton)
        self.OfflineButton = QtWidgets.QPushButton(self.centralwidget)
        font = QtGui.QFont()
        font.setFamily("Lethal Injector")
        font.setPointSize(12)
        font.setBold(True)
        font.setWeight(75)
        self.OfflineButton.setFont(font)
        self.OfflineButton.setStyleSheet("background-color: rgb(255, 0, 0);\n"
"border-style: outset;\n"
"border-width: 2px;\n"
"border-color: black;\n"
"padding: 4px;")
        self.OfflineButton.setObjectName("OfflineButton")
        self.verticalLayout.addWidget(self.OfflineButton)
        self.SettingsButton = QtWidgets.QPushButton(self.centralwidget)
        font = QtGui.QFont()
        font.setFamily("Lethal Injector")
        font.setPointSize(12)
        font.setBold(True)
        font.setWeight(75)
        self.SettingsButton.setFont(font)
        self.SettingsButton.setStyleSheet("background-color: rgb(255, 170, 0);\n"
"border-style: outset;\n"
"border-width: 2px;\n"
"border-color: black;\n"
"padding: 4px;")
        self.SettingsButton.setObjectName("SettingsButton")
        self.verticalLayout.addWidget(self.SettingsButton)
        self.setCentralWidget(self.centralwidget)
        self.statusbar = QtWidgets.QStatusBar(self)
        self.statusbar.setObjectName("statusbar")
        self.setStatusBar(self.statusbar)

        self.retranslateUi(self)
        QtCore.QMetaObject.connectSlotsByName(self)

        
#----------------------------------------------------------------------------------------------------
#                                      Button Actions
#----------------------------------------------------------------------------------------------------
        #------------------------------------------
        #               Online Mode Button
        #------------------------------------------
        #When the Online Mode button is clicked -> OnlineClicked Function
        OnlineButton = self.OnlineButton
        OnlineButton.clicked.connect(self.OnlineClicked)
        #------------------------------------------

#----------------------------------
#       Online Mode Function
#----------------------------------
    def OnlineClicked(self):
        #Print in terminal for testing:
        print("Online Mode Engaged")
        self.close() #Close this screen
        #Run Baxter
        from BAXTER_V5 import BAXTER
        BAXTER()
#----------------------------------

#----------------------------------------------------------------------------------------------------
#                                      Retranslate Ui
#----------------------------------------------------------------------------------------------------
    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        self.setWindowTitle(_translate("MainWindow", "BAXTER Menu"))
        self.TitleLabel.setText(_translate("MainWindow", "B.A.X.T.E.R A.I System"))
        self.textBrowser.setHtml(_translate("MainWindow", "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0//EN\" \"http://www.w3.org/TR/REC-html40/strict.dtd\">\n"
"<html><head><meta name=\"qrichtext\" content=\"1\" /><style type=\"text/css\">\n"
"p, li { white-space: pre-wrap; }\n"
"</style></head><body style=\" font-family:\'Runlion\'; font-size:12pt; font-weight:600; font-style:normal;\">\n"
"<p align=\"center\" style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">Reminders:</p></body></html>"))
        self.textBrowser_2.setHtml(_translate("MainWindow", "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0//EN\" \"http://www.w3.org/TR/REC-html40/strict.dtd\">\n"
"<html><head><meta name=\"qrichtext\" content=\"1\" /><style type=\"text/css\">\n"
"p, li { white-space: pre-wrap; }\n"
"</style></head><body style=\" font-family:\'Runlion\'; font-size:12pt; font-weight:600; font-style:normal;\">\n"
"<p align=\"center\" style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">Todo:</p></body></html>"))
        self.OnlineButton.setText(_translate("MainWindow", "Online Mode"))
        self.OfflineButton.setText(_translate("MainWindow", "Offline Mode"))
        self.SettingsButton.setText(_translate("MainWindow", "Settings"))


#----------------------------------------------------------------------------------------------------
#                                       Run this Program
#----------------------------------------------------------------------------------------------------
def main():
    app = QApplication(sys.argv)
    win = Ui_MainMenu()
    win.show()
    sys.exit(app.exec_())

if __name__ == "__main__":
    main()
#----------------------------------------------------------------------------------------------------
BAXTER_V5.py
#-------------------------------------------------------------------------------------
#                                  Imports
#-------------------------------------------------------------------------------------
import json
import random
import datetime
import operator
import os
import subprocess
import time
import sys
from unittest import result
import webbrowser
import requests
from bs4 import BeautifulSoup
import wikipedia
import wolframalpha
import pywhatkit
import threading
 

from BX_Intents import (greetings, farewell, thanks, noAnswer, youChoose)
from BX_External_Functions import (autoTypeAnimation, StartupText, ShutdownText, 
                                    UserInput, listen, speak, getRandomJoke, getFunFacts,
                                    setReminders, terminateTimers)

from pairs import chat
#-------------------------------------------------------------------------------------
#-------------------------------------------------------------------------------------
#                           Commander Name (You) and A.I Name
#-------------------------------------------------------------------------------------
Commander = "Commander"
AI_Name = 'Baxter'
#-------------------------------------------------------------------------------------

#-------------------------------------------------------------------------------------
#                                  WishMe Function
#-------------------------------------------------------------------------------------
def wishMe():
    hour = int(datetime.datetime.now().hour)
    if hour>=0 and hour<12:
        speak("Good Morning" + Commander)
    elif hour>=12 and hour<18:
        speak("Good Afternoon" + Commander)   
    else:
        speak("Good Evening" + Commander) 
#-------------------------------------------------------------------------------------


#-------------------------------------------------------------------------------------
#                                       Main
#-------------------------------------------------------------------------------------
def BAXTER():
    command = UserInput()
    command=str(command).lower()

    #-------------------------------------------------------------------------------------
    #                       General Conversation (From Intents.py) 
    #-------------------------------------------------------------------------------------
    #Greetings
    patterns, responses = greetings()
    if (command in patterns):
        results = (random.choice(responses))
        autoTypeAnimation(results)
        speak(results)

    #Farewell
    patterns, responses = farewell()
    if (command in patterns):
        results = (random.choice(responses))
        autoTypeAnimation(results)
        speak(results)
    
    #Thanks
    patterns, responses = thanks()
    if (command in patterns):
        results = (random.choice(responses))
        autoTypeAnimation(results)
        speak(results)
    
    #No Response
    patterns, responses = noAnswer()
    if (command in patterns):
        results = (random.choice(responses))
        autoTypeAnimation(results)
        speak(results)

    #-------------------------
    #       Tell a Joke
    #-------------------------
    if ('joke' in command):
        joke = getRandomJoke()
        autoTypeAnimation(joke)
        speak(joke)
    #-------------------------
    #-------------------------
    #     Tell a Fun Fact
    #-------------------------
    if ('fact' in command):
        funFact = getFunFacts()
        autoTypeAnimation(funFact)
        speak(funFact)
    #-------------------------
    
    #-------------------------------------------------------------------------------------
    #                       Search Wikipedia (General Info)
    #-------------------------------------------------------------------------------------
    if ('weather' not in command):
        if ('who is' in command) or ('what is the' in command) or ('what is a' in command) or ("what is" in command):
            if ('time' not in command):
                if ('news' not in command):
                    speak('Searching...')
                    command = command.replace("who is","")
                    command = command.replace("what is the","")
                    command = command.replace("what is a","")
                    command = command.replace("what is","")
                    results = wikipedia.summary(command, sentences = 2)
                    autoTypeAnimation(results)
                    speak(results) 
                    
    #-------------------------------------------------------------------------------------
    #               Search Wolfram Alpha (Math/Conversions, Definitions)
    #-------------------------------------------------------------------------------------
    if ('news' not in command):
        if ('weather' in command) or ('calculate' in command) or ("what's" in command) or ('define' in command) or ("what" in command):
                speak('Searching...')
                command = command.replace("calculate","")
                command = command.replace("what's","")
                command = command.replace("define","")
                # Wolframalpha App Id
                appId = 'JH9XHR-W9J76L7H5A'
                # Wolfram Instance
                client = wolframalpha.Client(appId)
                res = client.query(''.join(command))
                results = next(res.results).text
                autoTypeAnimation(results)
                speak(results)

    #-------------------------------------------------------------------------------------
    #                       Open Stuff on the Internet
    #-------------------------------------------------------------------------------------
    #Open Youtube Videos (Ex: 'Play __ on youtube')
    if ('youtube' in command):
        autoTypeAnimation("Launching Youtube...")
        speak('Launching Youtube')
        command = command.replace("youtube","")
        pywhatkit.playonyt(command)

    #Open Google Maps and Find The Location of A You Want
    if ('where is' in command):
        command = command.replace("where is","")
        autoTypeAnimation("Locating" + command + "...")
        speak('Locating' + command)
        webbrowser.open_new_tab("https://www.google.com/maps/place/" + command)

    #Search Stuff on Google
    if ('search' in command):
        command = command.replace("search", "")
        autoTypeAnimation("Searching" + command + " on Google")
        speak('Searching' + command)
        pywhatkit.search(command)
    
    #Close Firefox
    if ('close firefox' in command):
        autoTypeAnimation("Terminating Firefox...")
        speak('Closing Firefox')
        command = command.replace("close firefox", "")
        browser = "firefox.exe"
        os.system("taskkill /f /im " + browser)   

    #-------------------------------------------------------------------------------------
    #                       Open Stuff on the Computer
    #-------------------------------------------------------------------------------------
    #Open Windows Media Player and Auto Play the Playlist Called Music
    if ('play music' in command) or ('media player' in command) or ('drop the needle' in command):
        autoTypeAnimation("Launching music...")
        speak("Launching Music")
        command = command.replace("play music", "")
        command = command.replace("media player", "")
        command = command.replace("drop the needle", "") 
        subprocess.Popen("C:\Program Files (x86)\Windows Media Player\wmplayer.exe /Playlist Music")

    #Close Windows Media Player
    if ('stop music' in command):
        autoTypeAnimation("Terminating music...")
        speak('Closing Music')
        command = command.replace("stop music", "")
        mediaPlayer = "wmplayer.exe"
        os.system("taskkill /f /im " + mediaPlayer)   

    #-------------------------------------------------------------------------------------
    #                               Set Reminders
    #-------------------------------------------------------------------------------------
    if ('remind me' in command):
        command = command.replace("remind me", "")
        setReminders(command) #Call setReminders() from External Functions
    
    #-------------------------------------------------------------------------------------
    #                       Stop Program/Script Command
    #-------------------------------------------------------------------------------------
    if ('stop' in command) or ('shutdown' in command) or ('quit' in command):
        speak("Shutting Down...")
        results = "Terminating program..."
        autoTypeAnimation(results)
        ShutdownText()
        terminateTimers()
        exit()
    #-------------------------------------------------------------------------------------
#-------------------------------------------------------------------------------------
      

#------------------------------------------------------------------------------------------
#                                   Run The Program
#------------------------------------------------------------------------------------------
StartupText()
wishMe()
speak("How may I be of service?") 

while True:
    BAXTER()
#------------------------------------------------------------------------------------------
Reply
#2
A few odd things I noticed. This is this in the bottom of BAXTER_V5.py
StartupText()
wishMe()
speak("How may I be of service?") 
 
while True:
    BAXTER()
This code runs when the module is imported the first time. It does not run again. If your GUI tries to run BAXTER again, it does so without the StartupText() or the wishMe or the greeting, and the BAXTER() function only runs once. I don't know if that is what you want or not.

This runs BAXTER()
    def OnlineClicked(self):
        #Print in terminal for testing:
        print("Online Mode Engaged")
        self.close() #Close this screen
        #Run Baxter
        from BAXTER_V5 import BAXTER
        BAXTER()
The first time OnlineClicked() is called, the BAXTER_V5 module is imported. This automatically runs the code mentioned above (StartupText(), wishMe(), greeting. BAXTER() in a loop) and then it calls BAXTER() one more time. Well, it is programmed to call BAXTER() one more time, but it can't.

BAXTER does not exit nicely. When you ask BAXTER to stop, exit or quit, he does this:
    if ('stop' in command) or ('shutdown' in command) or ('quit' in command):
        speak("Shutting Down...")
        results = "Terminating program..."
        autoTypeAnimation(results)
        ShutdownText()
        terminateTimers()
        exit()
This ends the program. The entire program. There is no way to call BAXTER() again because the program that might call BAXTER() is no longer running. I would expect BAXTER to loop until the stop request, do a little cleanup, and return. Or did you expect BAXTER() to only process one request and return? If so, you need to modify the BAXTER_V4.py module.
Output:
if __name__ == "__main__": StartupText() wishMe() speak("How may I be of service?") while True: BAXTER()[/python]
The if statement prevents running the enclosed block when the module is imported. You can still run BAXTER standalone, and you can call the BAXTER() function from another program.

Even if you make BAXTER play nice you still have another problem. This is how you start BAXTER when a button is pressed:
    def OnlineClicked(self):
        #Print in terminal for testing:
        print("Online Mode Engaged")
        self.close() #Close this screen
        #Run Baxter
        from BAXTER_V5 import BAXTER
        BAXTER()
close() does not just close the screen, it quits the program. The QApplication.exec_() runs an event loop until all the windows are closed. When the event loop stops running, exec_() returns, allowing sys.exit(app.exec_()) to finally run, and this exits the program.

As for the loop, I don't think you are showing the code that cause the problem. This short example demonstrates your problem.
import sys
from PySide6.QtWidgets import QApplication, QWidget, QVBoxLayout, QPushButton

class MyWindow(QWidget):
    def __init__(self, *args, **kvargs):
        super().__init__(*args, **kvargs)
        button = QPushButton("Push Me", self)
        button.clicked.connect(self.button_clicked)
        QVBoxLayout(self).addWidget(button)

    def button_clicked(self):
        app.exec()

app = QApplication()
window = MyWindow()
window.show()
sys.exit(app.exec())
Each time I press the "Push Me" button I get this message.
Output:
QCoreApplication::exec: The event loop is already running QCoreApplication::exec: The event loop is already running QCoreApplication::exec: The event loop is already running QCoreApplication::exec: The event loop is already running QCoreApplication::exec: The event loop is already running
In the posted code, exec (or exec_) is only called once. Do you have another piece of code that calls exec_()? If so, that is where the error occurs.
Reply
#3
Thanks for the response.

What I'm trying to do is once the Online Mode Button is clicked, the GUI quits and BAXTER_V5.py runs in the terminal. Then to exit BAXTER I just type in one of the exit/stop commands and the program should quit.

So is there a way to do that so once the Button on the GUI is clicked, it runs BAXTER but quits the GUI (since the GUI is no longer needed)?

Thanks again.


(Sep-25-2022, 12:41 PM)deanhystad Wrote: In the posted code, exec (or exec_) is only called once. Do you have another piece of code that calls exec_()? If so, that is where the error occurs.
Also, No, I don't have any other pieces of code that call exec_(). The GUI is the only one that calls exec_().
Reply
#4
The GUI does not quit when you click the button. Clicking the button closes the window. The event manager will notice no windows are open and exits exec_(). But that doesn't happen in your program. In your program the function that closes the window also imports and calls BAXTER. The event manager loop is blocked waiting for the button callback to return. This never happens because importing BAXTER() eventually leads to BAXTER calling exit() and shutting down the process.

This is demonstrated by the program below. Pressing "Introducing a surprise guest" closes the window without quitting the application. The event manager waits for special_guest() to return, and when it does, window is no longer closed. Pressing "Time for bed" calls close and returns immediately. The window manager sees there are no windows still open and exec() returns.
import sys
from PySide6.QtWidgets import QApplication, QWidget, QVBoxLayout, QPushButton
import tkinter as tk

class MyWindow(QWidget):
    def __init__(self):
        super().__init__()
        layout = QVBoxLayout(self)

        button = QPushButton("Introducing a surprise guest", parent=self)
        button.clicked.connect(self.surprise_guest)
        layout.addWidget(button)

        button = QPushButton("Time for bed", parent=self)
        button.clicked.connect(self.close)
        layout.addWidget(button)

    def surprise_guest(self):
        self.close()
        root = tk.Tk()
        tk.Label(root, text="Close this window to continue").pack(padx=20, pady=20)
        root.mainloop()
        self.show()


app = QApplication()
window = MyWindow()
window.show()
sys.exit(app.exec())
For Qt5 you'll need to change exec() to exec_().

I am still confused about your error. The only way I can find to get that error message is calling exec_(). Do you have something that calls main()? What does UserInput() do?
Reply
#5
Nothing calls main() either (expect for the if statement in the GUI code: if __name__ == "__main__": main())

And this is UserInput() (It takes in the user's input from the terminal and stores it in the command variable)
#-------------------------------------------------------------------------------------
#                                User Input Function
#-------------------------------------------------------------------------------------
def UserInput():
    command = str(Prompt.ask("[yellow]Commander[/yellow]"))
    # CommanderInput(command)
    return command 
#-------------------------------------------------------------------------------------
Here are all the external functions from BX_External_Functions:
#!/usr/bin/env python3

#-------------------------------------------------------------------------------------
#                               B.A.X.T.E.R Externalized Functions
#-------------------------------------------------------------------------------------

#----------------------------------------------------------------------------------------------
#                                  Table Of Contents/Overview
#----------------------------------------------------------------------------------------------
# Imports
# Define Variables

# Auto Type Function
# Jokes 
# Fun Facts
# Listen Function -> Uses Google API to Listen
# Reminder Function
# Startup & Shutdown Text Function
# Terminate Timers
# User Input Function
# Voice Settings
#----------------------------------------------------------------------------------------------

#-------------------------------------------------------------------------------------
#                                  Imports
#-------------------------------------------------------------------------------------
import time
import datetime
import random
import sys
import requests
import json
import threading

import smtplib
import ssl
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText

import keyboard

import speech_recognition as sr
import pyttsx3

from rich import print
from rich.console import Console
from rich.prompt import Prompt

from BX_Intents import (youChoose)
#-------------------------------------------------------------------------------------

#-------------------------------------------------------------------------------------
#                                Define Variables
#-------------------------------------------------------------------------------------
console = Console(width=100) 
#-------------------------------------------------------------------------------------


#-------------------------------------------------------------------------------------
#                                Auto Type Function
#-------------------------------------------------------------------------------------
def autoTypeAnimation(results):
    #----------------------
    #Auto typing animation:
    print("[green]Baxter: [/green]", end="")
    for i in results:
        sys.stdout.write(i)
        sys.stdout.flush()
        time.sleep(0.05)
    print("\n")
    #---------------------- 
#-------------------------------------------------------------------------------------


#-------------------------------------------------------------------------------------
#                               Fun Facts Function
#-------------------------------------------------------------------------------------
def getFunFacts():
    # URL from where we will fetch the data
    url = "https://uselessfacts.jsph.pl/random.json?language=en"
      
    # Use GET request
    response = requests.request("GET", url)  
      
    # Load the request in json file
    data = json.loads(response.text)
    result = data['text']
    return result
#-------------------------------------------------------------------------------------

#-------------------------------------------------------------------------------------
#                                Joke Function
#-------------------------------------------------------------------------------------
def getRandomJoke():
    headers = {
        'Accept': 'application/json'
    }
    result = requests.get("https://icanhazdadjoke.com/", headers=headers).json()
    return result["joke"]
#-------------------------------------------------------------------------------------

#-------------------------------------------------------------------------------------
#                                Listen Function
#-------------------------------------------------------------------------------------
def listen():
    hear = sr.Recognizer()
    with sr.Microphone() as source:
        results = "Listening..."
        autoTypeAnimation(results)
        audio = hear.listen(source)  
    try:
        results = "Recognizing..."
        autoTypeAnimation(results)
        # Uses google API to listen
        command = hear.recognize_google(audio, language='en-in')
        print("[yellow]Commander: " + command)

    except:
            pass

    return command 
#-------------------------------------------------------------------------------------

#-------------------------------------------------------------------------------------
#                                Reminder Function
#-------------------------------------------------------------------------------------
def setReminders(command):
    results = "Would you like to pick a time for me to remind you, or should I do it?"
    autoTypeAnimation(results)
    speak(results)
    
    #User enters choice and thier input gets converted to lowercase 
    choiceCommand = UserInput() #Take user's input
    choiceCommand=str(choiceCommand).lower() #Convert str cmd to lowercase

    #Scan through the youChoose() list to see if the user's input matches
    #If it does, have Baxter randomly choose a time to remind the user
    #Else, have the user enter the time they would like to be reminded 
    patterns = youChoose()
    if (choiceCommand in patterns):
        #Baxter picks a random time to remind you
        remindTimeHrs = random.uniform(0.5,5.0) #Range: 0.5hrs - 5hrs
        remindTimeHrs = round(remindTimeHrs,2) #Round RemindTimeHrs to 2 decimal places
        remindTimeSec = remindTimeHrs*3600 #Hrs->Sec
        results = "Ok, I will remind you" + command + " in " + str(remindTimeHrs) + " hours"
        autoTypeAnimation(results)
        speak(results)
        t = threading.Timer(remindTimeSec, reminderPopup, args=(command,))
        t.start() #Start the timer
        
    else:
        #User picks the time to be reminded
        results = "When should I remind you" + command +"?"
        autoTypeAnimation(results)
        speak(results)
        while True:
            autoTypeAnimation("Enter wait time (H:M:S) (Ex: 0:0:5 -> 5sec)")
            timestr = UserInput()
            if not timestr:
                break
            try:
                h,m,s = timestr.split(':')
                timestr = (int(datetime.timedelta(hours=int(h),minutes=int(m),seconds=int(s)).total_seconds()))
                t = threading.Timer(timestr, reminderPopup, args=(command,))
                results = "Ok, I will remind you" + command + " in " + h + " Hours "+ m + " minutes " + s + " seconds"
                autoTypeAnimation(results)
                speak(results)
                t.start() #Start the timer
                break
            except ValueError:
                print("[green]Baxter: [red]Not a valid time input")


def reminderPopup(command):
    print("\n")
    style = "bold"
    console.print("[green]Baxter:", style=style, justify="center")
    console.print("[cyan]Reminder Alert!", style=style, justify="center")
    console.print("[cyan]I was told to remind you" + command, style=style, justify="center")
    speak("I hate to interrupt, but I was told to remind you" + command)
    keyboard.press('ENTER') #'Press' Enter to crudely clear the user query
#-------------------------------------------------------------------------------------

#-------------------------------------------------------------------------------------
#                             Startup & Shutdown Function
#-------------------------------------------------------------------------------------
def StartupText():
    #----------------------
    #Auto typing animation:
    results = """
    Systems Started...
    Defaulting to Keyboard Input...
    B.A.X.T.E.R System Online
    """
    #Print Start Header
    style = "bold green on blue"
    console.print("[green]B.A.X.T.E.R A.I System", style=style, justify="center")
    #Print Text
    console.print("[green]"+ results, justify="center")

def ShutdownText():
    #----------------------
    #Auto typing animation:
    results = """
    Systems Terminated...
    B.A.X.T.E.R System Offline
    """
    #Print Text
    console.print("[red]"+ results, justify="center")
    #Print End Header
    style = "bold blue on red"
    console.print(" ", style=style, justify="center")
#-------------------------------------------------------------------------------------

#-------------------------------------------------------------------------------------
#                             Terminate Timers Function
#-------------------------------------------------------------------------------------
def terminateTimers():
    #Cancel all ongoing timers
    for timer in threading.enumerate():
        if isinstance(timer, threading.Timer):
            #print(timer)
            timer.cancel()
#-------------------------------------------------------------------------------------

#-------------------------------------------------------------------------------------
#                                User Input Function
#-------------------------------------------------------------------------------------
def UserInput():
    command = str(Prompt.ask("[yellow]Commander[/yellow]"))
    # CommanderInput(command)
    return command 
#-------------------------------------------------------------------------------------

#-------------------------------------------------------------------------------------
#                                  Voice Settings
#-------------------------------------------------------------------------------------
def speak(audio):
    speaker = pyttsx3.init ()
    voices = speaker.getProperty('voices')
    speaker.setProperty('voice',voices[2].id)
    speaker.setProperty ('rate', 180)
    speaker.say (audio)
    speaker.runAndWait () 
# # Test to see all avaliable voices
# engine = pyttsx3.init()
# voices = engine.getProperty('voices')
# for voice in voices:
#     print(voice, voice.id)
#     engine.setProperty('voice', voice.id)
#     engine.say("Hello World!")
#     engine.runAndWait()
#     engine.stop()
#-------------------------------------------------------------------------------------
Reply
#6
I managed to get it working.

I used threading to have the BX_V5.py run while the GUI is running and it allows the GUI to quit without getting stuck in a loop.

BX_MainMenuGUI.py Snippet:
#----------------------------------
#       Online Mode Function
#----------------------------------
    def OnlineClicked(self):
        #Print in terminal for testing:
        print("Online Mode Engaged")
        import threading
        from BAXTER_V5 import Main
        t = threading.Timer(1,Main)
        t.start() #Start the timer
        self.close() #Quit the GUI
#----------------------------------
BX_V5.py Snippet:
#------------------------------------------------------------------------------------------
#                                   Run The Program
#------------------------------------------------------------------------------------------
# if __name__ == "__main__":
#     StartupText()
#     wishMe()
#     speak("How may I be of service?") 
#     while True:
#         BAXTER()

def Main():
    StartupText()
    wishMe()
    speak("How may I be of service?") 
    while True:
        BAXTER()
#------------------------------------------------------------------------------------------
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  [PyQt] [Solved]Populate ComboBox with for loop? Extra 3 2,137 Jul-31-2022, 09:01 PM
Last Post: Extra
  [PyQt] [Solved]Help Adding results from for loop Extra 2 1,452 Jun-24-2022, 05:01 PM
Last Post: Extra

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020