显示虚拟键盘时调整 QML 窗口大小

问题描述 投票:0回答:5

我正在使用 Qt/QML 编写一个聊天应用程序。但是,我在 Android 设备上测试应用程序时发现了一个问题:虚拟键盘将窗口向上“移动”,并且不允许我看到许多显示的消息,只能看到应用程序的底部。

理想情况下,我想调整窗口大小,以便显示消息控件(例如文本框和附加文件按钮)和标题栏。对于图形示例,您可以看一下:

screenshot of UI with keyboard shown

可以在 QML 中执行此操作吗?

android qt keyboard qml
5个回答
3
投票

您可以告诉 Android 为您执行此操作。

在您调整

<activity>
AndroidManifest.xml
标签后,只要出现虚拟键盘,Android 就会调整您的应用程序窗口大小,如下所示:

<activity ... android:windowSoftInputMode="adjustResize">

来源: 这是在 two comments 中针对 Qt 错误的解决方法进行讨论的,该错误在 2015 年底之前的一段时间内阻止手动调整窗口大小。


1
投票

从 Qt 5.12 部署到 Android 10(C++,无需 QML)。似乎没有任何非 QML C++ 示例可以调整应用程序大小以响应屏幕键盘可见性变化。我发现的那些需要与 Qt4 中的 Java 进行交互。

有必要为所有可见 UI 创建一个与 QMainWindow 分开的容器。 QMainWindow 通常占据整个屏幕,并与屏幕键盘重叠。容器 QWidget 是可以调整大小的,并且必须包含您期望不在键盘下的每个 UI 元素。

该示例使用 QFrame 作为一个非常小的(轻量级)容器。

你的应用程序.cpp:

YourApp::YourApp ( QWidget *parent ) : QMainWindow ( parent ) {

    // With Android, an application running normally ...
    // ... occupies the whole screen. Plan accordingly.
    QSize availableSize = qApp->desktop()->availableGeometry().size();
    Application_Width = availableSize.width();
    Application_Height = availableSize.height();

    App_Frame = new QFrame(this);
    // Build your UI inside this QFrame

    setCentralWidget(App_Frame);

    Virtual_Keyboard_Enabled = true;
    App_Input_Method = QApplication::inputMethod();
    connect(App_Input_Method, SIGNAL(keyboardRectangleChanged()),
            this, SLOT(onKeyboardRectangleChanged()));

    this->show();
}

void
YourApp::onKeyboardRectangleChanged ( ) {
#if defined(Q_OS_ANDROID)
    bool keyboard_visible = App_Input_Method->isVisible();
    QRectF keyboard_rectangle = App_Input_Method->keyboardRectangle();

    if (not keyboard_visible) {
        App_Frame->resize(Application_Width, Application_Height);
    }
    else {
        int keyboard_height = int(keyboard_rectangle.height());
        App_Frame->resize(Application_Width, 
                          (Application_Height - keyboard_height));
    }
#endif
}

void
YourApp::Toggle_Virtual_Keyboard_Enabled ( ) {
#if defined(Q_OS_ANDROID)
    Virtual_Keyboard_Enabled = not Virtual_Keyboard_Enabled;
    App_Input_Method->setVisible(Virtual_Keyboard_Enabled);
    qApp->setAutoSipEnabled(Virtual_Keyboard_Enabled);
#endif
}

你的应用程序.h:

class YourApp : public QMainWindow {
    Q_OBJECT

public:
    YourApp ( QWidget *parent = nullptr );
    ~YourApp ( );

private:
    bool Virtual_Keyboard_Enabled;
    QInputMethod *App_Input_Method;

    QFrame *App_Frame;

    void
    Toggle_Virtual_Keyboard_Enabled ( );

private slots:
    void
    onKeyboardRectangleChanged ( );
}

0
投票

这篇文章解释了当 Android 虚拟键盘出现时调整 QML 控件大小的方法。它涉及使用一些java代码,但您可以直接复制并粘贴链接的项目示例提供的代码:

QML:当 Android 虚拟键盘出现时调整控件大小


0
投票

当用户显示或隐藏虚拟键盘时,有一种仅 QML 的反应方式,即调整窗口内容的大小。

首先,确保 Android 尚未为您完成窗口大小调整(这也是可能的)。因此,您可以通过调整

<activity>
中的
AndroidManifest.xml
标签来告诉 Android 键盘应该与窗口重叠,如下所示:

<activity ... android:windowSoftInputMode="adjustPan">

然后,您可以将以下内容放入 QML 文件中,您可以在其中访问要调整大小和/或重新定位的窗口或窗口内容:

Connections {
    target: Qt.inputMethod

    onKeyboardRectangleChanged: {
        var newRect = Qt.inputMethod.keyboardRectangle

        console.log(
            "New keyboard rectangle size:" + 
            " x: " + newRect.x + 
            " y: " + newRect.y + 
            " width: " + newRect.width + 
            " height: " + newRect.height
        )

        // Your UI resizing / repositioning code goes here.
    }
}

说明和细节:

  • Qt
    QML 类型不可实例化(source),因此您无法编写
    Qt { inputMethod.onKeyboardRectangleChanged: { }}

  • Connections
    QML 类型是为这些情况而设计的,允许在发出信号的对象之外实现信号处理程序(详细信息)。

  • 另一种选择是使用

    connect()
    将信号连接到 JavaScript 函数,如此处所示。

  • 底层 C++ 类中使用的

    QRectF
    类型
    QInputMethod
    在 QML 中可用作 QML 基本类型
    rect
    。这已记录在here

    与 C++ 集成时,请注意,从 C++ 传递到 QML 的任何 QRect 或 QRectF 值都会自动转换为矩形值,反之亦然。

  • 您不应该在

    onVisibleChanged
    信号处理程序中实现此功能,因为当用户单击“隐藏键盘”按钮时,该事件在 Android 上不会触发。 (使用 Android 6.0 和 Qt 5.12 进行测试。)这似乎是 Qt 中的一个错误,因为高度 0 的键盘绝对不可见。


-1
投票
TextArea {
    //..
    //.. works with Qt 6.5.0 on iOS
    //..
    
    Connections {
        target: Qt.inputMethod

        function onKeyboardRectangleChanged() {
            var newRect = Qt.inputMethod.keyboardRectangle

            console.log(
                "New keyboard rectangle size:" +
                " x: " + newRect.x +
                " y: " + newRect.y +
                " width: " + newRect.width +
                " height: " + newRect.height
            )

            // Your UI resizing / repositioning code goes here.
        }
    }
}

Qt 文档链接:

© www.soinside.com 2019 - 2024. All rights reserved.