鸿蒙PC实战_鸿蒙Qt交互适配:软键盘遮挡与窗口调整
·
1. 被遮挡的输入框
用户点击界面底部的 QLineEdit 输入框,软键盘弹起。
但是!输入框依然停留在底部,被软键盘死死盖住。用户此时处于"盲打"状态。
在Android上,我们可以设置 adjustResize 或 adjustPan 来解决。
在鸿蒙 + Qt 的环境下,这个问题变得更加棘手,因为Qt窗口可能只是ArkUI中的一个 XComponent。
2. 鸿蒙的窗口模式
在 module.json5 中,Ability有一个 windowSoftInputMode 属性。
"abilities": [
{
"name": "EntryAbility",
// ...
"window": {
"softInputMode": 1
}
}
]
0(Unspecified)1(AdjustResize): 窗口大小改变,腾出空间。2(AdjustPan): 窗口整体上移。
理论上设置成 1 或 2 就能解决。但在Qt混合开发中,有时设置了 AdjustResize,Qt应用收到了Resize事件,但布局没有正确刷新,或者背景出现了黑边。
3. Qt侧的手动处理
如果系统级的自动调整不尽如人意(例如界面变形),我们可以手动处理。
思路:
- 监听键盘的显示/隐藏事件。
- 获取键盘高度。
- 将界面底部向上Padding,或者将滚动条滚动到焦点控件位置。
Qt API:QGuiApplication::inputMethod() 提供了键盘状态。
connect(qGuiApp->inputMethod(), &QInputMethod::keyboardRectangleChanged,
this, &MainWindow::onKeyboardChanged);
connect(qGuiApp->inputMethod(), &QInputMethod::visibleChanged,
this, &MainWindow::onKeyboardVisible);
槽函数实现:
void MainWindow::onKeyboardChanged() {
QRect rect = qGuiApp->inputMethod()->keyboardRectangle().toRect();
int height = rect.height();
// 如果键盘可见
if (qGuiApp->inputMethod()->isVisible()) {
// 给CentralWidget设置底边距,防止内容被遮挡
ui->centralWidget->setStyleSheet(
QString("QWidget#centralWidget { padding-bottom: %1px; }").arg(height)
);
// 或者滚动ScrollArea
QTimer::singleShot(100, this, [this](){
ensureFocusWidgetVisible();
});
} else {
// 恢复
ui->centralWidget->setStyleSheet("");
}
}
4. 焦点控件自动滚动
为了让用户体验更好,我们需要确保当前获取焦点的控件(Focus Widget)在可视区域内。
void MainWindow::ensureFocusWidgetVisible() {
QWidget *focusConfig = QApplication::focusWidget();
if (!focusConfig) return;
// 简单的逻辑:如果控件在屏幕下方,就滚动ScrollArea
// 实际需要坐标转换 mapToGlobal 等
ui->scrollArea->ensureWidgetVisible(focusConfig);
}
5. 沉浸式状态栏的冲突
如果你的应用开启了"沉浸式"(全屏,状态栏透明),AdjustResize 可能会导致状态栏区域也发生奇怪的偏移。
最佳实践:
在鸿蒙混合开发中,推荐使用 AdjustPan (整体平移) 模式配合Qt的手动滚动。AdjustResize 会导致Qt触发重绘(Repaint),在复杂界面上可能有性能开销,且容易导致背景图片拉伸变形。
6. 总结
软键盘适配是UI细节打磨的重点。
- 优先尝试修改
module.json5的softInputMode。 - 如果系统行为不符合需求,使用
QInputMethod监听高度变化。 - 手动调整
Padding或ScrollArea位置,确保焦点可见。
不要让软键盘成为用户交互的拦路虎。
欢迎加入开源鸿蒙PC社区:https://harmonypc.csdn.net/
更多推荐


所有评论(0)