避免循环导入的同时,在pyqt5中的窗口之间来回切换
因此,我有2个窗口,我希望能够在登录和 mainWindow 之间切换,每个窗口 ,每个窗口都是 qwidget
strong> loginui.py 和 mainui.py 。
通过创建MainWindow的新实例,我可以在正确的身份验证后轻松切换到MAIN。但是在MainWindow中,我想拥有一个显示登录屏幕的“断开连接”按钮。
由于两者都在不同的文件中,因此在这种情况下导入会在Python中引起循环导入错误。
我尝试使用的其他方法是:
-
使用信号并在中间文件中处理它们。这很好,但是当我添加更多按钮/窗口时,文件开始变得有些混乱。
-
将登录的实例传递到
mainWindow .__ INT __(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.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()
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
注意:由于这是一个常见的问题,我将提供更多 broad 答案,可以更好地反映对象层次结构。,
因为“主”窗口是,如名称所暗示的那样, main 一个,包含它的脚本应为 main 一个,而登录窗口应被导入并最终按需要显示。
层次结构很重要:您不必考虑显示窗户的顺序,而是它们的相关性。
考虑到这一点,主脚本将:
以上还表明了为什么连续创建新的Windows实例很少是一个好主意。
登录窗口也应该是一个qdialog,它使事情变得更容易:
exec()
方法是“阻止”(用于函数执行,而不是事件循环),然后等待对话框被接受或 *被拒绝。main.py
login.py
注意:
登录
实例,因此用户名和密码字段将“记住”以前的条目;如果您不想要那个,可以随时调用clear> clear()
在这些字段上覆盖exec()
(但请记住调用基本实现并返回其结果!);另外,请勿创建self.login
,并且始终创建login()
inshowlogin()
in 的新的本地实例;setCentralWidget()
;Note: since this is a common question, I'll provide a more broad answer that better reflects the object hierarchy.
Since the "main" window is, as the name suggests, the main one, the script containing it should be the main one, while the login window should be imported and eventually shown as required.
The hierarchy is important: you don't have to consider the order in which the windows are shown, but their relevance.
Considering this, the main script will:
The above also shows why it's rarely a good idea to continuously create new instances of windows.
The login window should also be a QDialog, which makes things easier: the
exec()
method is "blocking" (for the function execution, not for the event loop), and waits until the dialog is accepted or *rejected.main.py
login.py
Notes:
Login
instance, so the username and password fields will "remember" the previous entries; if you don't want that, you can always callclear()
on those fields by overriding theexec()
(but remember to call the base implementation and return its result!); alternatively, don't create theself.login
and always create a new, local instance ofLogin()
inshowLogin()
;setCentralWidget()
;与其关闭
登录
在创建mainWindow
小部件时,您可以隐藏窗口小部件,该小部件可以节省创建新实例的开销,还可以使连接的插槽保持完整。然后,在您的
mainWindow
上,您可以创建一个diconnected
信号,当用户单击“断开连接”按钮时,应发出该信号。登录窗口可以侦听信号,并调用其
show
方法。我在以下示例中进行了内联评论:
mainwindow.py
login.py
Instead of closing the
Login
widget when creating theMainWindow
widget, you could just hide the widget, which will save the overhead of creating a new instance and also keep the connected slots intact.Then on your
MainWindow
you can create adiconnected
signal that should be emited when the user clicks the disconnect button.The login window can listen for the signal and call it's
show
method.I made inline comments where I made changes in the example below:
mainwindow.py
login.py