2

I'm creating a Qt Widgets application and deploying it on Windows 11 tablet.

Currently, when I click on a QLineEdit, the Windows 11 integrated virtual keyboard appears and I can edit the text. But, when it's a QSpinBox, the keyboard does not appear.

My app must be in full screen and does not allow access to the virtual keyboard shortcut in the taskbar:

virtual keyboard shortcut

I have tried :

  • QProxyStyle to the QSpinBox

  • Re-implementing some QEvent feature to force the call with QEvent e(QEvent::RequestSoftwareInputPanel);

    bool event(QEvent *event) override
    {
        if (QEvent::InputMethodQuery == event->type())
        {
            QEvent e(QEvent::RequestSoftwareInputPanel);
            return QApplication::sendEvent(qApp, &e);
        }
        return QSpinBox::event(event);
    }
    
  • QInputMethod

    setInputMethodHints(Qt::ImhDigitsOnly);
    
  • Reading QLineEdit source code.

Here is my demo to implement this functionality:

Clicking on QLineEdit

Clicking on QLineEdit calls the virtual keyboard:

Clicking on QSPinBox

Clicking on QSpinbox calls nothing.

Qt version is 6.5.0.

All the sources:

touchscreen.pro

QT       += core gui

greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

CONFIG += c++17

# You can make your code fail to compile if it uses deprecated APIs.
# In order to do so, uncomment the following line.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0

SOURCES += \
    main.cpp \
    mainwindow.cpp

HEADERS += \
    custom.h \
    mainwindow.h

FORMS += \
    mainwindow.ui

# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target

custom.h

#ifndef CUSTOM_H
#define CUSTOM_H


#include <QSpinBox>
#include <QFocusEvent>

#include <QApplication>


class Custom : public QSpinBox
{
    Q_OBJECT

public:
    Custom(QWidget* parent = 0) :
        QSpinBox(parent)
    {
    }

    void focusInEvent(QFocusEvent *event) override
    {
        qDebug() << event;

        QSpinBox::focusInEvent(event);
        QGuiApplication::inputMethod()->show();
    }
};

#endif // CUSTOM_H

mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>



QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE

class MainWindow : public QMainWindow

{
    Q_OBJECT

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

private:
    Ui::MainWindow *ui;
};

#endif // MAINWINDOW_H

main.cpp

#include "mainwindow.h"
#include <QApplication>


int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MainWindow w;
    w.show();
    return a.exec();
}

mainwindow.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"

#include <QProcess>


MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
}

MainWindow::~MainWindow()
{
    delete ui;
}

mainwindow.ui

<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
 <class>MainWindow</class>
 <widget class="QMainWindow" name="MainWindow">
  <property name="geometry">
   <rect>
    <x>0</x>
    <y>0</y>
    <width>800</width>
    <height>600</height>
   </rect>
  </property>
  <property name="windowTitle">
   <string>MainWindow</string>
  </property>
  <widget class="QWidget" name="centralwidget">
   <layout class="QGridLayout" name="gridLayout">
    <item row="1" column="1">
     <widget class="QLineEdit" name="lineEdit_2">
      <property name="readOnly">
       <bool>true</bool>
      </property>
     </widget>
    </item>
    <item row="1" column="0">
     <widget class="QLineEdit" name="lineEdit"/>
    </item>
    <item row="0" column="0">
     <widget class="Custom" name="spinBox"/>
    </item>
   </layout>
  </widget>
  <widget class="QMenuBar" name="menubar">
   <property name="geometry">
    <rect>
     <x>0</x>
     <y>0</y>
     <width>800</width>
     <height>21</height>
    </rect>
   </property>
  </widget>
  <widget class="QStatusBar" name="statusbar"/>
 </widget>
 <customwidgets>
  <customwidget>
   <class>Custom</class>
   <extends>QSpinBox</extends>
   <header>custom.h</header>
  </customwidget>
 </customwidgets>
 <resources/>
 <connections/>
</ui>

1 Answer 1

0

This seems to me to be a Qt bug. Reporting it through the official Qt Bug Report system may be appropriate.

As a work-around, I would try the following:

void focusInEvent(QFocusEvent *event) override
{
    QSpinBox::focusInEvent(event);
    QGuiApplication::instance()->inputMethod()->show();
}

Note that I have not tested this approach, as I have no Windows 11 tablet at hand.

8
  • Thank for your reply. I have tested with QGuiApplication::inputMethod()->show(); in void focusInEvent(QFocusEvent *event) override but nothing appears either Commented Jul 10 at 14:00
  • 1
    @user26304607 Where did you implement it, and did you properly call the focusInEvent() of the base class? Note that spinboxes are a bit peculiar: they use an internal QLineEdit that uses the spinbox as its focus proxy, and then they programmatically send some events to that line edit (specifically, focus and keyboard events), which makes things quite weird to manage. Commented Jul 10 at 15:41
  • @user26304607 Have you checked the function is actually called?
    – m7913d
    Commented Jul 10 at 16:35
  • Thanks for your reply. Yes I checked that the function void focusInEvent(QFocusEvent *event) override is called. I juste added my source file in the initial question. Commented Jul 11 at 11:07
  • 1
    I just report the bug, it can be see here: bugreports.qt.io/browse/QTBUG-127124 Commented Jul 12 at 12:27

Not the answer you're looking for? Browse other questions tagged or ask your own question.