Written by Bo Thorsen
2015/06/30
I have a pet project where I’m doing some fun stuff with Qt scripting. To quickly test small script things, I implemented a simple window that have a QPlainTextEdit where I input a script, and an output window for what the script returns. And of course a QPushButton I can push to have the script evaluated.
Switching to use the mouse to press the eval button is obviously completely unacceptable, so I had a standard keyboard shortcut on the eval button. However, it seems more and more “standard” to use Ctrl+Return in text edits when the edit is done and should be handled, so I found myself pressing this a couple of times.
Implementing this for QPlainTextEdit can be done in many ways. One would be to subclass it and handle the keyboard events directly. If you have to subclass it anyway, that’s a nice option. But in this case, the UI was done in designer and I wasn’t already subclassing it.
Another way would be to create an eventFilter. This is of course one of those “if you only have a hammer, all problems are just nails”. Event filters are so easy to use, very powerful and able to do the trick, and one of the biggest hammers you’ll find in Qt. In this case, I would implement a class like this:
class CtrlEnterKeyPressFilter : public QObject {
public:
CtrlEnterKeyPressFilter(QWidget* widget, QPushButton* button)
: QObject(widget), mButton(button)
{
widget->installEventFilter(this);
}
protected:
bool eventFilter(QObject*, QEvent* event) {
if ((event->type() == QEvent::KeyPress
|| event->type() == QEvent::KeyRelease) && mButton)
{
// This might be one for us
QKeyEvent *keyEvent = static_cast(event);
if (keyEvent->key() == Qt::Key_Return &&
keyEvent->modifiers() == Qt::ControlModifier)
{
// Ctrl + return pressed
if (event->type() == QEvent::KeyRelease) {
mButton->click();
}
// This event has been handled
return true;
}
}
return false;
}
private:
QPointer mButton;
};
However, my favourite way to implement this is to use a QAction and set a keyboard shortcut on that:
QAction* action = new QAction(d->ui.input);
action->setAutoRepeat(false);
action->setShortcut(tr("Ctrl+Return"));
connect(action, SIGNAL(triggered()), d->ui.eval, SLOT(click()));
d->ui.input->addAction(action);
This is a simple and clean solution that does the trick for you.