所以我有 2 个窗口我希望能够在Login和MainWindow之间切换,每个窗口分别QWidget
位于自己的单独文件loginUI.py和MainUI.py中。
通过创建 MainWindow 的新实例,我可以在正确的身份验证后轻松地从登录切换到主。但在 MainWindow 中,我想要一个显示登录屏幕的“断开连接”按钮。
由于两者都在不同的文件中,因此在这种情况下导入会在 python 中引发循环导入错误。
我尝试的其他方法是:
使用信号并在中间文件中处理它们。这很好,但是当我添加更多按钮/窗口时,文件开始变得有点混乱。
将 Login 的实例传递给MainWindow.__init__(self, login)
,然后只使用self.login.show()
. 这似乎是一个好方法,但是当我添加越来越多的窗口时,我担心它可能会影响性能,因为很多实例只是在后台运行。
这些是正确的方法还是我错过了更简单的方法
编辑:
login.py
from PyQt5.QtWidgets import QWidget, QPushButton, QLineEdit
from PyQt5.QtCore import QSize
from mainmenu import MainWindow
from PyQt5 import QtWidgets
import sys
class Login(QWidget):
def __init__(self):
QWidget.__init__(self)
self.setMinimumSize(QSize(300, 200))
self.setWindowTitle("Log in")
self.username = QLineEdit(self)
self.username.move(50, 10)
self.password = QLineEdit(self)
self.password.move(50, 40)
self.connect_button = QPushButton('Connect', self)
self.connect_button.move(50, 100)
self.connect_button.clicked.connect(self.handleConnexion)
def handleConnexion(self):
if self.username.text() == "admin" and self.password.text()=="1":
self.mw = MainWindow()
self.mw.show()
self.close()
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
mainWin = Login()
mainWin.show()
sys.exit( app.exec_() )
mainmenu.py
from PyQt5.QtCore import QSize
from PyQt5.QtWidgets import QPushButton
from PyQt5.QtWidgets import QMainWindow
class MainWindow(QMainWindow):
def __init__(self):
QMainWindow.__init__(self)
self.setMinimumSize(QSize(300, 200))
self.setWindowTitle("Main menu")
disconnect_button = QPushButton('Disconnect', self)
disconnect_button.clicked.connect(self.handeDC)
def handeDC(self):
pass
# here I either send a signal to handle it somewhere else
# or
# if i pass the login instance in __init__, just do login.show()
注意:由于这是一个常见问题,我将提供更广泛的答案,以更好地反映对象层次结构。
由于“主”窗口,顾名思义,是主窗口,包含它的脚本应该是主窗口,而登录窗口应该被导入并最终根据需要显示。
层次结构很重要:您不必考虑窗口的显示顺序,而是它们的相关性。
考虑到这一点,主脚本将:
以上还说明了为什么不断创建新的窗口实例很少是一个好主意。
登录窗口也应该是一个QDialog,这让事情变得更简单:exec()
方法是“阻塞”(用于函数执行,而不是用于事件循环),并等待对话框被接受或*拒绝。
main.py
from PyQt5.QtWidgets import *
from login import Login
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
self.setMinimumSize(300, 200)
self.setWindowTitle('Main menu')
disconnect_button = QPushButton('Disconnect')
self.setCentralWidget(disconnect_button)
# only for a *persistent* login dialog (*see below)
self.login = Login()
disconnect_button.clicked.connect(self.disconnect)
def start(self):
# put here some function that might check for a 'previous' logged in
# state, possibly stored using QSettings.
# in this case, we just assume that the user has never previously
# logged in, so we automatically show the login window; if the above
# function returns True instead, we can safely show the main window
logged = False
if logged:
self.show()
else:
self.showLogin()
def disconnect(self):
self.hide()
self.showLogin()
def showLogin(self):
if self.login.exec():
self.show()
# alternatively (*see below):
login = Login()
if login.exec():
self.show()
if __name__ == '__main__':
import sys
app = QApplication(sys.argv)
mainWindow = MainWindow()
mainWindow.start()
sys.exit(app.exec())
login.py
from PyQt5.QtWidgets import *
class Login(QDialog):
def __init__(self, parent=None):
super().__init__(parent)
self.setMinimumSize(300, 200)
self.setWindowTitle('Log in')
self.username = QLineEdit()
self.password = QLineEdit()
self.password.setEchoMode(self.password.Password)
self.connect_button = QPushButton('Connect', enabled=False)
layout = QGridLayout(self)
layout.addWidget(QLabel('Username:'), 0, 0)
layout.addWidget(self.username, 0, 1)
layout.addWidget(QLabel('Password:'), 1, 0)
layout.addWidget(self.password, 1, 1)
layout.addWidget(self.connect_button, 2, 0, 1, 2)
self.connect_button.clicked.connect(self.handleConnexion)
self.username.textChanged.connect(self.checkFields)
self.password.textChanged.connect(self.checkFields)
def checkFields(self):
if self.username.text() and self.password.text():
self.connect_button.setEnabled(True)
else:
self.connect_button.setEnabled(False)
def handleConnexion(self):
if self.username.text() == 'admin' and self.password.text() == '1':
self.accept()
else:
QMessageBox.warning(self, 'Error',
'Invalid username or password!')
笔记:
Login
实例,因此用户名和密码字段将“记住”以前的条目;如果您不希望这样,您可以随时clear()
通过覆盖来调用这些字段exec()
(但请记住调用基本实现并返回其结果!);或者,不要创建inself.login
并始终创建一个新的本地实例Login()
in showLogin()
;setCentralWidget()
;本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句