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

PyQt5 Login to Register Dialog Auto Close

我有一个登录和注册对话框,当然还有一个主要 window。所以,我希望用户能够在登录和注册对话框之间切换,如果用户输入正确的凭据,用户就可以转到主界面 window。如果用户注册了新的凭据,则用户将被重定向到登录 window。也就是说,用户看到的第一个界面是登录对话框。以下是登录注册对话框的一些代码:

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()

我加载了两个对话框的 .ui 文件。但是,对于主要 window,.py 文件是从 .ui 文件转换而来的。也就是说,在登录文件的主体中,我使用以下代码调用主体 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_())

使用该代码,我可以在登录后进入主 window。但是,每当我尝试切换到注册对话框时,注册对话框都会自动关闭。我相信 sys.exit(app.exec_()) 行是它的原因,因为当我取消缩进一次时,我可以转到寄存器,但不能转到主 window。谁能帮我解决这个问题?

问题是,当对话框关闭时,它会退出其事件循环(使用 exec 启动的那个),结果为 Rejected

在您的情况下,由于拒绝不匹配 window.exec_() == QDialog.Accepted,结果是整个块未被评估,应用程序直接退出。

一个简单的解决方案是 隐藏 登录,直到注册完成(或被拒绝),然后再显示。

既然无论如何都要显示登录对话框,就不需要自定义信号或 if 语句,因为在 redirect_to_register 函数中调用注册对话框的 exec_ 就足够了,这样您就可以再次显示登录不管报名结果如何。

不幸的是,这有一个问题:在 Qt 中,隐藏对话框会导致类似于关闭它的行为(因此,拒绝)。
解决方案是避免 QDialog 的基本实现(它覆盖了 hide()setVisible()),而是使用 QWidget 的实现:

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

这也意味着在注册对话框中您不应该尝试重新创建登录 window:

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

一些未提出的建议:

  • 在你导入“GoodLife”的最后代码中,你不仅没有使用它,而且还把它覆盖为一个变量;您可能犯了一些 copy/paste/edit 错误,但重点是,以大写字母开头的名称只能用于 类 和常量,不能用于变量;
  • 如果只是调用 self.close(),则无需实现 close_window 函数:只需将信号连接到 self.close
  • 使用 object 名称更加冗长,包括您在 Designer 中创建的小部件:拥有大量 pushButton_x 从来都不是一个好主意,因为您无法轻易区分它们的作用;
  • 评论应该仅限于那些不是直接说明代码做什么的部分;诸如“设置按钮 2 以在单击时调用函数”或“显示 window”之类的评论完全无用且令人分心,因为它们不添加任何信息;
  • window标题和图标可以在设计器中设置;
  • 注意相对路径,尤其是 parent (../) 文件夹;考虑使用 Qt 资源系统(它还允许您直接在 Designer 中设置图标和图像);