如何在 Kotlin Desktop Compose 中触发 PC 键盘输入
How to trigger PC Keyboard inputs in Kotlin Desktop Compose
我打算使用 Kotlin Jetpack Compose 开发一个 POS 系统,我想知道如何在我的项目中触发键盘输入事件。
在 Compose Desktop 中您可以使用 onKeyEvent
Window
参数监听按键事件:
Window(
onCloseRequest = ::exitApplication,
visible = visible,
onKeyEvent = {
if (it.isCtrlPressed && it.key == Key.A) {
println("Ctrl + A is pressed")
true
} else {
// let other handlers receive this event
false
}
}
) {
App()
}
在 Android 中也适用于 Compose 的另一个选项是使用 Modifier.onKeyEvent。正如文档所说:
will allow it to intercept hardware key events when it (or one of its children) is focused.
所以您需要使一个项目或其子项之一可聚焦和集中。在 this article
中查看有关撰写焦点的更多信息
为此,您需要一个 FocusRequester
,在我的示例中,我在使用 LaunchedEffect
.
呈现视图时询问焦点
对于未来的注意事项,如果用户点击文本字段,或者其他可获得焦点的元素将获得焦点,您的视图将失去它。如果这个焦点视图在你的 onKeyEvent
处理程序的视图中,它仍然可以工作。
空框无法成为焦点,因此您需要使用修饰符添加一些大小。它仍然是不可见的:
val requester = remember { FocusRequester() }
Box(
Modifier
.onKeyEvent {
if (it.isCtrlPressed && it.key == Key.A) {
println("Ctrl + A is pressed")
true
} else {
// let other handlers receive this event
false
}
}
.focusRequester(requester)
.focusable()
.size(10.dp)
)
LaunchedEffect(Unit) {
requester.requestFocus()
}
或者只需将内容添加到 Box
,这样它就会拉伸并且不再需要 .size
修饰符
当您设置焦点并出于某种原因在应用程序内部单击时,按照 Philip 答案的第二个选项可能会出现奇怪的行为 window。这样做,可能会“失去”焦点,并且关键事件处理不当。
为了避免这种情况,建议通过添加 click/tap 修饰符手动处理此问题,它仅指定当检测到 click/tap 时,requester
再次请求焦点。见下文:
val requester = FocusRequester()
Box(
Modifier
//pointer input handles [onPress] to force focus to the [requester]
.pointerInput(key1 = true) {
detectTapGestures(onPress = {
requester.requestFocus()
})
}
.onKeyEvent {
if (it.isCtrlPressed && it.key == Key.A) {
println("Ctrl + A is pressed")
true
} else {
// let other handlers receive this event
false
}
}
.focusRequester(requester)
.focusable()
.fillMaxSize()
.background(Color.Cyan)
)
LaunchedEffect(Unit) {
requester.requestFocus()
}
我打算使用 Kotlin Jetpack Compose 开发一个 POS 系统,我想知道如何在我的项目中触发键盘输入事件。
在 Compose Desktop 中您可以使用 onKeyEvent
Window
参数监听按键事件:
Window(
onCloseRequest = ::exitApplication,
visible = visible,
onKeyEvent = {
if (it.isCtrlPressed && it.key == Key.A) {
println("Ctrl + A is pressed")
true
} else {
// let other handlers receive this event
false
}
}
) {
App()
}
在 Android 中也适用于 Compose 的另一个选项是使用 Modifier.onKeyEvent。正如文档所说:
will allow it to intercept hardware key events when it (or one of its children) is focused.
所以您需要使一个项目或其子项之一可聚焦和集中。在 this article
中查看有关撰写焦点的更多信息为此,您需要一个 FocusRequester
,在我的示例中,我在使用 LaunchedEffect
.
对于未来的注意事项,如果用户点击文本字段,或者其他可获得焦点的元素将获得焦点,您的视图将失去它。如果这个焦点视图在你的 onKeyEvent
处理程序的视图中,它仍然可以工作。
空框无法成为焦点,因此您需要使用修饰符添加一些大小。它仍然是不可见的:
val requester = remember { FocusRequester() }
Box(
Modifier
.onKeyEvent {
if (it.isCtrlPressed && it.key == Key.A) {
println("Ctrl + A is pressed")
true
} else {
// let other handlers receive this event
false
}
}
.focusRequester(requester)
.focusable()
.size(10.dp)
)
LaunchedEffect(Unit) {
requester.requestFocus()
}
或者只需将内容添加到 Box
,这样它就会拉伸并且不再需要 .size
修饰符
当您设置焦点并出于某种原因在应用程序内部单击时,按照 Philip 答案的第二个选项可能会出现奇怪的行为 window。这样做,可能会“失去”焦点,并且关键事件处理不当。
为了避免这种情况,建议通过添加 click/tap 修饰符手动处理此问题,它仅指定当检测到 click/tap 时,requester
再次请求焦点。见下文:
val requester = FocusRequester()
Box(
Modifier
//pointer input handles [onPress] to force focus to the [requester]
.pointerInput(key1 = true) {
detectTapGestures(onPress = {
requester.requestFocus()
})
}
.onKeyEvent {
if (it.isCtrlPressed && it.key == Key.A) {
println("Ctrl + A is pressed")
true
} else {
// let other handlers receive this event
false
}
}
.focusRequester(requester)
.focusable()
.fillMaxSize()
.background(Color.Cyan)
)
LaunchedEffect(Unit) {
requester.requestFocus()
}