[英]How to reopen window after closing other one?
I work on qml-based application.我从事基于 qml 的应用程序。
Environment:环境:
I'd like to have the following behaviour:我想有以下行为:
Now I have the following issue after closing Login window without access token (login.res_token == ""):现在,在没有访问令牌的情况下关闭登录窗口后出现以下问题(login.res_token == ""):
The program has unexpectedly finished.
The process was ended forcefully.
...\Python\Python37\python.exe crashed.
A piece of main.py:一段main.py:
def init_app():
app_login = QGuiApplication(sys.argv)
engine = QQmlApplicationEngine()
manager = ComponentCacheManager(engine)
context = engine.rootContext()
context.setContextProperty("componentCache", manager)
current_path = os.path.abspath(os.path.dirname(__file__))
qml_file = os.path.join(current_path, 'ui/LoginPage.qml')
engine.load(qml_file)
login = Login()
engine.rootContext().setContextProperty("login", login)
win = engine.rootObjects()[0]
win.show()
app_login.exec_()
if(login.res_token != ""):
main_app = QGuiApplication(sys.argv)
engine = QQmlApplicationEngine()
manager = ComponentCacheManager(engine)
context = engine.rootContext()
context.setContextProperty("componentCache", manager)
current_path = os.path.abspath(os.path.dirname(__file__))
qml_file = os.path.join(current_path, 'ui/GeneralPage.qml')
engine.load(qml_file)
engine.rootContext().setContextProperty("access_token", login.res_token)
win = engine.rootObjects()[0]
win.show()
main_app.exec_()
init_app()
else:
sys.exit()
if __name__ == "__main__":
init_app()
However, if I code in another way (without recursion), this action works correctly.但是,如果我以另一种方式进行编码(不使用递归),则此操作可以正常工作。 For example:
例如:
if __name__ == "__main__":
app_login = QGuiApplication(sys.argv)
engine = QQmlApplicationEngine()
manager = ComponentCacheManager(engine)
context = engine.rootContext()
context.setContextProperty("componentCache", manager)
current_path = os.path.abspath(os.path.dirname(__file__))
qml_file = os.path.join(current_path, 'ui/LoginPage.qml')
engine.load(qml_file)
login = Login()
engine.rootContext().setContextProperty("login", login)
win = engine.rootObjects()[0]
win.show()
app_login.exec_()
if(login.res_token != ""):
main_app = QGuiApplication(sys.argv)
engine = QQmlApplicationEngine()
manager = ComponentCacheManager(engine)
context = engine.rootContext()
context.setContextProperty("componentCache", manager)
current_path = os.path.abspath(os.path.dirname(__file__))
qml_file = os.path.join(current_path, 'ui/GeneralPage.qml')
engine.load(qml_file)
engine.rootContext().setContextProperty("access_token", login.res_token)
win = engine.rootObjects()[0]
win.show()
main_app.exec_()
else:
sys.exit()
But here I don't reopen Login window after closing General window.但是在这里我没有在关闭常规窗口后重新打开登录窗口。
If I write something like that, the program crashes after closing General window with the same error:如果我写这样的东西,程序会在关闭常规窗口后崩溃并出现相同的错误:
if __name__ == "__main__":
while(True):
app_login = QGuiApplication(sys.argv)
engine = QQmlApplicationEngine()
manager = ComponentCacheManager(engine)
context = engine.rootContext()
context.setContextProperty("componentCache", manager)
current_path = os.path.abspath(os.path.dirname(__file__))
qml_file = os.path.join(current_path, 'ui/LoginPage.qml')
engine.load(qml_file)
login = Login()
engine.rootContext().setContextProperty("login", login)
win = engine.rootObjects()[0]
win.show()
app_login.exec_()
if(login.res_token != ""):
main_app = QGuiApplication(sys.argv)
engine = QQmlApplicationEngine()
manager = ComponentCacheManager(engine)
context = engine.rootContext()
context.setContextProperty("componentCache", manager)
current_path = os.path.abspath(os.path.dirname(__file__))
qml_file = os.path.join(current_path, 'ui/GeneralPage.qml')
engine.load(qml_file)
engine.rootContext().setContextProperty("access_token", login.res_token)
win = engine.rootObjects()[0]
win.show()
main_app.exec_()
else:
break
sys.exit()
How will it be better to resolve this problem?如何更好地解决这个问题?
The logic is to use the signals to notify the changes and in the logical part to change the page逻辑是使用信号通知更改并在逻辑部分更改页面
import os
from PyQt5 import QtCore, QtGui, QtQml
class AuthenticationManager(QtCore.QObject):
login_signal = QtCore.pyqtSignal()
logout_signal = QtCore.pyqtSignal()
def __init__(self, parent=None):
super().__init__(parent)
self._token = ""
@QtCore.pyqtProperty(str, constant=True)
def token(self):
return self._token
@QtCore.pyqtSlot(str, str, result=bool)
def login(self, username, password):
self._token = self._get_token(username, password)
if self.token:
self.login_signal.emit()
return True
return False
@QtCore.pyqtSlot()
def logout(self):
self._token = ""
self.logout_signal.emit()
def _get_token(self, username, password):
"emulate token"
if username == "user" and password == "pass":
return "Token"
return ""
class WindowManager(QtCore.QObject):
def __init__(self, parent=None):
super().__init__(parent)
self._current_page = ""
self._engine = QtQml.QQmlApplicationEngine()
self._authentication = AuthenticationManager()
self._authentication.login_signal.connect(self.on_login_signal)
self._authentication.logout_signal.connect(self.on_logout_signal)
self._engine.rootContext().setContextProperty(
"authentication", self._authentication
)
def init(self):
self.on_logout_signal()
def on_login_signal(self):
self.current_page = "ui/GeneralPage.qml"
def on_logout_signal(self):
self.current_page = "ui/LoginPage.qml"
@property
def current_page(self):
return self._current_page
@current_page.setter
def current_page(self, page):
self._current_page = page
current_dir = os.path.abspath(os.path.dirname(__file__))
qml_file = os.path.join(current_dir, self.current_page)
self._engine.load(qml_file)
if __name__ == "__main__":
import sys
app = QtGui.QGuiApplication(sys.argv)
manager = WindowManager()
manager.init()
sys.exit(app.exec_())
LoginPage.qml登录页面.qml
import QtQuick 2.13
import QtQuick.Controls 2.13
ApplicationWindow {
id: root
visible: true
width: 640
height: 480
title: "Login Page"
Row{
TextField {
id: username
placeholderText: qsTr("Enter name")
}
TextField {
id: password
placeholderText: qsTr("Enter password")
echoMode: TextInput.Password
}
Button{
text: "Login"
onClicked: {
if(authentication.login(username.text, password.text)){
console.log("token:", authentication.token)
root.close()
}
}
}
}
}
GeneralPage.qml通用页面.qml
import QtQuick 2.13
import QtQuick.Controls 2.13
ApplicationWindow {
id: root
visible: true
width: 640
height: 480
title: "General Page"
Button{
text: "Logout"
onClicked: close()
}
onClosing: authentication.logout()
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.