How to return value of PyQt5 QInputDialog as input to a function

217 Views Asked by At

I am trying to make a simple gui for an AI assistant using PyQt5. In the gui I created a QPlainTextEdit to show the output of my Main program and created an QInputDialog to take user input. The output is working fine.

For the input I tried two things:

  1. First I tried to call the QInputDialog from the Main function (which is in another file), wherever input was needed I replace input() with userInput() (this function contains the QInputDialog). But importing the userInput function causes the MainWindow of GUI to run again, resulting in error.
  2. I created a button called "Input" to connect to the QInputDialog. This works fine, I click the "Input" button whenever written user input is required and the QInputDialog pops up. But I am unable to provide the returned value as input to the Main program.

Please let me know how can I return the QInputDialog value as input()

Here is the code

techna.py

from PyQt5 import QtCore, QtWidgets, QtGui
from PyQt5.QtGui import QMovie, QTextBlock
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
from gui.technaui2 import Ui_technaui2
import sys
import techna2


class MainThread(QThread):
    def __init__(self):
        super(MainThread, self).__init__()

    def run(self):
        self.TaskGui()

    def TaskGui(self):
        while True:
            techna2.Main()


startFunction = MainThread()


class GuiStart(QMainWindow):
    def __init__(self):
        super().__init__()

        self.technaui2 = Ui_technaui2()
        self.technaui2.setupUi(self)
        self.technaui2.pushButton.clicked.connect(self.startFunc)
        self.technaui2.pushButton_2.clicked.connect(self.close)
        self.technaui2.btn1.clicked.connect(self.userInput2)
        sys.stdout = EmittingStream(textWritten=self.normalOutputWritten)

    def __del__(self):
        # Restore sys.stdout
        sys.stdout = sys.__stdout__

    def normalOutputWritten(self, text):
        """Append text to the QTextEdit."""
        cursor = self.technaui2.textEdit.textCursor()
        cursor.movePosition(QtGui.QTextCursor.End)
        cursor.insertText(text)
        self.technaui2.textEdit.setTextCursor(cursor)
        self.technaui2.textEdit.ensureCursorVisible()

    def startFunc(self):
        self.technaui2.movies = QtGui.QMovie(
            "C:\\Users\\Hp\\Desktop\\SP\\techna2\\gui\\images\\gif\\ai2.gif"
        )
        self.technaui2.gif.setMovie(self.technaui2.movies)
        self.technaui2.movies.start()

        startFunction.start()

    def userInput2(self):
        text, ok = QtWidgets.QInputDialog.getText(self, "Introduce value", "Value:")
        if ok:
            return str(text)
        else:
            print("Invalid")
            # return ""


class EmittingStream(QtCore.QObject):
    textWritten = QtCore.pyqtSignal(str)

    def write(self, text):
        self.textWritten.emit(str(text))


guiApp = QApplication(sys.argv)

guiTechna = GuiStart()

guiTechna.show()

exit(guiApp.exec_())

technaui2.py

from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtWidgets import *
import sys


class Ui_technaui2(object):
    def setupUi(self, technaui2):
        technaui2.setObjectName("technaui2")
        technaui2.resize(1000, 800)
        self.centralwidget = QtWidgets.QWidget(technaui2)
        self.centralwidget.setObjectName("centralwidget")
        self.label = QtWidgets.QLabel(self.centralwidget)
        self.label.setGeometry(QtCore.QRect(-6, -1, 651, 411))
        self.label.setText("")
        self.label.setPixmap(
            QtGui.QPixmap(
                "C:\\Users\\Hp\\Desktop\\SP\\techna2\\gui\\images\\use\\bg.webp"
            )
        )
        self.label.setScaledContents(True)
        self.label.setObjectName("label")
        self.gif = QtWidgets.QLabel(self.centralwidget)
        self.gif.setGeometry(QtCore.QRect(147, 0, 321, 261))
        self.gif.setStyleSheet("border : 1px solid purple;")
        self.gif.setText("")
        self.gif.setPixmap(
            QtGui.QPixmap(
                "C:\\Users\\Hp\\Desktop\\SP\\techna2\\gui\\images\\gif\\ai2.gif"
            )
        )
        self.gif.setScaledContents(True)
        self.gif.setObjectName("gif")
        self.pushButton = QtWidgets.QPushButton(self.centralwidget)
        self.pushButton.setGeometry(QtCore.QRect(675, 330, 111, 51))
        self.pushButton.setStyleSheet(
            'font: 16pt "Modern No. 20";\n'
            "background-color: rgb(0, 0, 0);\n"
            "color: rgb(255, 255, 255);\n"
            "color: qlineargradient(spread:pad, x1:0, y1:0, x2:1, y2:0, stop:0 rgba(0, 61, 162, 255), stop:1 rgba(255, 255, 255, 255));\n"
            "border : 1px solid;\n"
            "border-color: rgb(170, 85, 255);"
        )
        self.pushButton.setObjectName("pushButton")
        self.pushButton_2 = QtWidgets.QPushButton(self.centralwidget)
        self.pushButton_2.setGeometry(QtCore.QRect(675, 400, 111, 51))
        self.pushButton_2.setStyleSheet(
            'font: 16pt "Modern No. 20";\n'
            "\n"
            "background-color: rgb(0, 0, 0);\n"
            "color: rgb(255, 255, 255);\n"
            "color: qlineargradient(spread:pad, x1:0, y1:0, x2:1, y2:0, stop:0 rgba(0, 61, 162, 255), stop:1 rgba(255, 255, 255, 255));\n"
            "border : 1px solid;\n"
            "border-color: rgb(170, 0, 255);"
        )
        self.pushButton_2.setObjectName("pushButton_2")

        self.textEdit = QtWidgets.QPlainTextEdit(self.centralwidget)
        self.textEdit.setGeometry(QtCore.QRect(0, 500, 651, 211))
        self.textEdit.setObjectName("textEdit")
        technaui2.setCentralWidget(self.centralwidget)
        self.textEdit.setStyleSheet(
            'font: 12pt "Modern No. 10";\n'
            "background-color: rgb(0, 0, 0);\n"
            "color: rgb(255, 255, 255);\n"
            "padding-left: 30px;\n"
        )

        self.btn1 = QtWidgets.QPushButton(self.centralwidget)
        self.btn1.setGeometry(QtCore.QRect(675, 900, 111, 51))
        self.btn1.setStyleSheet(
            'font: 16pt "Modern No. 20";\n'
            "background-color: rgb(0, 0, 0);\n"
            "color: rgb(255, 255, 255);\n"
            "color: qlineargradient(spread:pad, x1:0, y1:0, x2:1, y2:0, stop:0 rgba(0, 61, 162, 255), stop:1 rgba(255, 255, 255, 255));\n"
            "border : 1px solid;\n"
            "border-color: rgb(170, 85, 255);"
        )
        self.btn1.setObjectName("Input")
        self.btn1.resize(140, 70)

        self.label.resize(1006, 800)
        self.gif.resize(700, 500)
        self.pushButton.resize(140, 70)
        self.pushButton_2.resize(140, 70)
        self.textEdit.resize(1000, 300)

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

    def retranslateUi(self, technaui2):
        _translate = QtCore.QCoreApplication.translate
        technaui2.setWindowTitle(_translate("technaui2", "TECHnA"))
        technaui2.setWindowIcon(
            QtGui.QIcon(
                "C:\\Users\\Hp\\Desktop\\SP\\techna2\\gui\\images\\Difference-between-AI-and-Neural-Network-768x614.jpg"
            )
        )
        self.pushButton.setText(_translate("technaui2", "START"))
        self.pushButton_2.setText(_translate("technaui2", "STOP"))
        self.btn1.setText(_translate("technaui2", "INPUT"))


