Solved How to get the returned value?
-
How can I get the True value returned by login () ?
from control.functionslogin import login app = QtWidgets.QApplication([]) viewlogin = uic.loadUi('./views/ui/login/viewLogin.ui') mainview = uic.loadUi('./views/ui/main/mainview.ui') login = viewlogin.button_login.pressed.connect(lambda: login(viewlogin, mainview)) viewlogin.show() app.exec()
def login(viewlogin,mainview): login = viewlogin.login_login.text() password = viewlogin.login_password.text() erro = verification_login_user(login, password) if (erro == False): viewlogin.close() session_user = (login,password) return True elif(erro == True): viewlogin.login_login.setText('') viewlogin.login_password.setText('')
Because every time I run the code this error is returned:
login = view.button_login.pressed.connect(lambda: login(viewlogin, mainsview)) TypeError: 'Connection' object is not callable
-
@_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_ 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.
-
@_jao_victor_
As @jsulm says, slots cannot return any value. A lot of people implement your "login" as a modalQDialog
, no signals/slots, which can return a result like true/false to caller. -
@JonBBut my login screen is a QDialog.
-
@_jao_victor_
So if it's already aQDialog
you are already there! You don't need signals/slots. Justresult = theDialog.exec()
. Read https://doc.qt.io/qt-5/qdialog.html#exec. -
@jsulm Aren't signals emitted only when a widget is changed?
-
@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?
-
@_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...
-
@_jao_victor_
No. Like I said, no signals/slots/connect
s. Noshow
. 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. -
@_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).
-
@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?
-
@_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?
-
@_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.
-
-
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?
-
@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.
-
@_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?