QtWidgets应用程序使用虚拟键盘还是屏幕键盘?

4
我将在我的基于窗口小部件的应用程序中部署qtvirtualkeyboard,方法如下:
#include <QtWidgets>

int main(int argc, char *argv[]) {
    qputenv("QT_IM_MODULE", QByteArray("qtvirtualkeyboard"));
    QApplication app(argc, argv);
    QMainWindow window;
    QLineEdit input(&window);
    input.move(250, 250);
    window.show();
    return app.exec();
}

但唯一的问题是,虚拟键盘输入面板会隐藏下面的小部件并覆盖它们!
我该如何解决这个问题?
对于基于小部件的应用程序,是否有任何文档或解决方案?

2
请注意,Qt虚拟键盘是根据GNU通用公共许可证第3版(而不是其他模块的LGPL)提供的--请参见此处。您可能需要商业许可证...祝你好运! - vlp
2个回答

2
你只需要在main.cpp中添加这行代码。
qputenv("QT_IM_MODULE", QByteArray("qtvirtualkeyboard"));

这将使Qtwidgets中的虚拟键盘正常工作。

输入图像描述

1
是的,我手动解决了这个问题,你需要捕获事件,并在打开虚拟键盘时重新排列窗口,以便它们可见。 - Vahagn Avagyan
但据我所知,qtvirtualkeyboard是在QML中实现的,那么在QStackedWidget内使用键盘小部件或捕获事件的方法在哪里呢?谢谢。 - IMAN4K
有任何想法吗? - IMAN4K
@IMAN4K QT单独无法修复您的界面,您需要手动进行修复。 - Vahagn Avagyan
我将在全屏模式下打开我的MainWindow,但如何手动修复呢?您能否提供更详细的帮助?谢谢。 - IMAN4K
显示剩余3条评论

1

终于找到解决方案了!

你只需要调用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;

    /* move main widget */
    if (keyboard_visible && !_moved && need_to_move) {
        _moved = true;
        _lastDiff = diff;
        const auto g = parentWidget()->frameGeometry();
        parentWidget()->move(g.x(), g.y() - qAbs(_lastDiff));
    }
    /* roll back */
    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


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接