Customising Qt Virtual Keyboard QML for a cross-compiled, remote device
-
wrote on 12 Mar 2022, 02:47 last edited by
I have an Embedded Linux device, for which I use a cross-compilation toolchain to build and deploy my Qt application to the device on an Ubuntu workstation. I've included the Virtual Keyboard module when building the Embedded Linux device's Qt installation, as well as its corresponding SDK/toolchain for Ubuntu. The Virtual Keyboard works as expected; i.e. if I have an InputPanel in a QML file, the Virtual Keyboard appears as exepcted.
What I'm now trying to do is setup my own style.qml to customise the appearance of the Virtual Keyboard. I've been through the documents, as well as this very informative thread, and feel like I have a reasonable comprehension as to how the customisation is supposed to take place.
With that said, the documentation and the linked thread pertain to the process required when compiling natively; it doesn't address how to setup a custom style when cross-compiling for a remote target.
I.e. adding the path of the custom style (i.e. .../QtQuick/VirtualKeyboard/Styles/[MY_STYLE]" to the QQmlApplicationEngine (engine.addImportPath()) will add a path relative to the remote device, which doesn't have a QML file/directory structure. How can the Virtual Keyboard custom QML process be executed within a cross-compilation environment? The custom style.qml file (and its associated path) should be registered on the Ubuntu workstation, with the resulting code deployed to the remote device (as per normal).
Any clarification or guidance would be greatly appreciated!
-
wrote on 12 Mar 2022, 06:46 last edited by jars121 3 Dec 2022, 06:47
Bit of an update on this as I continue to explore, hopefully it helps someone facing a similar challenge in the future.
As per my original post above, I'm fairly comfortable with the general process for specifying a custom style and layout when compiling natively. I've confirmed this by establishing the required style.qml directory structure on the remote Embedded Linux device, and then selecting the custom style at runtime in my QML file.
I've done this using the following steps:
- Identified the QML import paths used by the QQmlApplicationEngine with engine.importPathList().
- I created a QtQuick/VirtualKeyboard/Styles/myCustomStyle directory within one of the existing/default QML import paths on the Embedded Linux device.
- In my InputPanel in my QML file, I select my custom style within the Component.onCompleted() function with VirtualKeyboardSettings.styleName = "myCustomStyle"
The above process works as expected; the Virtual Keyboard is shown, and the style used is my custom style (per the style.qml file in the QtQuick/VirtualKeyboard/Styles/myCustomStyle path). I've done something similar with custom Layouts, and used the QT_VIRTUALKEYBOARD_LAYOUT_PATH environment variable to specify the custom Layout path.
While the above solution does allow me to build the custom Layouts and styles required, it's not the solution I'm looking for, as I have to edit the files on the Ubuntu workstation and then transfer them to the remote device. I'm hoping there's a way to instead incorporate the files/directories into compilation process on the workstation, rather than them being found and loaded at runtime on the device.
-
wrote on 15 Mar 2022, 14:35 last edited by lemons
I am not quite sure if I get your issue.
Here is the way I did it in a previous project, which worked as expected:- I copied the entire QtQuick/VirtualKeyboard directory into my QML directory
(qrc:/components/keyboard/QtQuick/VirtualKeyboard/...)
- [QMLROOT]/
---- components/
-------- keyboard/
------------ QtQuick/VirtualKeyboard/
---------------- images/
---------------- layouts/
---------------- Styles/
---------------- HandwritingInputPanel.qml
---------------- InputPanel.qml
------------ Keyboard.qml
---- main.qml
- Inside this directory there is a "Styles" directory, in which I created a new directory with the name of my keyboard style
- [QMLROOT]/components/keyboard/
---- QtQuick/VirtualKeyboard/
-------- Styles/
------------ MyStyleName/
---------------- style.qml
-
I copied the style.qml from an other style and modified it for my requirements
-
In main.cpp I added the following 3 lines:
engine.addImportPath("qrc:/components/keyboard"); // compare to directory structure of step 1 qputenv("QT_VIRTUALKEYBOARD_STYLE", "MyStyleName"); // name of directory from step 2 qputenv("QT_VIRTUALKEYBOARD_LAYOUT_PATH", "qrc:/components/keyboard/QtQuick/VirtualKeyboard/layouts");
- add import path to main.qml and place Keyboard
// main.qml import "./components/keyboard" ApplicationWindow { //... Keyboard { id: virtualKeyboard } }
// [QMLROOT]/components/keyboard/Keyboard.qml // ... import QtQuick.VirtualKeyboard 2.1 import QtQuick.VirtualKeyboard.Styles 2.1 import QtQuick.VirtualKeyboard.Settings 2.1 Item { id: container anchors.fill: parent property bool active: keyboard.active InputPanel { id: keyboard y: container.height anchors.left: parent.left anchors.right: parent.right states: State { name: "visible" when: keyboard.active PropertyChanges { target: keyboard y: container.height - keyboard.height } } transitions: Transition { from: "" to: "visible" reversible: true ParallelAnimation { NumberAnimation { properties: "y" duration: 250 easing.type: Easing.InOutQuad } } } } }
The steps you anyhow already completed:
// main.cpp int main(int argc, char *argv[]) { qputenv("QT_IM_MODULE", QByteArray("qtvirtualkeyboard")); // ... }
// myApplication.pro static { QT += svg QTPLUGIN += qtvirtualkeyboardplugin }
- I copied the entire QtQuick/VirtualKeyboard directory into my QML directory
-
wrote on 17 Mar 2022, 01:04 last edited by
Thank you very much @lemons , your response is greatly appreciated, and I'm sure it'll assist others in the future.
Is your setup based on a Qt deployment for a remote device? I've implemented the approach you've outlined above, and I come across the same issue: the environment variables set in main.cpp set a QML path on the remote device, which doesn't have QRC files on it. If I replicate the hierarchy on the remove device then everything works as expected, but establishing the hierarchy within my Qt Creator structure doesn't work as the runtime QML paths are on the build machine not the remote target.
-
wrote on 17 Mar 2022, 06:20 last edited by
my setup was used on an embedded yocto project.
the requirements for it to work:
- add virtualkeyboard to the remote-image. for yocto add : qtvirtualkeyboard (included in the meta-qt5 layer) to local.conf
IMAGE_INSTALL_append = " qtvirtualkeyboard \
-
make sure everything is updated accordingly
-> rebuild toolchain
-> rebuild remote-image
-> install latest image on embedded device -
make sure to build your project with the remote-toolchain
-> e.g. source it before launching qtcreator from command line
-
-
3/5