Question

What I want
I made onscreen keyboard using simple QPushButtons and QFrame. What I want, when a input widget (QLineEdit, QTextEdit, QPlainText, QSpinBox) is in focus my onscreen keyboard will show and when no input widget is in focus, my keyboard will automatically hide.

What should I do for this?

My Approch
I extends separate class for each of QLineEdit., QTextEdit, QPlainEdit, QSpinBox. Then I implemented keyboard show/hide on their focusIn and focusOut event. But it cause a problem.

Problem
When there are two Input widget on form, and when I click on first widget keyboard will come up (that is fine). When I click on second input widget keyboard hides due to focusOut of first input widget (THIS IS PROBLEM).

I have to proceed with this approach. What should I do for this?

Was it helpful?

Solution

It would help if you'd shown some code for how you've gone about your solution, so excuse me if I'm describing what you're already doing.

Each of the classes that you've extended is a QWidget, which inherits QObject. A useful feature of QObject is the ability to install an event filter. This is an object that will receive events before the object it is installed on and can choose to handle those events, or pass them to the original object.

If you're only extending the input widgets to handle showing and disabling the keyboard events, I suggest you change that to use the event handler.

Here's an example of how to create one: -

class MyEventHandler : public QObject
{
    Q_OBJECT

    public:
         MyEventHandler(QObject* parent);

    protected:
         bool eventFilter(QObject *obj, QEvent *event);
};

bool MyEventHandler::eventFilter(QObject *obj, QEvent *event)
{
    if(event->type == QEvent::FocusAboutToChange) // May need QEvent::FocusIn or QEvent::FocusOut
    {
        // handle on-screen keyboard
    }
}

Then you can use the same event filter for each input widget; for example a QLineEdit and a QSpinBox: -

MyEventHandler* theEventHandler = new MyEventHandler(this);
lineEdit->installEventFilter(theEventHandler);
spinBox->installEventFilter(theEventHandler);

As both input widgets use the same event handler, it can also be used to store the status of the keyboard; either displayed or hidden. If you add a timer to the focusOut and the focusIn is not called within a short time, you know that the input widgets have lost focus and you can hide the keyboard. If focusIn is called before the timer expires, another input widget has focus, so just stop the timer and there's no need to hide the keyboard.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top