简体   繁体   English

PyQt5 登录注册对话框自动关闭

[英]PyQt5 Login to Register Dialog Auto Close

I have a login and register dialog, and of course a main window.我有一个登录和注册对话框,当然还有一个主要的 window。 So, I want the users to be able to switch between login and register dialog, and if the user enters correct credentials, the user can go to the main window.所以,我希望用户能够在登录和注册对话框之间切换,如果用户输入正确的凭据,用户可以 go 到主 window。 If the user registered a new credential, then the user will be redirected to the login window.如果用户注册了新的凭证,那么用户将被重定向到登录 window。 That said, the first interface that the user see is the login dialog.也就是说,用户看到的第一个界面是登录对话框。 Here are some codes for login-register dialog:以下是登录注册对话框的一些代码:

class Login(QDialog):
    # Push Button -> Login
    # Push Button 2 -> To Register
    # Push Button 3 -> Exit
    def __init__(self):
        super(Login, self).__init__()
        # Load Login UI
        loadUi("Login.ui", self)
        # Set Translucent Background for the Windows
        self.setWindowFlags(PyQt5.QtCore.Qt.FramelessWindowHint)
        self.setAttribute(PyQt5.QtCore.Qt.WA_TranslucentBackground)
        # Set Push Button 1 to call the function upon clicked
        self.pushButton.clicked.connect(self.check_login)
        # Set Push Button 2 to call the function upon clicked
        self.pushButton_2.clicked.connect(self.redirect_to_register)
        # Set Push Button 3 to call the function upon clicked
        self.pushButton_3.clicked.connect(self.close_window)
        # Show the Window
        self.show()

    # Procedure to redirect to register windows
    def redirect_to_register(self):
        self.close()  # Close the login windows
        # Show the register windows
        self.register = Register()
        self.register.show()
...

class Register(QDialog):
    # Push Button -> Register
    # Push Button 2 -> To Login
    # Push Button 3 -> Exit
    def __init__(self):
        # Load Register UI
        super(Register, self).__init__()
        loadUi("Register.ui", self)
        # Set Translucent Background for the Windows
        self.setWindowFlags(PyQt5.QtCore.Qt.FramelessWindowHint)
        self.setAttribute(PyQt5.QtCore.Qt.WA_TranslucentBackground)
        # Set Push Button 2 to call the function upon clicked
        self.pushButton.clicked.connect(self.insert_to_database)
        # Set Push Button 2 to call the function upon clicked
        self.pushButton_2.clicked.connect(self.redirect_to_login)
        # Set Push Button 3 to call the function upon clicked
        self.pushButton_3.clicked.connect(self.close_window)
        # Show the Window
        self.show()

    # Procedure to redirect to login windows
    def redirect_to_login(self):
        # Close the login windows
        self.close()
        # Show the register windows
        self.login = Login()
        self.login.show()

    def close_window(self):
        self.close()

I load the.ui file of both dialog.我加载了两个对话框的 .ui 文件。 But, for the main window, the.py file is converted from the.ui file.但是,对于主 window,.py 文件是从 .ui 文件转换而来的。 That said, in the main of the login file, I call the main window with this code:也就是说,在登录文件的主文件中,我使用以下代码调用主文件 window:

import GoodLife
# Call main
if __name__ == "__main__":
    # Init App
    app = QApplication(sys.argv)
    QtGui.QFontDatabase.addApplicationFont("../img/dripicons-v2.ttf")
    # Build the window
    window = Login()
    if(window.exec_() == QDialog.Accepted):
        GoodLife = QMainWindow()
        ui = Ui_MainWindow()
        ui.setupUi(GoodLife)
        GoodLife.setWindowTitle("Good Life - Your Dear Bestfriend :)")
        GoodLife.setWindowIcon(QtGui.QIcon('../img/goodlife.jpg'))
        GoodLife.show()
        sys.exit(app.exec_())

