Solved How to get the returned value?
-
@_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)
-
@_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 derivedQDialog
subclass. [Note: I don't know whether we can do that with youruic.loadUi()
. I would suggest you change over to usingpyuic
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 callsQDialog::accept()
, which exits the dialog and returns non-zero to the caller ofQDialog::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. -
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?
a
-
@_jao_victor_
Looks OK. Sorry, is there a question here? -
@JonB yes i rewrote the text to explain it better, sorry.
-
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 onlyaccept()
orreject()
. They use void QDialog::done(int r), and you can do the same with as many differentr
values as you please. That value is the return result when you goint result = dialog.exec()
. -
@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.
-
@_jao_victor_
Indeed theaccept
/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'sglobal
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 doself.close()
.self.accept
/reject
/done()
close the dialog. -
-
@_jao_victor_ said in How to get the returned value?:
I didn't understand it very well, but is my app running time?
I don't know what this means :)
Do you use the multiple or single inheritance approach?
Neither of these seems to be relevant to what you have been asking about :)
-
@JonB sorry, I don't speak your language, but the question is does my app followBuild Time or Runtime?
-
viewlogin = uic.loadUi('./views/ui/login/viewLogin.ui') mainview = uic.loadUi('./views/ui/main/mainview.ui')
Since you are loading a
.ui
file at runtime you are following the pattern from Run Time Form Processing.