我有使用 qml2 作为前端的 pyqt5 应用程序。从开发人员(我的)机器迁移到另一台机器(mint qiana,debian sid)时,它卡在导入QtQuick.Dialogs 1.1
上。
即使在运行映像debian-sid
新的docker
容器上也可以重现错误。
我的测试蟒蛇脚本:
from PyQt5 import QtWidgets, QtWidgets, QtCore, uic
from PyQt5.QtCore import pyqtProperty, QCoreApplication, QObject, QUrl
from PyQt5.QtQml import qmlRegisterType, QQmlComponent, QQmlEngine
class CommonQMLWindow():
def __init__(self, qml_file_name):
self._engine = QQmlEngine()
component = QQmlComponent(self._engine)
# STUCK HERE (LINE BELOW - component.loadUrl)
component.loadUrl(QUrl(qml_file_name))
self.qml_window = component.create()
if self.qml_window is None:
for error in component.errors():
print(error.toString())
exit(1)
from ui import commonqmlwindow
装载:
from PyQt5 import QtWidgets, QtWidgets, QtCore, uic
from PyQt5.QtCore import pyqtProperty, QCoreApplication, QObject, QUrl
from PyQt5.QtQml import qmlRegisterType, QQmlComponent, QQmlEngine
class MainWindow(commonqmlwindow.CommonQMLWindow):
def __init__(self, parent=None):
commonqmlwindow.CommonQMLWindow.__init__(self, 'ui/test.qml')
QML 文件:
import QtQuick 2.0
import QtQuick.Dialogs 1.1
import QtGraphicalEffects 1.0
import QtQuick.Controls 1.1
import QtQuick.Controls.Styles 1.2
import "." as Controls
import "../uihelpers.js" as UIHelpers
TextField {
id: rootItem
property bool pickDirectory: false
property alias pickerTitle: picker.title
property alias pickerSelectMask: picker.nameFilters
property alias selectedUrl: picker.fileUrl
readOnly: true
FileDialog {
id: picker
selectFolder: rootItem.pickDirectory ? true : false
}
}
main.py:
app = QtWidgets.QApplication(sys.argv)
main_window = mainwindow.MainWindow()
app.exec()
所有软件包都已安装(对于 qml2、python3、pyqt5 和 qt5)适用于除此以外的任何软件包。
此行为发生在 Linux Mint qiana
、 Debian sid
上。当我评论导入语句 ( //import QtQuick.Dialogs 1.1
) 时它可以工作,但我需要文件对话框。
版本:
Qt版本:5.3.2
PyQt 版本:5.3.2
蟒蛇版本:3.4.2
UPD:它甚至可以在Mac OS X Yosemite上运行,但在debian上则不能。
目前没有任何已知原因导致此行为。我创建了一个错误报告,并找到了该问题的解决方法。通过使用QQmlApplicationEngine
而不是QQmlEngine
来创建 qml 组件,可以避免此问题。似乎QQmlEngine
有问题,因为这两个类几乎做相同的工作。
from PyQt5 import QtQml
engine = QtQml.QQmlApplicationEngine()
engine.load(QtCore.QUrl('test.qml'))
sys.exit(app.exec())
此外,我也尝试使用C++代码重现错误,但似乎这种行为对 PyQt5 的实现很糟糕,只是因为它在后端工作正常C++。
不幸的是,我看不到PyQt
项目的任何错误跟踪器,因此除非开发人员看到此答案,否则它可能在很长一段时间内无法修复。