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

时间:2014-09-09 00:28:17

标签: android qt keyboard qml

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

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

screenshot of UI with keyboard shown

是否可以在QML中执行此操作?

4 个答案:

答案 0 :(得分:1)

从Qt 5.12部署到Android 10(C ++,不需要QML)。似乎没有任何非QML C ++示例可以根据屏幕键盘可见性的变化来调整应用程序的大小。我确实发现的那些需要与Qt4的Java接口。

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

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

YourApp.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
}

YourApp.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 ( );
}

答案 1 :(得分:0)

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

QML: Resize controls when Android virtual keyboard come up

答案 2 :(得分:0)

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

在调整<activity>的{​​{1}}标签后,只要出现虚拟键盘,Android就会调整应用程序窗口的大小,如下所示:

AndroidManifest.xml

来源:two comments中,这是一种解决方法,用于解决Qt错误,该错误阻止手动调整窗口大小直到2015年底。 >

答案 3 :(得分: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类型,从而可以在发出它的对象(details)之外实现信号处理程序。

  • 另一种选择是使用connect()将信号连接到JavaScript函数,如here所示。

  • 底层C ++类QInputMethod中使用的QRectF类型在QML中可用作QML基本类型rect。记录在here中:

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

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