终于找到解决方案了!
你只需要调用QGuiApplication::inputMethod()
来获取全局的Qt输入法,然后调用QInputMethod::keyboardRectangle()
和QInputMethod::isVisible()
来获取输入法属性,然后根据你的部件位置和键盘坐标进行计算。这里提供一个完整可用的示例:
lineedit.h
:
class LineEdit :public QLineEdit {
Q_OBJECT
public:
LineEdit(QWidget *parent = nullptr);
LineEdit(const QString&, QWidget *parent = nullptr);
protected:
bool event(QEvent*) override;
private:
bool _moved = false;
int _lastDiff = 0;
};
lineedit.cpp
:
LineEdit::LineEdit(QWidget *parent) :QLineEdit(parent) {
setAttribute(Qt::WA_InputMethodEnabled, true);
setInputMethodHints(inputMethodHints() | Qt::InputMethodHint::ImhDigitsOnly);
}
LineEdit::LineEdit(const QString& txt, QWidget *parent) : QLineEdit(txt, parent) {
setAttribute(Qt::WA_InputMethodEnabled, true);
setInputMethodHints(inputMethodHints() | Qt::InputMethodHint::ImhDigitsOnly);
}
bool LineEdit::event(QEvent* e) {
const auto keyboard_rect = QGuiApplication::inputMethod()->keyboardRectangle();
const auto keyboard_visible = QGuiApplication::inputMethod()->isVisible();
const auto global_y = QWidget::mapToGlobal(rect().topLeft()).y() + height();
const auto k_global_y = keyboard_rect.topLeft().y();
const auto diff = k_global_y - global_y;
const auto need_to_move = diff < 0;
if (keyboard_visible && !_moved && need_to_move) {
_moved = true;
_lastDiff = diff;
const auto g = parentWidget()->frameGeometry();
parentWidget()->move(g.x(), g.y() - qAbs(_lastDiff));
}
if (!keyboard_visible && _moved) {
_moved = false;
const auto g = parentWidget()->frameGeometry();
parentWidget()->move(g.x(), g.y() + qAbs(_lastDiff));
}
return QLineEdit::event(e);
}
main.cpp
:
#include <QtWidgets>
#define W 1024
#define H 768
int main(int argc, char *argv[]) {
qputenv("QT_IM_MODULE", QByteArray("qtvirtualkeyboard"));
QApplication app(argc, argv);
QMainWindow window(nullptr, Qt::FramelessWindowHint);
LineEdit lineedit1(&window);
lineedit1.move(100, 450);
LineEdit lineedit2(&window);
lineedit2.move(100, 100);
window.resize(W, H);
window.show();
return app.exec();
}
结果:
![enter image description here](https://istack.dev59.com/xgXCH.gif)