PyQt5 QML应用调用QApplication.exec()时冻结且不显示窗口
解决PyQt5加载QML时冻结无窗口的问题
我帮你梳理几个核心问题点,应该能解决你的脚本冻结、无窗口显示的问题:
1. QML顶层缺少窗口容器是关键原因
你的CurrentValues.qml顶层元素是ListView,但QQmlApplicationEngine要求顶层必须是**Window或ApplicationWindow**才能正确创建并显示可视化窗口。C++版本能运行,大概率是实际使用的QML被窗口容器包裹了(可能你贴的代码有遗漏),而Python版本直接加载ListView会导致Qt无法初始化窗口,进而让事件循环异常卡住。
修改你的CurrentValues.qml,给ListView加上窗口容器:
import QtQuick 2.0 import QtQuick.Window 2.0 Window { visible: true width: 650 height: 100 title: "Current Values" ListView { anchors.fill: parent orientation: ListView.Horizontal flickableDirection: Flickable.HorizontalFlick delegate: CurrentValueViewer {} model: ListModel { id: valuesModel ListElement { valueName: "Temp" curValue: "250°" } ListElement { valueName: "CO2" curValue: "125 PPM" } ListElement { valueName: "O2" curValue: "18 %" } ListElement { valueName: "N2" curValue: "15%" } ListElement { valueName: "RH" curValue: "80 %" } } } }
2. 确保QML文件路径正确
你的Python代码用相对路径./qml/CurrentValues.qml加载文件,要注意运行脚本时的当前工作目录必须是包含qml文件夹的上级目录。如果经常切换目录运行脚本,建议改用基于脚本文件的绝对路径:
import os from PyQt5.QtCore import QUrl # 获取脚本所在目录,拼接QML文件路径 script_dir = os.path.dirname(os.path.abspath(__file__)) qml_file_path = os.path.join(script_dir, "qml", "CurrentValues.qml") engine.load(QUrl.fromLocalFile(qml_file_path))
3. 让Ctrl-C能正常终止程序
Qt的事件循环会捕获SIGINT信号,导致你无法用Ctrl-C终止脚本。可以添加信号处理代码:
import signal def run(): logging.basicConfig(level = logging.DEBUG) logging.info("Create application object") app = QApplication(sys.argv) # 处理Ctrl-C信号,触发程序退出 signal.signal(signal.SIGINT, lambda *args: app.quit()) # 其余代码不变 logging.info("Create qml engine/view") engine = QQmlApplicationEngine() # ...
4. 检查QtQuick.Controls版本兼容性
你的CurrentValueViewer.qml使用了QtQuick.Controls 1.4,Ubuntu 17.10自带的PyQt5版本可能对这个控件版本支持有限。如果后续遇到控件渲染问题,可以尝试升级到QtQuick.Controls 2.x(注意2.x与1.x API有差异),或者确认python3-pyqt5.qtquickcontrols包是否已安装。
优先尝试第一个修改(给QML添加Window容器),这是导致你脚本冻结无窗口的最直接原因。
内容的提问来源于stack exchange,提问作者Vladimir D.
相关产品推荐
相关产品推荐

