c++qtfocusqtableviewqtvirtualkeyboard

QtVirtualKeyboard focus problem when editing a cell in a QTableView


I have been battling for the last couple of days to include the QtVirtualKeyboard into my QWidget based app that is running on a Raspberry Pi with a 7" touch screen display.

Here's what I've done so far :

Installed the plugin :

sudo apt-get install -y qtvirtualkeyboard-plugin
sudo apt-get install -y qml-module-qtquick-controls2
sudo apt-get install -y qtdeclarative5-dev
sudo apt-get install qml-module-qt-labs-folderlistmodel

Added the QT_IM_MODULE environment variable and set that to qtvirtualkeyboard

Added QT += quickwidgets to my .pro

Created a QQuickWidget to place my virtual keyboard.

.h

private:
    QQuickWidget *m_quickWidget;

.cpp

// In constructor
QUrl source(QML_FILE_PATH + "virtualkeyboard.qml");
m_quickWidget->setSource(source);
m_quickWidget->setAttribute(Qt::WA_AcceptTouchEvents);
ui->verticalLayout->addWidget(m_quickWidget);

And finally my virtualkeyboard.qml file

import QtQuick 2.7
import QtQuick.VirtualKeyboard 2.1

Rectangle {
    id: window
    width: 600
    height: 0

    InputPanel {
        id: inputPanel
        width: window.width

        states: State {
            name: "visible"
            when: inputPanel.active
            PropertyChanges {
                target: window
                height: inputPanel.height
            }
        }
        transitions: Transition {
            from: ""
            to: "visible"
            reversible: true
            ParallelAnimation {
                NumberAnimation {
                    properties: "y"
                    duration: 250
                    easing.type: Easing.InOutQuad
                }
            }
        }
    }
}

So up to now, visually everything is looking pretty good. When I open my app, the keyboard widget is not visible (window height: 0 in qml), and when I double-click a cell in my QTableView (which has flags Qt::ItemIsEnabled | Qt::ItemIsEditable), the keyboard widget shows up at the bottom of my vertical layout at the right position and size.

And now to my problems :

I hope I have been clear enough, but will gladly provide more details if required.

Any help on either of these issues would be greatly appreciated.

Cheers.

EDIT: Some useful links I have come across:

Qt Virtual Keyboard in QQuickWidget

Resize qtvirtualkeyboard according to QObject

Qt Virtual Keyboard


Solution

  • Ok, so after another few days of all out war with the virtual keyboard, I have finally achieved the desired result.

    After finding this gem of a guide, it turns out that because the widget containing my QTableView and QtVirtualKeyboard was a QDialog that was being displayed using the exec() method, it meant that the window properties wouldn't allow the keyboard to modify my data. And while the solution proposed in the guide didn't resolve my problem, making my widget inherit QWidget did set me off along the path to getting it all working properly.

    I say this because once I changed my QDialog into a QWidget, I then had a console output error saying unknown:0 input method is not set every time I pressed a key.

    The solution to this was to remove the Qt:Dialog flag from my setWindowFlags() method. And maybe most importantly, set the focus policy of my QQuickWidget to NoFocus like so:

    // In constructor
    QUrl source(QML_FILE_PATH + "virtualkeyboard.qml");
    m_quickWidget->setSource(source);
    m_quickWidget->setAttribute(Qt::WA_AcceptTouchEvents);
    m_quickWidget->setFocusPolicy(Qt::NoFocus);
    ui->verticalLayout->addWidget(m_quickWidget);
    

    Hallelujah!! My QtVirtualKeyboard finally sends the clicked keys to my editable cell.

    Finally, to open the keyboard with a single click on a cell in my table, I'm sure there is a better solution than this, but i connected a slot to my QTableView's pressed signal and manually set the visibility of the input method:

    void ConfigWindow::on_tableView_pressed(const QModelIndex &index)
    {
        if ((index.column() == 0) || (index.column() == 1))
        {
            QApplication::inputMethod()->show();
        }
    }
    

    Hope this helps anyone having the same trouble as me with this powerful yet painfully under-documented plugin.