Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. Qt for Python
  4. How to get the returned value?
Forum Updated to NodeBB v4.3 + New Features

How to get the returned value?

Scheduled Pinned Locked Moved Solved Qt for Python
28 Posts 3 Posters 6.2k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • jsulmJ jsulm

    @_jao_victor_ You want to get value returned by a slot called by a signal? You can't. You should rethink your design. For example login() function could emit a signal in case the login was successful.

    _ Offline
    _ Offline
    _jao_victor_
    wrote on last edited by
    #6

    @jsulm Aren't signals emitted only when a widget is changed?

    jsulmJ 1 Reply Last reply
    0
    • JonBJ JonB

      @_jao_victor_
      So if it's already a QDialog you are already there! You don't need signals/slots. Just result = theDialog.exec(). Read https://doc.qt.io/qt-5/qdialog.html#exec.

      _ Offline
      _ Offline
      _jao_victor_
      wrote on last edited by
      #7

      @JonBSo should it look something like this?

      from control.functionslogin import login
      
      app = QtWidgets.QApplication([])
      
      viewlogin = uic.loadUi('./views/ui/login/viewLogin.ui') 
      mainview =  uic.loadUi('./views/ui/main/mainview.ui')
      
      result = viewlogin.exec()
      viewlogin.button_login.pressed.connect(lambda: login(viewlogin, mainview))
      
      
      viewlogin.show()
      app.exec()
      

      As I understand it, the modal window (QDialog) blocks the interaction with other windows, but how will the window (QDialog) know when to close and send and send the signal?

      JonBJ jsulmJ 2 Replies Last reply
      0
      • _ _jao_victor_

        @jsulm Aren't signals emitted only when a widget is changed?

        jsulmJ Offline
        jsulmJ Offline
        jsulm
        Lifetime Qt Champion
        wrote on last edited by
        #8

        @_jao_victor_ said in How to get the returned value?:

        Aren't signals emitted only when a widget is changed?

        I was talking about your own custom signals. You emit them whenever needed...

        https://forum.qt.io/topic/113070/qt-code-of-conduct

        1 Reply Last reply
        1
        • _ _jao_victor_

          @JonBSo should it look something like this?

          from control.functionslogin import login
          
          app = QtWidgets.QApplication([])
          
          viewlogin = uic.loadUi('./views/ui/login/viewLogin.ui') 
          mainview =  uic.loadUi('./views/ui/main/mainview.ui')
          
          result = viewlogin.exec()
          viewlogin.button_login.pressed.connect(lambda: login(viewlogin, mainview))
          
          
          viewlogin.show()
          app.exec()
          

          As I understand it, the modal window (QDialog) blocks the interaction with other windows, but how will the window (QDialog) know when to close and send and send the signal?

          JonBJ Offline
          JonBJ Offline
          JonB
          wrote on last edited by JonB
          #9

          @_jao_victor_
          No. Like I said, no signals/slots/connects. No show. Just:

          result = viewlogin.exec()    # Like I said, read https://doc.qt.io/qt-5/qdialog.html#exec
          if not result:    # e.g. user clicked `Cancel`
              sys.exit(1)
          login = viewlogin.login_login.text()
          password = viewlogin.login_password.text()
          
          mainview.show()
          sys.exit(app.exec())
          

          Get that working first. Then think about what you want to do if the user presses Cancel, or if the name+password is incorrect. (Hint: you might move the credential validation code into viewlogin when user presses OK, and give an error message and keep him in there till he gets it right or Cancels. There are various possible strategies.) The point initially is to get the dialog working.

          _ 2 Replies Last reply
          3
          • _ _jao_victor_

            @JonBSo should it look something like this?

            from control.functionslogin import login
            
            app = QtWidgets.QApplication([])
            
            viewlogin = uic.loadUi('./views/ui/login/viewLogin.ui') 
            mainview =  uic.loadUi('./views/ui/main/mainview.ui')
            
            result = viewlogin.exec()
            viewlogin.button_login.pressed.connect(lambda: login(viewlogin, mainview))
            
            
            viewlogin.show()
            app.exec()
            

            As I understand it, the modal window (QDialog) blocks the interaction with other windows, but how will the window (QDialog) know when to close and send and send the signal?

            jsulmJ Offline
            jsulmJ Offline
            jsulm
            Lifetime Qt Champion
            wrote on last edited by
            #10

            @_jao_victor_ said in How to get the returned value?:

            know when to close and send and send the signal?

            It knows that when the user closes the dialog. And if you go for @JonB suggestion there is no need for any signals. Simply check what https://doc.qt.io/qt-5/qdialog.html#exec returns (hint: https://doc.qt.io/qt-5/qdialog.html#DialogCode-enum).

            https://forum.qt.io/topic/113070/qt-code-of-conduct

            1 Reply Last reply
            3
            • JonBJ JonB

              @_jao_victor_
              So if it's already a QDialog you are already there! You don't need signals/slots. Just result = theDialog.exec(). Read https://doc.qt.io/qt-5/qdialog.html#exec.

              _ Offline
              _ Offline
              _jao_victor_
              wrote on last edited by
              #11

              @JonB I think my problem is much more due to the design, as @jsulm said. I searched the internet for several tutorials but I couldn't find one that would suit me completely, because at most, they only taught how to create two windows and my system has more than two (1 QMainWindow and 4 QDialog). My login QDialog calls my QMainWindow main and it can call another 3 QDialog.

              My problem is that I can't pass the specific variable (session_user) that needs to be passed to the mainview screen and then passed to the other 3 QDialog that can be opened.

              I managed to make the variable go to mainview (I think in an unviable way) but I couldn't pass it on to the 3 QDIalog.

              Do you know any system that I can get the design?

              jsulmJ JonBJ 2 Replies Last reply
              0
              • _ _jao_victor_

                @JonB I think my problem is much more due to the design, as @jsulm said. I searched the internet for several tutorials but I couldn't find one that would suit me completely, because at most, they only taught how to create two windows and my system has more than two (1 QMainWindow and 4 QDialog). My login QDialog calls my QMainWindow main and it can call another 3 QDialog.

                My problem is that I can't pass the specific variable (session_user) that needs to be passed to the mainview screen and then passed to the other 3 QDialog that can be opened.

                I managed to make the variable go to mainview (I think in an unviable way) but I couldn't pass it on to the 3 QDIalog.

                Do you know any system that I can get the design?

                jsulmJ Offline
                jsulmJ Offline
                jsulm
                Lifetime Qt Champion
                wrote on last edited by
                #12

                @_jao_victor_ said in How to get the returned value?:

                but I couldn't pass it on to the 3 QDIalog

                Why not? What stops you from subclassing QDialog and pass that data to the constructor or implement a setter method?

                https://forum.qt.io/topic/113070/qt-code-of-conduct

                1 Reply Last reply
                2
                • _ _jao_victor_

                  @JonB I think my problem is much more due to the design, as @jsulm said. I searched the internet for several tutorials but I couldn't find one that would suit me completely, because at most, they only taught how to create two windows and my system has more than two (1 QMainWindow and 4 QDialog). My login QDialog calls my QMainWindow main and it can call another 3 QDialog.

                  My problem is that I can't pass the specific variable (session_user) that needs to be passed to the mainview screen and then passed to the other 3 QDialog that can be opened.

                  I managed to make the variable go to mainview (I think in an unviable way) but I couldn't pass it on to the 3 QDIalog.

                  Do you know any system that I can get the design?

                  JonBJ Offline
                  JonBJ Offline
                  JonB
                  wrote on last edited by JonB
                  #13

                  @_jao_victor_ said in How to get the returned value?:

                  My login QDialog calls my QMainWindow

                  Never do this. Use a pattern such as I showed. Nothing should "call" your main window, nor anything in it, other than the Python main program. The main window may "call" dialogs, or access things within them if required, and dialogs may call other dialogs. But keep thing "uni-directional": widgets which open other widgets may pass/access/receive things to/from the sub-widget, but do not make it so the sub-widget accesses or even knows anything about the calling/parent widget.

                  Follow either of @jsulm's suggestions for passing variables around.

                  _ 1 Reply Last reply
                  3
                  • JonBJ JonB

                    @_jao_victor_ said in How to get the returned value?:

                    My login QDialog calls my QMainWindow

                    Never do this. Use a pattern such as I showed. Nothing should "call" your main window, nor anything in it, other than the Python main program. The main window may "call" dialogs, or access things within them if required, and dialogs may call other dialogs. But keep thing "uni-directional": widgets which open other widgets may pass/access/receive things to/from the sub-widget, but do not make it so the sub-widget accesses or even knows anything about the calling/parent widget.

                    Follow either of @jsulm's suggestions for passing variables around.

                    _ Offline
                    _ Offline
                    _jao_victor_
                    wrote on last edited by
                    #14

                    @JonB I will reformulate my design based on what you and @jsulm showed me and I return feedback here. Thank you, this problem has been chasing me for a long time.

                    1 Reply Last reply
                    0
                    • JonBJ JonB

                      @_jao_victor_
                      No. Like I said, no signals/slots/connects. No show. Just:

                      result = viewlogin.exec()    # Like I said, read https://doc.qt.io/qt-5/qdialog.html#exec
                      if not result:    # e.g. user clicked `Cancel`
                          sys.exit(1)
                      login = viewlogin.login_login.text()
                      password = viewlogin.login_password.text()
                      
                      mainview.show()
                      sys.exit(app.exec())
                      

                      Get that working first. Then think about what you want to do if the user presses Cancel, or if the name+password is incorrect. (Hint: you might move the credential validation code into viewlogin when user presses OK, and give an error message and keep him in there till he gets it right or Cancels. There are various possible strategies.) The point initially is to get the dialog working.

                      _ Offline
                      _ Offline
                      _jao_victor_
                      wrote on last edited by _jao_victor_
                      #15

                      Hello I'm back. Okay, but, how am I going to do so that when the user presses the login button, a verification function is called and returns True (1) to main.py if the login and password are correct, how am I going to do this if I can't use slots or signals?

                      jsulmJ 1 Reply Last reply
                      0
                      • JonBJ JonB

                        @_jao_victor_
                        No. Like I said, no signals/slots/connects. No show. Just:

                        result = viewlogin.exec()    # Like I said, read https://doc.qt.io/qt-5/qdialog.html#exec
                        if not result:    # e.g. user clicked `Cancel`
                            sys.exit(1)
                        login = viewlogin.login_login.text()
                        password = viewlogin.login_password.text()
                        
                        mainview.show()
                        sys.exit(app.exec())
                        

                        Get that working first. Then think about what you want to do if the user presses Cancel, or if the name+password is incorrect. (Hint: you might move the credential validation code into viewlogin when user presses OK, and give an error message and keep him in there till he gets it right or Cancels. There are various possible strategies.) The point initially is to get the dialog working.

                        _ Offline
                        _ Offline
                        _jao_victor_
                        wrote on last edited by
                        #16

                        @JonB exec () returns me 0 when I close the window, but how do I return zero when the password and login are not right, for example. I have no control over this returned value.

                        JonBJ 1 Reply Last reply
                        0
                        • _ _jao_victor_

                          Hello I'm back. Okay, but, how am I going to do so that when the user presses the login button, a verification function is called and returns True (1) to main.py if the login and password are correct, how am I going to do this if I can't use slots or signals?

                          jsulmJ Offline
                          jsulmJ Offline
                          jsulm
                          Lifetime Qt Champion
                          wrote on last edited by
                          #17

                          @_jao_victor_ said in How to get the returned value?:

                          but, how am I going to do so that when the user presses the login button, a verification function is called

                          @JonB already shown you how to do this, even with code.
                          Just add additional method to your dialog which returns that information (like loginValid() in this example):

                          result = viewlogin.exec()    # Like I said, read https://doc.qt.io/qt-5/qdialog.html#exec
                          if not result or not viewlogin.loginValid():
                              sys.exit(1)
                          

                          https://forum.qt.io/topic/113070/qt-code-of-conduct

                          1 Reply Last reply
                          2
                          • _ _jao_victor_

                            @JonB exec () returns me 0 when I close the window, but how do I return zero when the password and login are not right, for example. I have no control over this returned value.

                            JonBJ Offline
                            JonBJ Offline
                            JonB
                            wrote on last edited by JonB
                            #18

                            @_jao_victor_ said in How to get the returned value?:

                            I have no control over this returned value.

                            Oh, but you do :)

                            @jsulm suggests you do:

                            result = viewlogin.exec()    # Like I said, read https://doc.qt.io/qt-5/qdialog.html#exec
                            if not result or not viewlogin.loginValid():
                                sys.exit(1)
                            

                            This is fine, and I suggest you actually do that to start with as it's simple and you should get that working initially.

                            However, this will mean that if the user types the wrong credentials and clicks OK you will exit your program; or at best you might create a loop which perhaps gives an error message and shows the logon dialog again. I suggested a hint:

                            (Hint: you might move the credential validation code into viewlogin when user presses OK, and give an error message and keep him in there till he gets it right or Cancels. There are various possible strategies.)

                            It might be nicer if the viewlogin dialog checks the credentials before exiting back to the caller, and keeps the user in the dialog until either he types correct credentials and OK or he gives up and clicks Cancel, at which point it's fair enough to exit the program.

                            For that we will override the virtual void QDialog::accept() in your derived QDialog subclass. [Note: I don't know whether we can do that with your uic.loadUi(). I would suggest you change over to using pyuic at compilation stage to generate compile-time subclasses for your design stuff, instead of loading it dynamically at runtime. Read https://doc.qt.io/qtforpython/tutorials/basictutorial/uifiles.html and follow Option A: Generating a Python class.] Normally clicking OK just calls QDialog::accept(), which exits the dialog and returns non-zero to the caller of QDialog::exec(). You might replace with something like:

                            /*virtual*/ void ViewDialog::accept() override
                            {
                                if (!loginValid())
                                {
                                    MessageBox("Bad credentials, try again");
                                    return;
                                }
                                QDialog::accept();
                            }
                            

                            Now so far as the caller of viewLogon::exec() is concerned, it either receives false if the user clicked Cancel, in which case you can exit, or true iff the user clicked OK and the credentials were correct.

                            1 Reply Last reply
                            1
                            • _ Offline
                              _ Offline
                              _jao_victor_
                              wrote on last edited by _jao_victor_
                              #19

                              Ok @jsulm and @JonB, so far I understood correctly, I did the tests and got the expected result, however, what if the buttons are not the ones from QDialog, but one that I implemented myself? The Cancel and OK buttons send the signals automatically when they are pressed, so how do I make my buttons (login and register) send their signals when they are pressed?

                              esseaquivai.pnga

                              JonBJ 1 Reply Last reply
                              0
                              • _ _jao_victor_

                                Ok @jsulm and @JonB, so far I understood correctly, I did the tests and got the expected result, however, what if the buttons are not the ones from QDialog, but one that I implemented myself? The Cancel and OK buttons send the signals automatically when they are pressed, so how do I make my buttons (login and register) send their signals when they are pressed?

                                esseaquivai.pnga

                                JonBJ Offline
                                JonBJ Offline
                                JonB
                                wrote on last edited by
                                #20

                                @_jao_victor_
                                Looks OK. Sorry, is there a question here?

                                _ 1 Reply Last reply
                                0
                                • JonBJ JonB

                                  @_jao_victor_
                                  Looks OK. Sorry, is there a question here?

                                  _ Offline
                                  _ Offline
                                  _jao_victor_
                                  wrote on last edited by
                                  #21

                                  @JonB yes i rewrote the text to explain it better, sorry.

                                  JonBJ 1 Reply Last reply
                                  0
                                  • _ _jao_victor_

                                    @JonB yes i rewrote the text to explain it better, sorry.

                                    JonBJ Offline
                                    JonBJ Offline
                                    JonB
                                    wrote on last edited by JonB
                                    #22

                                    @_jao_victor_

                                    connect(loginButton, &QPushButton::clicked, accept);
                                    connect(cancelButton, &QPushButton::clicked, reject);
                                    

                                    You'll have to think a bit more carefully about the Register button. It does not do the same thing as the Login button, i.e. it does/should not cause the dialog to exit with "success" back to the main program for the user to continue into the main window.

                                    That's for you to figure out what you want to do.

                                    QDialog does not have to exit with only accept() or reject(). They use void QDialog::done(int r), and you can do the same with as many different r values as you please. That value is the return result when you go int result = dialog.exec().

                                    _ 1 Reply Last reply
                                    2
                                    • JonBJ JonB

                                      @_jao_victor_

                                      connect(loginButton, &QPushButton::clicked, accept);
                                      connect(cancelButton, &QPushButton::clicked, reject);
                                      

                                      You'll have to think a bit more carefully about the Register button. It does not do the same thing as the Login button, i.e. it does/should not cause the dialog to exit with "success" back to the main program for the user to continue into the main window.

                                      That's for you to figure out what you want to do.

                                      QDialog does not have to exit with only accept() or reject(). They use void QDialog::done(int r), and you can do the same with as many different r values as you please. That value is the return result when you go int result = dialog.exec().

                                      _ Offline
                                      _ Offline
                                      _jao_victor_
                                      wrote on last edited by _jao_victor_
                                      #23

                                      @JonB I think I'm almost there :). I've been researching more and seeing the differences between
                                      Build Time and Runtime and more, The single inheritance approach and The multiple inheritance approach however, as I am still a beginner I was a bit in doubt in which my app fits, I think in Compilation time and multiple inheritance, right?

                                      This is my current 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()
                                                  sessao_user = (self.login, self.senha) 
                                                  #self.done(r) # I understand its functionality # PROBLEM
                                                  #return (sessao_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_())
                                      

                                      But unfortunately I saw that done () only takes numbers as a parameter and does not allow another type, and the return doesn't work here either, so I still don't have the sessao_user variable in main.py because I need to pass it to the main window.

                                      JonBJ 1 Reply Last reply
                                      0
                                      • _ _jao_victor_

                                        @JonB I think I'm almost there :). I've been researching more and seeing the differences between
                                        Build Time and Runtime and more, The single inheritance approach and The multiple inheritance approach however, as I am still a beginner I was a bit in doubt in which my app fits, I think in Compilation time and multiple inheritance, right?

                                        This is my current 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()
                                                    sessao_user = (self.login, self.senha) 
                                                    #self.done(r) # I understand its functionality # PROBLEM
                                                    #return (sessao_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_())
                                        

                                        But unfortunately I saw that done () only takes numbers as a parameter and does not allow another type, and the return doesn't work here either, so I still don't have the sessao_user variable in main.py because I need to pass it to the main window.

                                        JonBJ Offline
                                        JonBJ Offline
                                        JonB
                                        wrote on last edited by
                                        #24

                                        @_jao_victor_
                                        Indeed the accept/reject/done() only tell the caller what button the user to exit the modal dialog. That is all you actually return from it. But there is nothing to stop the caller still querying what is in the dialog's widgets:

                                        result = viewlogin.exec()
                                        if not result:
                                            sys.exit(1)
                                        username = viewlogin.login_login.text()
                                        

                                        If you want to do it via your sessao_user you will have to use Python's global to access that. Or, you could wrap it up with some method from the dialog:

                                        class ViewLogin(QDialog):
                                            def sessao_user(self):
                                                return (self.login, self.senha)
                                        
                                        result = viewlogin.exec()
                                        if not result:
                                            sys.exit(1)
                                        sessao_user = viewlogin.sessao_user()
                                        

                                        In your def login() do not do self.close(). self.accept/reject/done() close the dialog.

                                        _ 1 Reply Last reply
                                        0
                                        • JonBJ JonB

                                          @_jao_victor_
                                          Indeed the accept/reject/done() only tell the caller what button the user to exit the modal dialog. That is all you actually return from it. But there is nothing to stop the caller still querying what is in the dialog's widgets:

                                          result = viewlogin.exec()
                                          if not result:
                                              sys.exit(1)
                                          username = viewlogin.login_login.text()
                                          

                                          If you want to do it via your sessao_user you will have to use Python's global to access that. Or, you could wrap it up with some method from the dialog:

                                          class ViewLogin(QDialog):
                                              def sessao_user(self):
                                                  return (self.login, self.senha)
                                          
                                          result = viewlogin.exec()
                                          if not result:
                                              sys.exit(1)
                                          sessao_user = viewlogin.sessao_user()
                                          

                                          In your def login() do not do self.close(). self.accept/reject/done() close the dialog.

                                          _ Offline
                                          _ Offline
                                          _jao_victor_
                                          wrote on last edited by
                                          #25

                                          @JonB Fiddled, thank you. And thanks to @jsulm too. But clarify one last question, as the documentation is in C ++, I didn't understand it very well, but is my app running time? Do you use the multiple or single inheritance approach?

                                          JonBJ 1 Reply Last reply
                                          0

                                          • Login

                                          • Login or register to search.
                                          • First post
                                            Last post
                                          0
                                          • Categories
                                          • Recent
                                          • Tags
                                          • Popular
                                          • Users
                                          • Groups
                                          • Search
                                          • Get Qt Extensions
                                          • Unsolved