目录
做界面时,用户希望常用的操作不用每次都点鼠标------按一下 Ctrl+S 就保存,按一下 Ctrl+K 再按 Ctrl+C 就注释一段代码。QML 里有个专门的 Shortcut 组件干这件事:注册一个按键序列,触发时执行一段逻辑,不用自己写一堆按键监听。下面从最基础的单个组合键讲起,再延伸到更复杂的组合键序列。
基础快捷键
界面上摆了三张提示卡片:Ctrl+S 保存、Ctrl+C 复制、Ctrl+V 粘贴。窗口不聚焦任何输入框时,直接按这三个组合键,底部状态栏会显示"已执行: 保存"这样的反馈,右侧的操作日志区域还会逐条记录每一次触发的按键和时间。

演示代码
qml
import QtQuick
import QtQuick.Layouts
FadeInAnimation {
ColumnLayout {
anchors.fill: parent
anchors.margins: 20
spacing: 15
// ... 省略标题组件 TitleSeparator ...
// 快捷键注册
Shortcut {
sequence: "Ctrl+S"
onActivated: {
logModel.append({ text: "Ctrl+S - 保存", time: Qt.formatTime(new Date(), "hh:mm:ss") })
statusText.text = "已执行: 保存"
}
}
Shortcut {
sequence: "Ctrl+C"
onActivated: {
logModel.append({ text: "Ctrl+C - 复制", time: Qt.formatTime(new Date(), "hh:mm:ss") })
statusText.text = "已执行: 复制"
}
}
Shortcut {
sequence: "Ctrl+V"
onActivated: {
logModel.append({ text: "Ctrl+V - 粘贴", time: Qt.formatTime(new Date(), "hh:mm:ss") })
statusText.text = "已执行: 粘贴"
}
}
// ... 省略快捷键提示卡片 Repeater ...
// 操作日志
Rectangle {
Layout.fillWidth: true
Layout.fillHeight: true
radius: 8
color: "#FAFAFA"
border.color: "#ddd"
border.width: 1
ColumnLayout {
anchors.fill: parent
anchors.margins: 10
spacing: 4
Text {
text: "操作日志"
font.pointSize: 11
font.bold: true
color: "#666"
}
ListView {
Layout.fillWidth: true
Layout.fillHeight: true
clip: true
model: ListModel { id: logModel }
delegate: Text {
text: "[" + model.time + "] " + model.text
font.pointSize: 11
color: "#333"
}
}
}
}
// ... 省略底部状态提示 Text ...
}
}
关键逻辑解析
Shortcut 是注册,不是画控件
Shortcut 和之前讲的按钮不一样,它本身不占界面、看不到,它只做一件事:记住一个按键序列,然后监听键盘。代码里三个 Shortcut 各注册了一个组合键,剩下的就是等着触发。
sequence 写按键,onActivated 写逻辑
每个 Shortcut 就两个关键点:sequence 告诉它监听什么键,onActivated 告诉它触发后干什么。这里的写法很直白,Ctrl+S 对应保存、Ctrl+C 对应复制、Ctrl+V 对应粘贴,一一对应。注意按键写法是固定的格式,两个键之间用加号连接,比如 Ctrl 加 S 就写成 "Ctrl+S"。
触发后顺手记个日志
onActivated 里除了更新状态栏文字,还往 logModel 里追加一条记录,带上当前时间。这个日志用的是 Qt.formatTime 格式化出的时分秒。它顺带说明了一个常见做法------把快捷键触发的动作记录下来,方便调试和给用户反馈。
注意一个前提:别抢系统快捷键
Ctrl+C、Ctrl+V 这类组合在文本输入框里是"复制粘贴"的原生操作。本 demo 里没有可编辑的输入框,所以窗口级生效不冲突。如果你界面上有 TextField,就要考虑快捷键的优先级和冲突,这在后面讲作用域时会细说。
组合键序列
这次除了 Ctrl+Shift+S 另存为、Ctrl+Shift+A 全选这种"修饰键多一点"的组合,还引入了一种 VSCode 风格的连续键序列:Ctrl+K 之后再按 Ctrl+C。屏幕上三个提示卡片,下方一个大字体的触发显示区,按中哪个组合,文字就变颜色并闪一下。

