方案 1: 启用 “Emulate terminal in output console”
这是一个常用的方法, 点击 Pycharm 右上方的运行下拉框 – “Edit Configurations…” – 勾选 “Emulate terminal in output console”:
缺点:
- Pycharm 控制台会失去一些特性. 比如原先可以显示蓝色下划线的链接, 但是启用这个后就变成普通文本; 原先控制台可以打印彩色文字和背景, 启用这个后就不行了 (如下图所示)
- QML
console.log
不显示源码行, 所以不好定位日志来源
方案 2: 使用 lk-qtquick-scaffold (推荐)
这是一个新方案, 首先 pip 安装 “lk-qtquick-scaffold” 第三方库:
pip install lk-qtquick-scaffold
安装完成后, 您只需通过 lk-qtquick-scaffold 启动 QML, 即可看到效果:
"""
myproj
|- main.py
|- view.qml
"""
# == main.py ==
# 很简单, 只有两行代码
from lk_qtquick_scaffold import app
app.start('view.qml')
// == view.qml ==
import QtQuick 2.15
import QtQuick.Window 2.15
Window {
width: 100; height: 100
visible: true
Component.onCompleted: {
console.log('hello world')
}
}
运行截图:
原理解析
参考 Stack Overflow 上的第二个回答. 简单来说就是用到了 PySide2.QtCore.qInstallMessageHandler()
函数:
import PySide2.QtCore
def log(mode, ctx, msg):
"""
Args:
mode (PySide2.QtCore.QtMsgType): 模式.
一共有六种模式:
QtCriticalMsg
QtDebugMsg
QtFatalMsg
QtInfoMsg
QtSystemMsg
QtWarningMsg
平时我们在 QML 中使用 `console.log`, `console.debug`, 其对应的模式都是
QtDebugMsg; 当 QML 出现报错时, 模式是 QtWarningMsg 或者 QtCriticalMsg.
其他不太常见, 暂不清楚在什么情况下产生.
ctx (PySide2.QtCore.QMessageLogContext): 'context (上下文)'.
上下文指的就是源码行了. 通过以下属性可获得与源码行有关的关键信息:
ctx.file (str): 源码所在文件的绝对路径, 注意是以 'file:///' 开头, 其文件
后缀通常是 '.qml' 或 '.js'.
ctx.line (int): 源码所在第几行, 从 1 开始数.
ctx.function (str|None): 所属函数名. None 表示无所属函数.
ctx.category (str): 这个值目前只观察到始终是 'qml'.
ctx.version: int (always to 2 in lk_qtquick_scaffold)
msg (str): 'message', 对应 `console.log(...)` 中的 '...' 内容.
Returns:
print: '{file}:{line_number} >> {function} >> {message}'
"""
print('{}:{}'.format(simple_path(ctx.file), ctx.line),
ctx.function, msg, sep='\t>>\t')
# 最后, 我们使用 qInstallMessageHandler 绑定此函数.
# (注: 该步骤要放在 QmlEngine 启动前完成)
PySide2.QtCore.qInstallMessageHandler(log)