if __name__ == "__main__":
    import sys

    app = QtWidgets.QApplication(sys.argv)
    technaui2 = QtWidgets.QMainWindow()
    ui = Ui_technaui2()
    ui.setupUi(technaui2)
    technaui2.show()
    sys.exit(app.exec_())

The program I am running in QPlainTextEdit and need input for:

techna2.py

    import random
    import json
    import torch
    from brain import NeuralNet  # myfile
    from neuralnetwork import bag_of_words, tokenize  # myfile
    import datetime
    import os
    
    
    device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
    with open("C:\\Users\\Hp\\Desktop\\SP\\techna2\\intents.json", "r") as json_data:
        intents = json.load(json_data)
    
    FILE = "C:\\Users\\Hp\\Desktop\\SP\\techna2\\TrainData.pth"
    data = torch.load(FILE)
    
    input_size = data["input_size"]
    hidden_size = data["hidden_size"]
    output_size = data["output_size"]
    all_words = data["all_words"]
    tags = data["tags"]
    model_state = data["model_state"]
    
    model = NeuralNet(input_size, hidden_size, output_size).to(device)
    model.load_state_dict(model_state)
    model.eval()
    
    
    Name = "Techna"
    from wish import wishMe
    
    from listen import *  # my files
    from speak import Say
    from task import (
        NonInputExecution,
        InputExecution,
        Game,
        Calculations,
        Bye,
        Email,
        Open,
        Close,
        Video,
        Youtube,
        Sound,
        Whatsapp,
        screenShot,
        Joke,
        shutDown,
        Weather,
        Location,
        How,
        News,
        Covid,
        Reader,
        Notepad,
        Alarm,
    )
    
    
    def Main():
        sentence = Listen()
        result = str(sentence)
    
    
        sentence = tokenize(sentence)
        X = bag_of_words(sentence, all_words)
        X = X.reshape(1, X.shape[0])
        X = torch.from_numpy(X).to(device)
    
        output = model(X)
    
        _, predicted = torch.max(output, dim=1)
    
        tag = tags[predicted.item()]
    
        probs = torch.softmax(output, dim=1)
        prob = probs[0][predicted.item()]
    
        if prob.item() > 0.75:
            for intent in intents["intents"]:
                if tag == intent["tag"]:
                    reply = random.choice(intent["responses"])
    
                    if "time" in reply:
                        NonInputExecution(reply)
    
                    elif "alarm" in reply:
                        Say("For what time?")
                        time = input()  #Example, Whenever input is needed I want to provide it through the QInputDialog (or another way of providing the input is also welcomed)
                        Alarm(time)
    
                    else:
                        Say(reply)
1

There are 1 best solutions below

1
On

From what i understand, you want to take the input from user, then pass that input into function 'normalOutputWritten'. Here is my solution:

class GuiStart(QMainWindow):
    textWritten = QtCore.pyqtSignal(str) # Text written should be put here.

    def __init__(self):
        super().__init__()

        self.technaui2 = Ui_technaui2()
        self.technaui2.setupUi(self)
        self.technaui2.pushButton.clicked.connect(self.startFunc)
        self.technaui2.pushButton_2.clicked.connect(self.close)
        self.technaui2.btn1.clicked.connect(self.userInput2)
        self.textWritten.connect(self.normalOutputWritten)  # Add this to use the input value
        sys.stdout = EmittingStream(
            textWritten=self.normalOutputWritten)  # You might not need this line and also this class EmittingStream

    ...

    def userInput2(self):
        text, ok = QtWidgets.QInputDialog.getText(self, "Introduce value", "Value:")
        if ok:
            self.textWritten.emit(str(text)) #Send the input.
        else:
            print("Invalid")
            self.textWritten.emit("") #Send the input.