演示代码
qml
import QtQuick
import QtQuick.Layouts
FadeInAnimation {
ColumnLayout {
anchors.fill: parent
anchors.margins: 20
spacing: 15
// ... 省略标题组件 TitleSeparator ...
// 多键序列快捷键
Shortcut {
sequence: "Ctrl+Shift+S"
onActivated: {
triggerLabel.text = "Ctrl+Shift+S - 另存为"
triggerLabel.color = "#1296FF"
flashAnim.start()
}
}
Shortcut {
sequence: "Ctrl+Shift+A"
onActivated: {
triggerLabel.text = "Ctrl+Shift+A - 全选"
triggerLabel.color = "#21be2b"
flashAnim.start()
}
}
Shortcut {
sequence: "Ctrl+K, Ctrl+C"
onActivated: {
triggerLabel.text = "Ctrl+K, Ctrl+C - VSCode 风格注释"
triggerLabel.color = "#FF9800"
flashAnim.start()
}
}
// ... 省略提示卡片 Repeater ...
// 触发显示区
Rectangle {
Layout.alignment: Qt.AlignHCenter
width: 360
height: 60
radius: 10
color: "#EAF4FF"
border.color: "#1296FF"
border.width: 1
Text {
id: triggerLabel
anchors.centerIn: parent
text: "按下组合键试试"
font.pointSize: 15
font.bold: true
color: "#1296FF"
}
SequentialAnimation {
id: flashAnim
NumberAnimation { target: triggerLabel; property: "opacity"; to: 0.3; duration: 80 }
NumberAnimation { target: triggerLabel; property: "opacity"; to: 1.0; duration: 120 }
}
}
// ... 省略底部提示 Text ...
}
}
关键逻辑解析
组合键不是只有 Ctrl,修饰键可以叠着用
Ctrl+Shift+S 看着复杂,写法上只是把修饰键按顺序用加号连起来,快捷键语法的规则是一致的,区别只在按键多了几个。它本身没有新知识,主要是告诉你:一个快捷键里可以同时按下多个修饰键。
连续按键序列:逗号分隔,一步步按
真正的新东西是 Ctrl+K 然后 Ctrl+C 这种写法。sequence 里用逗号把两个组合键分开,表示"先按 Ctrl+K,再按 Ctrl+C",两步之间可以松开手。这是模仿 VSCode 的 chord 风格快捷键------适合按键数量多、单次按不下的场景,比如给自定义命令配快捷键时不想占太多全局组合。
触发后给个视觉反馈
每个 onActivated 都改文字、改颜色,再启动一个闪动动画。这个 SequentialAnimation 把透明度闪到 0.3 再闪回 1.0,就是那一下"闪"。快捷键触发后不一定要有复杂的响应,给用户一个明确、即时的视觉反馈同样重要------至少让用户知道"按中了"。
单组合键和连续序列的区别很简单:单组合键一次按下(如 Ctrl+S),适合常用高频操作;连续键序列分步按下、可松手(如 Ctrl+K, Ctrl+C),适合低频但带命令前缀的操作,占用全局组合更少。
运行验证
- Qt Creator 打开示例的 CMakeLists.txt;
- 按 Ctrl+R 运行;
- 基础快捷键:不碰鼠标,按 Ctrl+S / Ctrl+C / Ctrl+V,看状态栏和操作日志变化;
- 组合键序列:按 Ctrl+Shift+S,再试 Ctrl+K 后跟 Ctrl+C,看触发显示区变色闪烁。
小结
给应用配一套全局快捷键时,用 Shortcut 逐个注册,逻辑写在 onActivated 里,比手写键盘事件监听清晰得多。"先按一个键,再按另一个键"的连续序列适合低频但有明确前缀的操作(比如编辑器命令),避免占用太多全局组合键。把日志追加抽成公共函数,所有快捷键共用,方便统一记录和排查。触发后配一个简短的状态提示或闪动反馈,用户"按没按中"一目了然。
已验证环境:
- Qt 版本:Qt 6.11.1
- 操作系统:Windows 11
- 项目地址:QML 示例合集V2.0 - qml_shortcut