We can adapt SomcoKeyboard to your layouts and visual system or help you choose and integrate Qt Virtual Keyboard for more advanced input requirements.
Adding an on-screen keyboard to an embedded Qt application looks like a UI task. Draw several rows of keys, send the selected characters to a TextInput, and the feature is done.
That approach works until the product gains a second form, a password field, a numeric input, another language, or a scrollable screen. At that point, the keyboard has to follow focus, react to input hints, report its geometry, avoid covering the active field, and remain consistent across the application. It has become an input method, not a reusable grid of buttons.
Qt provides the official Qt Virtual Keyboard module for this job. It is a broad input framework with a reference QML frontend, multiple input methods, predictive text capabilities, handwriting integration, and support for scripts that require text composition. That breadth is valuable, but not every embedded product needs it.
For many embedded products, Qt Virtual Keyboard can be more than is actually needed. It is a comprehensive, feature-rich module, but that also comes with commercial licensing costs. SomcoKeyboard takes a more focused approach: it keeps Qt's input-method boundary, provides the keyboard UI in QML, and covers the vast majority of everyday product requirements while remaining easy to customize and completely free to use under MIT License.
This article is the introduction of our completely open-source virtual keyboard project.
One of the reasons why coding your own keyboard might take a lot of time to be equally usable as Qt Virtual keyboard is that a useful keyboard separates input integration from visual presentation.
The keyboard's backend side knows which object has focus, whether it accepts text input, what kind of content it expects, and whether the keyboard is visible. It also routes input back to the focused object. The presentation side (UI) draws keys, loads a language layout, displays alternative characters, and applies the product's visual style.
Qt exposes the application-facing part of this mechanism through `QInputMethod`. QML applications access the same state through Qt.inputMethod, including keyboard visibility and geometry. Text controls describe their expectations with `inputMethodHints`, such as Qt.ImhDigitsOnly, Qt.ImhDate, or Qt.ImhSensitiveData.
With this contract, a login screen does not need to tell the keyboard explicitly when to show a number pad. The input field declares what it accepts, and the active input method decides how to represent that requirement.
Application screens should describe input; the input method should own keyboard behavior. That's one of the many reasons good keyboard is not a half-day task.
Qt Virtual Keyboard is implemented as an input context plugin. Its framework supports multiple input methods and allows third-party input methods and layouts to be loaded at runtime. The module includes considerably more than an InputPanel.
According to the Qt Virtual Keyboard overview, its feature set includes predictive input, character previews, automatic capitalization, multiple character sets, right-to-left input, handwriting support, hardware-key navigation, and integration with both Qt Quick and Qt Widgets applications. Custom layouts and styles can be supplied without replacing the whole framework.
The official Qt module is the stronger choice when a product needs capabilities such as:
predictive text and candidate selection;
preedit and text composition for complex input methods;
Chinese, Japanese, or Korean input;
right-to-left layouts;
handwriting recognition;
one input framework shared by Qt Quick and Qt Widgets applications.
Qt Virtual Keyboard supports two deployment models. Desktop integration exposes the keyboard to Qt applications through a separate top-level window. Application integration embeds an InputPanel inside the application, which is the required model for many single-window embedded systems. The deployment guide describes both approaches.
The official module gives a team a mature, extensible input framework. The product also adopts the framework's architecture, deployment requirements, feature surface, and licensing model, even when it needs only a small subset.
Many embedded interfaces built with Qt and Linux have a more constrained input problem. A device may need a few European languages, a numeric layout, password entry, symbols, and branding consistent with the rest of its touchscreen UI. That's the case for most of Somco Software projects. It may never need predictive text, handwriting, or a composition engine.
This is the requirement profile behind SomcoKeyboard.
Out solution targets Qt Quick applications and divides the work into a C++ input context layer and a QML presentation layer:
VirtualKeyboardInputContext implements the platform input context. It tracks the focused QQuickItem, exposes keyboard visibility and geometry to Qt, and reads the focused item's input method queries. DeclarativeInputEngine holds the active input mode, language layout, shift state, symbol state, and capitalization setting. The QML layer owns the panel, individual keys, popups, themes, and layout files.
The boundary is intentionally narrow. QML does not search the object tree for whichever TextInput happens to be active, and application screens do not call keyboard-specific APIs for every field. Both sides communicate through Qt's input-method mechanism.
The implementation details below show how the input context, QML panel, input hints, focus handling, and presentation layer preserve that boundary in practice. The SomcoKeyboard repository includes a detailed README with practical instructions for setting up, integrating, and customizing the keyboard in your own Qt application.
The plugin has to be selected before QGuiApplication is created. In the example application, that requires one environment setting:
int main(int argc, char **argv)
{
qputenv("QT_IM_MODULE", QByteArray("somcokeyboard"));
QGuiApplication app(argc, argv);
// Load the QML application.
return app.exec();
} The value matches the key declared by SomcoKeyboard's platform input context plugin. The application then instantiates the QML panel:
import QtQuick
import QtQuick.SomcoKeyboard 1.0
InputPanel {
id: inputPanel
width: parent.width
y: Qt.inputMethod.visible
? parent.height - height
: parent.height
themeName: "defaultDark"
Behavior on y {
NumberAnimation {
duration: 300
easing.type: Easing.InOutQuad
}
}
} This is application integration: the product controls where the panel is rendered and how it enters or leaves the screen, while the input context controls whether Qt considers the keyboard visible.
SomcoKeyboard can be added with CMake through add_subdirectory(). Its current build configuration places the platform input context plugin next to the executable by default, under platforminputcontexts. It can also install the plugin into a custom plugin directory or into the Qt installation.
The most useful behavior in an embedded keyboard is often not visible in a screenshot. SomcoKeyboard reads Qt::ImHints whenever focus changes and chooses an input mode from the field's declared purpose.
The current implementation follows this decision:
const auto hints = Qt::InputMethodHints(focusItem->inputMethodQuery(Qt::ImHints).toInt());
if (hints & Qt::ImhDigitsOnly) {
inputEngine->setInputMode(DeclarativeInputEngine::DigitsOnly);
inputEngine->setSymbolMode(false);
} else if (hints & (Qt::ImhPreferNumbers |
Qt::ImhDate |
Qt::ImhTime |
Qt::ImhFormattedNumbersOnly)) {
inputEngine->setInputMode(DeclarativeInputEngine::Letters);
inputEngine->setSymbolMode(true);
} else {
inputEngine->setInputMode(DeclarativeInputEngine::Letters);
inputEngine->setSymbolMode(false);
} The snippet is simplified, but it preserves the actual decision boundary. Qt.ImhDigitsOnly receives a digits layout. Date, time, formatted-number, and preferred-number fields start with symbols. Regular fields receive the current language layout.
SomcoKeyboard covers the input modes commonly needed in embedded applications out of the box. If a product requires more specialized behavior, for example dedicated layouts for email addresses, URLs, dialable characters, or uppercase-only input. It can be added easily by extending the QML layout and input-hint handling. This keeps the default implementation lightweight while leaving room for product-specific customization.
Automatic capitalization is deliberately modest. When enabled, the current implementation suppresses it for Qt::ImhHiddenText and Qt::ImhSensitiveData fields, then raises shift for an empty field or after a period, exclamation mark, or question mark followed by a space. Automatic capitalization handles common sentence boundaries while remaining straightforward to adapt through the input-hint mapping when a product requires different behavior.
Hints guide the keyboard; they are not a substitute for validation. A field that must accept a specific format should still use an appropriate validator or input mask.
A bottom-aligned keyboard can cover the field the user is editing. Moving every screen manually would couple application layout code to a global input component.
SomcoKeyboard instead inspects the focused item's parent chain for a QQuickFlickable. If the field would sit below the visible area, the input context adjusts the flickable's contentY; it also scrolls back when the focused item is above the viewport. The adjustment waits until the keyboard animation settles, preventing two layout movements from competing with each other.
This is a small implementation detail with a large architectural consequence. Screens can remain responsible for their content, while the input method handles the space it occupies.
The same principle applies to hiding the panel. When the keyboard closes, SomcoKeyboard clears focus from an active input item to keep the visual state consistent. If a focused item becomes invisible, the panel is hidden as well.
SomcoKeyboard ships with defaultLight and defaultDark themes. A KeyboardTheme contains colors, typography, corner styling, and icon paths, while ThemeManager exposes the active theme to QML controls.
Product teams can supply their own theme objects:
InputPanel {
themeName: "deviceTheme"
themes: [
KeyboardTheme {
themeName: "deviceTheme"
backgroundColor: "#182028"
btnBackgroundColor: "#273440"
btnTextColor: "#ffffff"
}
]
} When an application provides custom themes, it explicitly controls which themes are available. Built-in themes are not added automatically, allowing the product to expose only the visual variants intended for its UI.
The current repository defines 21 language variants across Latin, Cyrillic, and Greek scripts, as summarized in the table below. Some variants share the same physical QML layout. Bosnian, Croatian, and Serbian variants, for example, can reuse the same key arrangement while still presenting the appropriate language name. Digits and symbols are kept as separate layouts rather than duplicated inside every locale file.
Language Name | Language Code | Layout File |
|---|---|---|
Bosnian (Cyrillic) | CyBs | CySrBsLayout.qml |
Bosnian (Latin) | LtBs | LtSrHrBsLayout.qml |
Croatian | Hr | LtSrHrBsLayout.qml |
Czech | Cs | CsLayout.qml |
Danish | Da | DaLayout.qml |
Dutch | Nl | NlLayout.qml |
English | En | EnLayout.qml |
Finnish | Fi | FiLayout.qml |
French | Fr | FrLayout.qml |
German | De | DeLayout.qml |
Greek | El | ElLayout.qml |
Italian | It | ItLayout.qml |
Polish | Pl | PlLayout.qml |
Portuguese | Pt | PtLayout.qml |
Russian | Ru | RuLayout.qml |
Serbian (Cyrillic) | CySr | CySrBsLayout.qml |
Serbian (Latin) | LtSr | LtSrHrBsLayout.qml |
Spanish | Es | EsLayout.qml |
Swedish | Sv | SvLayout.qml |
Turkish | Tr | TrLayout.qml |
Ukrainian | Uk | UkLayout.qml |
Alternative characters are defined next to their base keys. A long press opens a QML popup, allowing a compact layout to expose diacritics without adding another permanent row.
Requirement | Qt Virtual Keyboard | SomcoKeyboard |
|---|---|---|
License | Commercial or GPLv3 | MIT |
Cost for proprietary use | Paid commercial license or GPLv3 | Free |
Customizable | Yes | Yes |
Multiple language support | Yes | Yes |
Custom keyboard layouts | Yes | Yes |
Custom themes / styling | Yes | Yes |
Qt Quick support | Yes | Yes |
Input method integration | Yes | Yes |
Numeric input support | Yes | Yes |
Symbol input support | Yes | Yes |
Input method hints support | Yes | Yes |
Automatic capitalization | Yes | Yes |
Current script coverage | Broad, including CJK and right-to-left languages | Latin, Cyrillic, and Greek layouts |
Predictive input and candidate lists | Supported | Not implemented |
Preedit and complex text composition | Supported | Not implemented |
Handwriting support | Supported | Not implemented |
Third-party input engines | Supported | Not implemented |
Qt Widgets | Supported | Current focus handling requires QQuickItem |
The current Qt documentation states that Qt Virtual Keyboard is available under commercial licenses and GPLv3. SomcoKeyboard's own source code is MIT-licensed. That does not turn the complete application stack into an MIT-licensed product: teams still need to review the licenses and obligations of the Qt modules and other software they distribute. This is an engineering comparison, not legal advice.
Choose Qt Virtual Keyboard when the product needs a full input framework: predictive text, complex composition, handwriting, broad language coverage, Qt Widgets integration, or vendor input engines.
Consider a focused input context such as SomcoKeyboard when the product uses Qt Quick and its requirements are deliberately narrower: controlled European language layouts, numeric and symbol modes, product-specific theming, alternative characters, and predictable application-level integration.
The decision should be made early. Keyboard architecture affects field definitions, focus behavior, screen layout, deployment, licensing, localization, testing, and future language support. Treating it as a cosmetic component postpones those decisions; it does not remove them.
SomcoKeyboard is our public, reusable foundation for embedded Qt Quick products that need a focused input-method solution. Its source code, example application, themes, and layouts are available in the SomcoKeyboard GitHub repository. It provides a clear input-method boundary while keeping the implementation lightweight, customizable, and well suited to products that do not require the full scope of a comprehensive text-input framework.
That distinction matters. The best virtual keyboard is not the one with the longest feature list. It is the one whose input model, language coverage, maintenance cost, and licensing fit the device being built.
CEO, Somco Software
Write a few sentences about your project and it lands directly in my inbox. I usually answer within one business day, and when it's a fit, we can get started in as little as two weeks.
Connect with me on LinkedIn