Search code examples
pythonfunctionpyqt5return

How can I return my session variable to my main code with PyQt5?


I don't know how to express my problem in a question because I am a very PyQt5 learner and I don't know the vocabularies, but come on.

I need to return the session_user variable (in the login () function) to my main code. This variable needs to be passed to the main screen after the login is completed, but I don't know of a function in PyQt5 that returns a variable that is not of type int like: accept (), reject (), done ().

Is it possible to return my session_user variable to my main code with some PyQt5 function like the ones I mentioned?

my code:

from PyQt5 import uic, QtWidgets
from PyQt5.QtWidgets import QDialog
from views.ui.login.telaLogin import Ui_Dialog
import sys
from control.exception_login import verification_login_user

class ViewLogin(QDialog):
    def __init__(self):
        super().__init__()
        self.viewlogin = Ui_Dialog()
        self.viewlogin.setupUi(self)

        self.viewlogin.button_login.clicked.connect(self.login)

    def login(self):

        self.login = self.viewlogin.login_login.text() 
        self.password = self.viewlogin.login_password.text()

        erro =  verification_login_user(self.login, self.password)
    
        if (erro == False):
            self.close()
            session_user = (self.login, self.senha) 
            #self.done(r) # I understand its functionality # PROBLEM
            #return (session_user) # PROBLEM
            self.accept() # The problem would end here if I didn't need the variable sessao_user
             
        elif(erro == True):
            self.viewlogin.login_login.setText('')
            self.viewlogin.login_password.setText('')
            

app = QtWidgets.QApplication([])

w = ViewLogin()
result = w.exec_()

print(result)  # desired result = (' login', 'password') 
# real result = 1 

sys.exit(app.exec_())

Solution

  • One of the approaches you could implement is via threading module.

    1. Create a class Controller and Daemon to True (this ensures the thread will be killed after the app closes).
    class Controller(threading.Thread):
    
        def __init__(self):
            super(Controller, self).__init__(daemon = True)
    
            self.my_variable = 0
            self.variables_from_gui = None
    
    1. Overwrite the run method:
        def run(self):
            print("My main loop is here!")
    
            while True: 
                print("Button presses: {}, Variables from gui: {}".format(self.button_presses, self.variables_from_gui))
                time.sleep(1) #This wont freeze the gui
    
    1. Add a function that will register the button login click:
        def login(self, variables_from_gui = None):
            #Do you login stuff
            self.variables_from_gui = variables_from_gui
            self.button_presses += 1
    
    1. In the App class (in your case that would be the main GUI class) from the login function start a new thread and pass variables to it.
    def login(self):
        #Stuff to do in your GUI
        variables_to_send = 0, "Text", {"key" : 10}
    
        threading.Thread(target = lambda: self.controller.login(variables_from_gui = variables_to_send)).start()
    
    1. Also in your GUI class create a Controller object and start it:
            self.controller = Controller()
            self.controller.start() #Start the run method in the Controller()
    

    There are plenty of things that can be done better and make it more Threading safe. But that is outside of this question topic.


    Whole code:

    import sys
    from PyQt5.QtWidgets import QApplication, QWidget, QPushButton
    from PyQt5.QtGui import QIcon
    from PyQt5.QtCore import pyqtSlot
    
    import threading
    import time
    
    class App(QWidget):
    
        def __init__(self):
            super().__init__()
            self.left = 10
            self.top = 10
            self.width = 320
            self.height = 200
            self.initUI()
        
        def initUI(self):
            self.controller = Controller()
            self.controller.start() #Start the run method in the Controller()
    
            self.setGeometry(self.left, self.top, self.width, self.height)
            
            button = QPushButton("My login", self)
            button.move(100,70)
            button.clicked.connect(self.login)
            
            self.show()
    
        def login(self):
            #Stuff to do in your GUI
            variables_to_send = 0, "Text", {"key" : 10}
    
            threading.Thread(target = lambda: self.controller.login(variables_from_gui = variables_to_send)).start()
    
    class Controller(threading.Thread):
    
        def __init__(self):
            super(Controller, self).__init__(daemon = True)
    
            self.button_presses = 0
            self.variables_from_gui = None
    
        def run(self):
            print("My main loop is here!")
    
            while True: 
                print("Button presses: {}, Variables from gui: {}".format(self.button_presses, self.variables_from_gui))
                time.sleep(1) #This wont freeze the gui
    
        def login(self, variables_from_gui = None):
            #Do you login stuff
            self.variables_from_gui = variables_from_gui
            self.button_presses += 1
    
    
    if __name__ == '__main__':
        app = QApplication(sys.argv)
        ex = App()
        sys.exit(app.exec_())