Qapplication
需要理解下QApplication
- notify可以捕获的事件, 目标空间转发的, 所以filter和notify会捕获
| 事件类型 | 触发时机 | macOS 15 注意 |
|---|---|---|
QEvent::TabletEnterProximity / LeaveProximity |
使用 Apple Pencil(Sidecar 或 Studio Display 带触控) | 只在笔进入/离开屏幕边缘时发 |
QEvent::Gesture / GestureOverride |
触控板捏合、旋转、智能缩放 | macOS 15 默认会把三指 pinch 转成 Qt::ZoomNativeGesture |
- event可以捕获的事件(qapp自己的事件):
| 事件类型(PySide 枚举) | 典型触发场景(macOS 15) |
|---|---|
QEvent.FileOpen |
Finder 双击文档、拖拽文件到 Dock 图标、Spotlight 回车打开 |
QEvent.ApplicationActivate |
用户点击 Dock 图标、Mission Control 切回、Stage Manager 选回应用 |
QEvent.ApplicationDeactivate |
切到别的 App、进入 Mission Control、Stage Manager 隐藏 |
QEvent.ApplicationStateChange |
系统睡眠/唤醒、快速用户切换、控制中心→专注模式切换 |
QEvent.ApplicationFontChange |
系统设置→外观→字体大小变动(macOS 15 新“更大字体”滑块) |
QEvent.ApplicationPaletteChange |
深色/浅色自动切换、墙纸配色变动触发的外观色板更新 |
QEvent.Clipboard |
第一次访问粘贴板、其他设备通过通用剪贴板推送内容 |
QEvent.LanguageChange |
动态加载/卸载翻译文件后(应用内),或系统多语言热切换 |
QEvent.LocaleChange |
系统设置→语言与地区→地区/24h/货币/温度单位改动 |
QEvent.SessionManager |
macOS 关机/重启时请求“是否保存”会话(Qt 自动对接 NSApplication 回调) |
QEvent.Close |
仅当没有顶层窗口时,用户 Cmd+Q 或 Dock→退出,事件直接发给 QApplication |
QEvent.Quit |
调用 QCoreApplication::quit() 或最后一个窗口关闭且 quitOnLastWindowClosed=true 时发给自己 |
QEvent.Timer |
你手动 startTimer() 在 QApplication 上建的 QBasicTimer 超时 |
QEvent.ChildAdded/ChildRemoved |
把 QObject 的 parent 设成 qApp,子对象被挂/卸时会进 event() |
QEvent.DynamicPropertyChange |
对 qApp 自身调用 setProperty() 产生动态属性变更 |
-
QApplication 有 event() 和 notify() 两个虚函数,
-
event() 限于QApplication自身的事件处理
-
notify() 全局事件分发点,适合重载监控所有事件
-
所有QObeject派生的都有这个notify
-
但是只有app会自动生效, 其他的不在事件分发的链路时, 不会触发.
-
-
信号
| 信号原型 | 触发时机 | 常见用途 |
|---|---|---|
aboutToQuit() |
事件循环即将退出(quit() 被调用或最后一个窗口关闭且 quitOnLastWindowClosed=True) |
保存设置、刷缓存、终止线程 |
lastWindowClosed() |
最后一个 QWidget 窗口被关闭(无论是否退出) |
弹“确认退出”或隐藏到托盘 |
focusChanged(QWidget *old, QWidget *now) |
任意两个 QWidget 之间焦点切换 | 全局记录当前焦点、更新状态栏 |
commitDataRequest(QSessionManager &) |
macOS/Windows 会话管理器要求“准备关机/注销” | 保存会话、拒绝注销 |
saveStateRequest(QSessionManager &) |
系统要求保存会话状态(休眠、快速用户切换) | 写恢复文件、注册重启参数 |
applicationStateChanged(Qt::ApplicationState state) |
应用状态变化(Active / Inactive / Suspended) |
暂停播放、停止网络轮询 |
screenAdded(QScreen *screen) |
物理显示器插入或虚拟桌面新增 | 迁移窗口、重新计算 DPI |
screenRemoved(QScreen *screen) |
显示器拔掉 | 把窗口挪回主屏、释放资源 |
app = QApplication(argv)
# 1. 即将退出
app.aboutToQuit.connect(lambda: qDebug("about to quit"))
# 2. 焦点变化
app.focusChanged.connect(lambda old, now: qDebug(f"focus {old} -> {now}"))
# 3. 最后一个窗口关闭
app.lastWindowClosed.connect(lambda: qDebug("last window gone"))
-
事件 = 内部控制流,必须同步、可拦截、立即消费;
-
信号 = 对外通知接口,松散、可选、可异步、多播;
print此时很可能是失效/甚至是app崩溃的原因
下面说的不对, 最好的办法就是输出到文本文件, 用logging或者直接写标准输出文件位置, console一般就是看不到
- 用 Qt 自己的日志通道 (
qDebug,qWarning) 输出,保证在 Console.app / Xcode 日志 /log stream里一定能看见。 - 开发阶段vscode的terminal直接可以看到
- app阶段, 打开应用: console, -> 点击工具栏最左侧的: 开始 -> 然后搜索框输入 xxx.app 作为过滤条件, 搜索框可以谓词
- 直接输入: xxx.app
- process: xx 只看xx进程
- p: xx 缩写
subsystem:com.mycompany只看子系统category:viewcycle只看类别- 组合多个键值, 用空格分割, 代表’且’关系
# 也可以用xcode工具来看
log stream --level debug --predicate 'processImagePath contains "YourApp"'