I want to create a onscreen keyboard for a desktop application. The application will be built in Qt 5. I have couple of questions, please clarify them.
What is the replacement of QInputContext in Qt5? (Because I read somewhere about onscreen keybord by implementing QInputContext but this is not supported by Qt 5.)
Where can I find QPlatformInputContext and QInputPanel (on an internet search I found these two as alternatives of QInputContext but not sure about that and also I was unable to find them)?
My requirements:
Keyboard will not use QML or any external library (already build other keyboards).
Keyboard will use Qt Gui (traditional).
I understand there are two challenges you would have:
Getting notified as to when to show/hide the on-screen keyboard, based on the focus being on text widgets
How to post key-press event to the text widgets
ANSWER
As for the former, you could use QObject::InstallEventFilter() on widgets that you want to provide the keyboard service to. You can then look for the mouseReleaseEvent along the lines of the Qt code in the link.
This can be achieved by using QCoreApplication::postEvent()
As for QPlatformInputContext, get the example of a Qt Virtual Keyboard here.
I took me quite a while to find out how to do this in QT5 without qml and too much work. So thought I'd share:
#include <QCoreApplication>
#include <QGuiApplication>
#include <QKeyEvent>
void MainWindow::on_pushButton_clicked()
{
Qt::Key key = Qt::Key_1;;
QKeyEvent pressEvent = QKeyEvent(QEvent::KeyPress, key, Qt::NoModifier, QKeySequence(key).toString());
QKeyEvent releaseEvent = QKeyEvent(QEvent::KeyRelease, key, Qt::NoModifier);
QCoreApplication::sendEvent(QGuiApplication::focusObject(), &pressEvent);
QCoreApplication::sendEvent(QGuiApplication::focusObject(), &releaseEvent);
}
The clue here is that by clicking buttons (if you would manually make your keyboard), launches a sendevent to the current object thas has focus (for example a textbox). You could of course hardcode a textbox, but that only works if you have only a single input to use your keyboard for.
The last thing you have to make sure, is to set the focusPolicy of your keyboard buttons to NoFocus, to prevent focus from shifting when the keyboard is pressed.
Credits go to https://www.wisol.ch/w/articles/2015-07-26-virtual-keyboard-qt/
Hope this helps someone.
A good example is given in here http://tolszak-dev.blogspot.com.tr/2013/04/qplatforminputcontext-and-virtual.html
uses Qt Quick for on screen keyboard.
You can check it.
I just got this working in my awesome Qt app. Here is how I did it.
For Android and iOS:
QObject::connect(lineEdit, SIGNAL(returnPressed()), qApp->inputMethod(), SLOT(hide()));
For iOS:
Subclass QLineEdit and add the following:
void focusOutEvent(QFocusEvent * fe)
{
QLineEdit::focusOutEvent(fe);
#ifdef Q_OS_IOS
if(fe->reason() == Qt::OtherFocusReason)
{
// Done was pressed!
emit returnPressed();
}
#endif
}
Btw, the QInputMethod docs don't say much about how to access it from c++. You have to get an instance from QGuiApplication, like I did above.
Hope that helps.
Qt now provides a virtual keyboard framework in Qt 5.5.
http://doc.qt.io/QtVirtualKeyboard/
I have not tried it, so I can't say how easy it is to use. It looks like it's QML-based.
(It says it's for Linux and boot2qt, but it can also be built for Windows according to the building page (http://doc.qt.io/QtVirtualKeyboard/build.html))
Related
I'm using Qt5 on windows.
Is there a way to distinguish whether a Qt widget got focus from mouse clicking or from table key pressing?
Yes, there is. Override QWidget::focusInEvent and use the QFocusEvent::reason method of the focus event to get the reason!
Simple sample:
void MyWidget::focusInEvent(QFocusEvent *event) {
qDebug() << event->reason();
QWidget::focusInEvent(event);
}
Note: In case you want to get this information from an already existing widget, you can always install an event filter instead. See https://doc.qt.io/qt-5/qobject.html#installEventFilter for an example on how do do that.
I want to save the focused window's title, i made this part but i dont know is there any QEvent which catches all (non-application) focusChanged event? Like switching from Chrome to Qt Creator. I made an alternative solution that checks in every second if the topmost window title has changed but this is so rude. I need cross-platform solution if possible.
EDIT
I am using QT 5.9.0
Quick answer:
Qt only has focus events for it's own windows and widgets. See http://doc.qt.io/qt-5/qfocusevent.html#details for start point.
There is no event for focus in other applications.
Details:
For multi-platform solution is needed to have more general point of view. On some (X window) systems where keyboard focus is in window under mouse. But that window becomes topmost only after click. On Mobile platforms there is only one active application. And application is not allowed seeing when other applications are activated. So in my understanding there is no full multi-platform solution.
Windows only extensions are in the Qt Windows Extras. http://doc.qt.io/qt-5/qtwinextras-overview.html. But there is nothing focus change related unfortunately.
I'm learning and messing around in Qt with Widget application and I made some QPushButtons that do some straight forward actions, but as you would expect only when you click them with mouse, how can you make it work that way, that a specific keyboard press event does that same work as clicking that button? I couldn't get much from online tutorials as I don't even know how to specify what am I looking for. Thanks
use QShortcut or create derived class from QPushButton and re-implement QKeyPressEvent method
I am writing small c++ application using QT creator and i have a problem, I want to get selecting text from any application, I am using to this QClipboard library (SIGNAL(selectionChanged())), but it doesn't work properly admittedly i am getting selected text, but only after I release a mouse button. I would like to get selected text in "real time" without mouse button up. Is there any simple way to do it?
first you need to add this header file: QClipboard
then...
connect(qApp->clipboard, SIGNAL(selectionChanged), this, SLOT(your_slot()));
void your_slot() {
QClipboard *clipboard = QApplication::clipboard();
clipboard->setText(qApp->clipboard->text());
}
http://doc.qt.io/qt-5/qclipboard.html#selectionChanged
It looks like that is only supported well on X11, like Linux.
If you are interested in tracking mouse selections in your program in realtime, you can look directly at the mouse events or keyboard events, or the Rich Text Processing framework (QTextCursor).
You could also send a copy call while the mouse is down on a timer, and then look at the dataChanged signal.
Hope that helps.
My application is an OS lock screen (like GDM's lock screen or KDE's), so I'm trying to make it function like one.
I am trying to make my application's window hover above all other windows and disable/intercept all keyboard shortcuts (ALT-TAB, CTRL-ALT-D, etc.) that would cause it disappear.
Is there any way to do this? I'm 100% sure there is, as lock screens with GUIs exist, but I just can't find the place to look...
I don't know how to do it with Qt, but what you are looking for is called grabbing. You can grab the pointer input device as well as the keyboard.
Edit: Looking in to the Qt4 docs, have you tried to use QWidget::grabMouse? It looks like this function does exactly what you want.
I don't know if this is the best solution, but you can try an event handler using QObject::installEventFilter().
If you are using Windows, you can install an event filter that handles messages where event->type() == QEvent::WinEventAct.
I don't really know much about other OSs, but Qt probably has something for that too.
inherit Qwidget class with parameter Qt::WindowStaysOnTopHint see below
myclass::myclass(QWidget *parent) : QWidget(parent,Qt::WindowStaysOnTopHint)