With that code, I am able to go into the main window after logging in. But, whenever I tried to switch to register dialog, the register dialog keeps auto-closing.使用该代码,我可以在登录后将 go 进入主 window。但是,每当我尝试切换到注册对话框时,注册对话框都会自动关闭。 I believe that the line sys.exit(app.exec_()) is the cause of it, because when I unindent the line once, I can go to the register, but not the main window.我相信这行sys.exit(app.exec_())是它的原因,因为当我取消缩进一次时,我可以 go 到寄存器,但不是主要的 window。 Can anyone help me on this?谁可以帮我这个事?

The problem is that when a dialog is closed, it exits its event loop (the one launched with exec ) with a Rejected result.问题是,当一个对话框关闭时,它会退出它的事件循环(使用exec启动的那个)并返回一个Rejected结果。

In your case, since the rejection doesn't match window.exec_() == QDialog.Accepted , the result is that that whole block is not evaluated, and the application simply exits.在您的情况下,由于拒绝与window.exec_() == QDialog.Accepted不匹配,因此结果是未评估整个块,并且应用程序简单地退出。

A simple solution would be to hide the login until the registration is completed (or rejected) and show it again afterwards.一个简单的解决方案是在注册完成(或被拒绝)之前隐藏登录,然后再次显示。

Since the login dialog should be shown anyway, there's no need for custom signals or if statements, as it's enough to call the registration dialog's exec_ in the redirect_to_register function, so that you can show again the login no matter the result of the registration.由于无论如何都应该显示登录对话框,因此不需要自定义信号或 if 语句,因为在redirect_to_register function 中调用注册对话框的 exec_ 就足够了,这样无论注册结果如何,您都可以再次显示登录。

Unfortunately, there's a problem with that: in Qt, hiding a dialog results in a behavior similar to closing it (so, rejecting).不幸的是,有一个问题:在 Qt 中,隐藏对话框会导致类似于关闭它的行为(因此,拒绝)。
The solution is to avoid the base implementation of QDialog (which overrides both hide() and setVisible() ), and use that of QWidget instead:解决方案是避免 QDialog 的基本实现(覆盖hide()setVisible() ),而使用 QWidget 的基本实现:

   def redirect_to_register(self):
        QtWidgets.QWidget.setVisible(self, False)
        self.register = Register()
        self.register.exec_()
        self.show()

This also means that in the register dialog you should not try to recreate the login window:这也意味着在注册对话框中您不应尝试重新创建登录 window:

class Register(QDialog):
    def __init__(self):
        # ...
        self.pushButton_2.clicked.connect(self.accept)

Some unasked suggestions:一些未提出的建议:

  • in the last code you're importing "GoodLife", then not only you're not using it, but you're also overwriting it as a variable ;在您导入“GoodLife”的最后一个代码中,您不仅没有使用它,而且还将它作为变量覆盖; you probably did some copy/paste/edit error, but the point is that names that begin with uppercase letters should only be used for classes and constants, not for variables;你可能犯了一些复制/粘贴/编辑错误,但重点是以大写字母开头的名称只能用于类和常量,而不是变量;
  • there's no need to implement a close_window function if it just calls self.close() : just connect signals to self.close ;如果只调用self.close() ,则无需实现close_window function :只需将信号连接到self.close
  • be more verbose with object names, including widgets you create in Designer: having lots of pushButton_x is never a good idea, as you cannot easily distinguish their role;更详细地使用 object 名称,包括您在 Designer 中创建的小部件:拥有大量pushButton_x绝不是一个好主意,因为您无法轻松区分它们的角色;
  • commenting should be limited to sections in which it's not immediate what the code does;注释应仅限于代码不立即执行的部分; comments like "Set Push Button 2 to call the function upon clicked" or "Show the window" are completely useless and distracting as they don't add any information;诸如“设置按钮 2 以在单击时调用 function”或“显示窗口”之类的评论完全无用且令人分心,因为它们没有添加任何信息;
  • window title and icons can be set in Designer; window 标题和图标可以在Designer中设置;
  • be careful with relative paths, especially for parent ( ../ ) folders;小心相对路径,特别是对于父( ../ )文件夹; consider using Qt resource systems (which also allows you to set icons and images directly in Designer);考虑使用 Qt 资源系统(也允许您直接在 Designer 中设置图标和图像);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM