Search code examples
pythonpython-2.7pyqtpyqt4

How do I pass extra arguments to PyQt GUI functions?


I am trying to build a simple 1x1 practice tool for my kid with some graphical widgets. As shown in the image below a "New Problem" button generates internally 2 random numbers and displays it in a text field. The user has to provide the result next to =. With the "Check Result", I want a conditional instruction that makes:

  1. if result is correct print "Correct! Result is ..." and change background color to green.
  2. if result is wrong print "..." and change background color to red

enter image description here

Now, the problem is: I am generating the random numbers in a function that is connected to the "New Problem" button. If I hit "Check Result" those numbers will not be passed to the "check result" button. Without class definition I usually pass values by return, however, here with class self it does not work.

  • Question1: What is the best way to solve this problem ?
  • Question2: I have no clue how to change the color of those text fields.

Any help is greatly appreciated!

The code I have got so far is:

from PyQt4 import QtGui
import sys
import random
import numpy as np
import new_design6  # translated from Qt designer (not relevant for this question)

class ExampleApp(QtGui.QMainWindow,new_design6.Ui_MainWindow):


    def __init__(self):
        super(self.__class__, self).__init__()
        self.setupUi(self)
        self.exit_app.clicked.connect(self.exit_application)
        self.get_new_problem.clicked.connect(self.generate_new_problem)
        self.check_result.clicked.connect(self.check_problem_result)


    def generate_new_problem(self):
        # clear each field 
        self.show_problem.clear()
        self.input_result.clear()
        self.show_result.clear()

        u = int(np.random.randint(0,11,1))
        v = int(np.random.randint(0,11,1))
        w = str(u) + " x " + str(v)

        self.show_problem.setReadOnly(True)
        self.show_problem.setPlainText(w)
        # how to pass my random numbers ?
        return(u,v) #*---> Problem line1* 


    def check_problem_result(self,u,v): #*---> Problem line1* 
        input_result_number=self.input_result.toPlainText()
        result=int(input_result_number)

        # here I'd like to have a conditional question to check if result is correkt or wrong
        if (result == u*v):
            result_string="Correct! Result is:  " + str(result)
            self.show_result.setPlainText(result_string)
        else: 
            result_string="Wrong! Result is:  " + str(result) + "Try another one"


    def exit_application(self):
        self.close()

def main():
    app = QtGui.QApplication(sys.argv)
    form = ExampleApp()
    form.show()
    app.exec_()

if __name__=='__main__':
    main()

Solution

  • An appropriate way would be to create a class that manages operations:

    class Operation:
        def __init__(self):
            self.params = []
    
        def setParams(self, params):
            self.params = params
    
        def process(self):
            # processing
            u, v = self.params
            result = u*v
            return result 
    
        def toString(self):
            return "{}x{}".format(*self.params)
    

    Then an object of that kind is created as an attribute of the widget and the logic is handled, as it is a property that can be accessed in the whole scope of the class.

    To change the color I use the QPalette of the widget as shown in the following code:

    class ExampleApp(QtGui.QMainWindow,new_design6.Ui_MainWindow):
        def __init__(self):
            super(self.__class__, self).__init__()
            self.setupUi(self)
            self.exit_app.clicked.connect(self.close)
            self.get_new_problem.clicked.connect(self.generate_new_problem)
            self.check_result.clicked.connect(self.check_problem_result)
            self.operation = Operation()
            self.show_problem.setReadOnly(True)
    
        def generate_new_problem(self):
            self.show_problem.clear()
            self.input_result.clear()
            self.show_result.clear()
            pal = self.show_result.palette()
            pal.setColor(QtGui.QPalette.Base, QtCore.Qt.white)
            self.show_result.setPalette(pal)
            u = int(np.random.randint(0,11,1))
            v = int(np.random.randint(0,11,1))
            params = u, v
            self.operation.setParams(params)        
            self.show_problem.setPlainText(self.operation.toString())
    
        def check_problem_result(self):
            input_result_number = self.input_result.toPlainText()
            result = int(input_result_number)
            pal = self.show_result.palette()
            if self.operation.process() == result:
                result_string="Correct! Result is:  {}".format(result)
                pal.setColor(QtGui.QPalette.Base, QtCore.Qt.green)
            else: 
                result_string="Wrong! Result is: {} Try another one".format(result)
                pal.setColor(QtGui.QPalette.Base, QtCore.Qt.red)
            self.show_result.setPlainText(result_string)
            self.show_result.setPalette(pal)