我从事基于qml的应用程序。
环境:
64bit
我希望有以下行为:
现在,在关闭没有访问令牌的登录窗口(login.res_token ==“”)后,我遇到了以下问题:
The program has unexpectedly finished.
The process was ended forcefully.
...\Python\Python37\python.exe crashed.一段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()但是,如果我以另一种方式编写代码(不使用递归),则此操作将正确工作。例如:
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()但在这里我不会在关闭普通窗口后重新打开登录窗口。
如果编写类似的内容,程序会在关闭General窗口后崩溃,其错误与此相同:
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()怎样才能更好地解决这个问题呢?
发布于 2019-11-24 17:00:43
逻辑是使用信号通知更改,并在逻辑部分更改页面。
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
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
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()
}https://stackoverflow.com/questions/59018205
复制相似问题