I have a QDockWidget in my Mainwindow with a QTableWidget and two QPushbuttons.
Of course, I can click the buttons with my mouse, but I want also to "click" them with left- and right-arrow-key.
It nearly works perfect. But before they are clicked via key, it seems like the focus jumps to the right/left of the QTableWidget (the items in it, it goes through all columns).
Is it possible that I have the KeyPressEvents only for the buttons in the QDockWidget?
You can use an event filter like this:
class Filter : public QObject
{
public:
bool eventFilter(QObject * o, QEvent * e)
{
if(e->type() == QEvent::KeyPress)
{
QKeyEvent * event = static_cast<QKeyEvent *>(e);
if((event->key() == Qt::Key_Left) || (event->key() == Qt::Key_Right))
{
//do what you want ...
return true;
}
}
return QObject::eventFilter(o, e);
}
};
keep an instance of the filter class in your main window class:
private:
Filter filter;
then install it in your widgets, e.g. in your main window class constructor:
//...
installEventFilter(&filter); //in the main window itself
ui->dockWidget->installEventFilter(&filter);
ui->tableWidget->installEventFilter(&filter);
ui->pushButton->installEventFilter(&filter);
//etc ...
You may want to check for modifiers (e.g. Ctrl key), to preserve the standard behaviour of the arrow keys:
//...
if(event->modifiers() == Qt::CTRL) //Ctrl key is also pressed
{
if((event->key() == Qt::Key_Left) || (event->key() == Qt::Key_Right))
{
//...
Related
Something is fundamentally wrong with my eventFilter, as it lets every single event through, while I want to stop everything. I've read lots of documentation on QEvent, eventFilter() and so on, but obviously I'm missing something big. Essentially, I'm trying to create my own modal-functionality for my popup-window class based on QDialog. I want to implement my own since the built-in setModal(true) includes a lot of features, e.g. playing QApplication::Beep(), that I want to exclude. Basically, I want to discard all events going to the QWidget (window) that created my popup. What I have so far is,
// popupdialog.h
#ifndef POPUPDIALOG_H
#define POPUPDIALOG_H
#include <QDialog>
#include <QString>
namespace Ui {class PopupDialog;}
class PopupDialog : public QDialog
{
Q_OBJECT
public:
explicit PopupDialog(QWidget *window=0, QString messageText="");
~PopupDialog();
private:
Ui::PopupDialog *ui;
QString messageText;
QWidget window; // the window that caused/created the popup
void mouseReleaseEvent(QMouseEvent*); // popup closes when clicked on
bool eventFilter(QObject *, QEvent*);
};
...
// popupdialog.cpp
#include "popupdialog.h"
#include "ui_popupdialog.h"
PopupDialog::PopupDialog(QWidget *window, QString messageText) :
QDialog(NULL), // parentless
ui(new Ui::PopupDialog),
messageText(messageText),
window(window)
{
ui->setupUi(this);
setAttribute(Qt::WA_DeleteOnClose, true); // Prevents memory leak
setWindowFlags(Qt::Window | Qt::FramelessWindowHint);
ui->message_text_display->setText(messageText);
window->installEventFilter(this);
//this->installEventFilter(window); // tried this also, just to be sure ..
}
PopupDialog::~PopupDialog()
{
window->removeEventFilter(this);
delete ui;
}
// popup closes when clicked on
void PopupDialog::mouseReleaseEvent(QMouseEvent *e)
{
close();
}
Here's the problem, the filter doesn't work. Note that if I write a std::cout
inside the if(...), I see that it does trigger whenever events are sent to window, it just doesn't stop them.
bool PopupDialog::eventFilter(QObject *obj, QEvent *e)
{
if( obj == window )
return true; //should discard the signal (?)
else
return false; // I tried setting this to 'true' also without success
}
When the user interacts with the main program, a PopupDialog can be created like this:
PopupDialog *popup_msg = new PopupDialog(ptr_to_source_window, "some text message");
popup_msg->show();
// I understand that naming the source 'window' might be a little confusing.
// I apologise for that. The source can in fact be any 'QWidget'.
Everything else works as expected. Only the event filter fails. I want the filter to remove events sent to the window that created the popup; like mouse clicking and key pressing, until the popup is closed. I'm expecting to be extremely embarrassed when someone points out a trivial fix in my code.
You have to ignore all events that arrive in the widget tree of the window. Therefore, you need to install the eventFilter application-wide and check, if the object you are filtering on is a descendant of window. In other words: Replace
window->installEventFilter(this);
by
QCoreApplication::instance()->installEventFilter(this);
and implement the event filter function this way:
bool PopupDialog::eventFilter(QObject *obj, QEvent *e)
{
if ( !dynamic_cast<QInputEvent*>( event ) )
return false;
while ( obj != NULL )
{
if( obj == window )
return true;
obj = obj->parent();
}
return false;
}
I tried it, tested it and it worked for me.
Note: Using event filters in Qt is a bit messy in my experience, since it is not quite transparent what is happening. Expect bugs to pop up from time to time. You may consider disabling the main window instead, if you and your clients don't have a problem with the grayed-out main window as a consequence.
After the massive amount of responses, feedback, suggestions and time ivested in extensive research I've finally found what I believe to be the optimal, and safest solution. I wish to express my sincere gratidtude to everyone for their aid to what Kuba Ober describes as "(...) not as simple of a problem as you think".
We want to filter out all certain events from a widget, including its children. This is difficult, because events may be caught in the childrens default eventfilters and responded to, before they are caught and filtered by the the parent's custom filter for which the programmer implements. The following code solves this problem by installing the filter on all children upon their creation. This example assumes the use of Qt Creator UI-forms and is based on the following blog post: How to install eventfilters for all children.
// The widget class (based on QMainWindow, but could be anything) for
// which you want to install the event filter on, includings its children
class WidgetClassToBeFiltered : public QMainWindow
{
Q_OBJECT
public:
explicit WidgetClassToBeFiltered(QWidget *parent = 0);
~WidgetClassToBeFiltered();
private:
bool eventFilter(QObject*, QEvent*);
Ui::WidgetClassToBeFiltered *ui;
};
...
WidgetClassToBeFiltered::WidgetClassToBeFiltered(QWidget *parent) :
QMainWindow(parent), // Base Class constructor
ui(new Ui::WidgetClassToBeFiltered)
{
installEventFilter(this); // install filter BEFORE setupUI.
ui->setupUi(this);
}
...
bool WidgetClassToBeFiltered::eventFilter(QObject *obj, QEvent* e)
{
if( e->type() == QEvent::ChildAdded ) // install eventfilter on children
{
QChildEvent *ce = static_cast<QChildEvent*>(e);
ce->child()->installEventFilter(this);
}
else if( e->type() == QEvent::ChildRemoved ) // remove eventfilter from children
{
QChildEvent *ce = static_cast<QChildEvent*>(e);
ce->child()->removeEventFilter(this);
}
else if( (e->type() == QEvent::MouseButtonRelease) ) // e.g. filter out Mouse Buttons Relases
{
// do whatever ..
return true; // filter these events out
}
return QWidget::eventFilter( obj, e ); // apply default filter
}
Note that this works, because the eventfilter installs itself on added children! Hence, it should also work without the use of UI-forms.
Refer this code to filter out specific event:-
class MainWindow : public QMainWindow
{
public:
MainWindow();
protected:
bool eventFilter(QObject *obj, QEvent *ev);
private:
QTextEdit *textEdit;
};
MainWindow::MainWindow()
{
textEdit = new QTextEdit;
setCentralWidget(textEdit);
textEdit->installEventFilter(this);
}
bool MainWindow::eventFilter(QObject *obj, QEvent *event)
{
if (obj == textEdit) {
if (event->type() == QEvent::KeyPress) {
QKeyEvent *keyEvent = static_cast<QKeyEvent*>(event);
qDebug() << "Ate key press" << keyEvent->key();
return true;
} else {
return false;
}
} else {
// pass the event on to the parent class
return QMainWindow::eventFilter(obj, event);
}
}
If you want to set more specific event filter on multiple widgets you can refer following code:
class KeyPressEater : public QObject
{
Q_OBJECT
protected:
bool eventFilter(QObject *obj, QEvent *event);
};
bool KeyPressEater::eventFilter(QObject *obj, QEvent *event)
{
if (event->type() == QEvent::KeyPress) {
QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event);
qDebug("Ate key press %d", keyEvent->key());
return true;
} else {
// standard event processing
return QObject::eventFilter(obj, event);
}
}
KeyPressEater *keyPressEater = new KeyPressEater(this);
QPushButton *pushButton = new QPushButton(this);
pushButton->installEventFilter(keyPressEater);
I have a QTableView and i wanted the user to be able to select a whole row rather than individual cell. So i changed the selection behavior as shown below.
table->setSelectionBehavior(QAbstractItemView::SelectRows)
But now when the tab key is clicked it still walks through individual cells rather than whole row. I want the user to be able to walk through each row rather individual cells.
You must inherit from QTableView class and override keyPressEvent(). For example:
#include <QTableView>
#include <QKeyEvent>
class CustomView : public QTableView
{
Q_OBJECT
// QWidget interface
protected:
void keyPressEvent(QKeyEvent *event) {
switch(event->key()) {
case Qt::Key_Tab: {
if(currentIndex().row() != model()->rowCount())
selectRow(currentIndex().row() + 1);
break;
}
default: QTableView::keyPressEvent(event);
}
}
public:
explicit CustomView(QWidget *parent = 0);
~CustomView(){}
signals:
public slots:
};
As an alternative to subclassing QTableView, you can install an event filter on it. For example, here I'm using the MainWindow of my program to filter events on a table view, which is one of the window's child widgets:
In mainwindow.h:
class MainWindow: public QMainWindow {
private:
bool eventFilter(QObject *watched, QEvent *event) override;
}
In mainwindow.cpp:
bool MainWindow::eventFilter(QObject *watched, QEvent *event)
{
if (watched == ui->tableView &&
event->type() == QEvent::KeyPress &&
static_cast<QKeyEvent*>(event)->key() == Qt::Key_Tab)
{
//Handle the tab press here
return true; //return true to skip further event handling
}
//If the event was not a tab press on the tableView, let any other handlers do their thing:
return false;
}
Then, in MainWindow::MainWindow() (or wherever) you install the event filter like this:
ui->tableView->installEventFilter(this);
This is a bit of a beginners question but I don't find the solution.
I'm using an own object that inherits from QLineEdit and reiceves numbers as input (which works smoothly now).
Now I want to receive an event, when the user presses the Escape-button. This does not happen with the textChanged()-event. According to the documentation there is no special escape-event. So how else can this be done?
Thanks!
I had this same problem. I am solving it by implementing keyPressEvent in my QMainWindow.
void MainWindow::keyPressEvent(QKeyEvent *e)
{
if (e->key() == Qt::Key_Escape) {
QLineEdit *focus = qobject_cast<QLineEdit *>(focusWidget());
if (lineEditKeyEventSet.contains(focus)) {
focus->clear();
}
}
}
And setting up QSet<QLineEdit *> lineEditKeyEventSet to contain the QLineEdits that need this behavior.
void MainWindow::setupLineEditKeyEventList()
{
lineEditKeyEventSet.insert(ui->lineEdit_1);
lineEditKeyEventSet.insert(ui->lineEdit_2);
lineEditKeyEventSet.insert(ui->lineEdit_3);
}
You can either implement keyPressEvent :
void LineEdit::keyPressEvent(QKeyEvent *event)
{
if (event->key() == Qt::Key_Escape)
{
...
}
QLineEdit::keyPressEvent(event);
}
Or implement eventFilter :
bool LineEdit::eventFilter(QObject *obj, QEvent * event)
{
if((LineEdit *)obj == this && event->type()==QEvent::KeyPress && ((QKeyEvent*)event)->key() == Qt::Key_Escape )
{
...
}
return false;
}
When using the eventFilter approach, install the event filter in the constructor :
this->installEventFilter(this);
Background
I've made a custom widget with QLineEdit and several QPushButtons to use it with custom item delegate:
class LineEditor : public QWidget
{
public:
explicit LineEditor(QWidget *parent = 0) : QWidget(parent) {
setLayout(new QHBoxLayout);
layout()->setContentsMargins(0, 0, 0, 0);
layout()->setSpacing(0);
QLineEdit *edit = new QLineEdit(this);
layout()->addWidget(edit);
layout()->addWidget(new QPushButton(this));
layout()->addWidget(new QPushButton(this));
setFocusProxy(edit);
}
};
class PropertyDelegate : public QItemDelegate
{
public:
QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const {
return new LineEditor(parent);
}
bool eventFilter(QObject *object, QEvent *event) {
if (event->type() == QEvent::KeyPress) {
qDebug() << "KeyPress";
}
if (event->type() == QEvent::ShortcutOverride) {
qDebug() << "ShortcutOverride";
}
return QItemDelegate::eventFilter(object, event);
}
};
I'm going to bind them with QListView and QStandardItemModel like this:
QStandardItemModel *model = new QStandardItemModel;
model->appendRow(new QStandardItem("1"));
model->appendRow(new QStandardItem("2"));
model->appendRow(new QStandardItem("3"));
QListView w;
w.setItemDelegate(new PropertyDelegate);
w.setModel(model);
w.show();
Question
Why in the PropertyDelegate::eventFilter when Tab key is pressed there is only QEvent::ShortcutOverride event, but pressing of any other key emits both QEvent::ShortcutOverride and QEvent::KeyPress events?
UPD: I want to implement the moving between lines by pressing Tab and Backtab like with standard widgets.
Well, finally I've done some research about that.
Explanation
When a view calls createEditor function of delegate it also installs the delegate event filter to editor.
QWidget *QAbstractItemViewPrivate::editor(const QModelIndex &index,
const QStyleOptionViewItem &options)
{
Q_Q(QAbstractItemView);
QWidget *w = editorForIndex(index).widget.data();
if (!w) {
QAbstractItemDelegate *delegate = delegateForIndex(index);
if (!delegate)
return 0;
w = delegate->createEditor(viewport, options, index);
if (w) {
w->installEventFilter(delegate);
......
}
However the delegate can catch only events of editor widget, but not events of its children. When the Tab key is pressed the QWidget::event function is called, it uses it to change focus to another widget:
bool QWidget::event(QEvent *event)
{
......
switch (event->type()) {
......
case QEvent::KeyPress: {
QKeyEvent *k = (QKeyEvent *)event;
bool res = false;
if (!(k->modifiers() & (Qt::ControlModifier | Qt::AltModifier))) { //### Add MetaModifier?
if (k->key() == Qt::Key_Backtab
|| (k->key() == Qt::Key_Tab && (k->modifiers() & Qt::ShiftModifier)))
res = focusNextPrevChild(false);
else if (k->key() == Qt::Key_Tab)
res = focusNextPrevChild(true);
if (res)
break;
}
......
}
......
}
Accordingly in my case the focus is set to next QPushButton after QLineEdit and event isn't propagated to the parent (LineEditor).
Solving
The right way to solve the problem is like QSpinBox does it. Because it is also has QLineEdit. In constructor of widget it sets focus proxy for line edit:
edit->setFocusProxy(this);
So all of focus events will reach the main widget. Also the focusPolicy property must be set because it's NoFocus by default:
setFocusPolicy(Qt::WheelFocus);
All we need to do in this moment it is to propagate necessary events to QLineEdit from main widget like this:
bool LineEditor::event(QEvent *e)
{
switch(e->type())
{
case QEvent::ShortcutOverride:
if(m_lineEdit->event(e))
return true;
break;
case QEvent::InputMethod:
return m_lineEdit->event(e);
default:
break;
}
return QWidget::event(e);
}
void LineEditor::keyPressEvent(QKeyEvent *e)
{
m_lineEdit->event(e);
}
void LineEditor::mousePressEvent(QMouseEvent *e)
{
if(e->button() != Qt::LeftButton)
return;
e->ignore();
}
void LineEditor::mouseReleaseEvent(QMouseEvent *e)
{
e->accept();
}
void LineEditor::focusInEvent(QFocusEvent *e)
{
m_lineEdit->event(e);
QWidget::focusInEvent(e);
}
void LineEditor::focusOutEvent(QFocusEvent *e)
{
m_lineEdit->event(e);
QWidget::focusOutEvent(e);
}
This should be enough.
Tricky
As it's said above the delegate can't catch events of editor's children. So to make editor's behavior like "native" I have to duplicate events from children to editor.
LineEditor installs event filter to QLineEdit in constructor:
edit->installEventFilter(this);
Implementation of filter looks like this:
bool LineEditor::eventFilter(QObject *object, QEvent *event)
{
if(event->type() == QEvent::KeyPress)
{
QKeyEvent* keyEvent = static_cast<QKeyEvent *>(event);
if(keyEvent->key() == Qt::Key_Tab || keyEvent->key() == Qt::Key_Backtab)
{
QApplication::postEvent(this, new QKeyEvent(keyEvent->type(), keyEvent->key(), keyEvent->modifiers()));
// Filter this event because the editor will be closed anyway
return true;
}
}
else if(event->type() == QEvent::FocusOut)
{
QFocusEvent* focusEvent = static_cast<QFocusEvent *>(event);
QApplication::postEvent(this, new QFocusEvent(focusEvent->type(), focusEvent->reason()));
// Don't filter because focus can be changed internally in editor
return false;
}
return QWidget::eventFilter(object, event);
}
It's also possible to use qApp->notify(this, event) for QKeyEvent instead of QApplication::postEvent because we filter this events anyway. But it's not possible for QFocusEvent because notify will redirect the event and it will not reach a child.
Note that the standard (QItemDelegate or QStyledItemDelegate) delegate will care about situation when focus is changed internally by itself:
if (event->type() == QEvent::FocusOut || (event->type() == QEvent::Hide && editor->isWindow())) {
//the Hide event will take care of he editors that are in fact complete dialogs
if (!editor->isActiveWindow() || (QApplication::focusWidget() != editor)) {
QWidget *w = QApplication::focusWidget();
while (w) { // don't worry about focus changes internally in the editor
if (w == editor)
return false;
w = w->parentWidget();
}
......
I have a control with several QSpinBox objects inside a QScrollArea. All works fine when scrolling in the scroll area unless the mouse happens to be over one of the QSpinBoxes. Then the QSpinBox steals focus and the wheel events manipulate the spin box value rather than scrolling the scroll area.
I don't want to completely disable using the mouse wheel to manipulate the QSpinBox, but I only want it to happen if the user explicitly clicks or tabs into the QSpinBox. Is there a way to prevent the QSpinBox from stealing the focus from the QScrollArea?
As said in a comment to an answer below, setting Qt::StrongFocus does prevent the focus rect from appearing on the control, however it still steals the mouse wheel and adjusts the value in the spin box and stops the QScrollArea from scrolling. Same with Qt::ClickFocus.
In order to solve this, we need to care about the two following things:
The spin box mustn't gain focus by using the mouse wheel. This can be done by setting the focus policy to Qt::StrongFocus.
The spin box must only accept wheel events if it already has focus. This can be done by reimplementing QWidget::wheelEvent within a QSpinBox subclass.
Complete code for a MySpinBox class which implements this:
class MySpinBox : public QSpinBox {
Q_OBJECT
public:
MySpinBox(QWidget *parent = 0) : QSpinBox(parent) {
setFocusPolicy(Qt::StrongFocus);
}
protected:
virtual void wheelEvent(QWheelEvent *event) {
if (!hasFocus()) {
event->ignore();
} else {
QSpinBox::wheelEvent(event);
}
}
};
That's it. Note that if you don't want to create a new QSpinBox subclass, then you can also use event filters instead to solve this.
Try removing Qt::WheelFocus from the spinbox' QWidget::focusPolicy:
spin->setFocusPolicy( Qt::StrongFocus );
In addition, you need to prevent the wheel event from reaching the spinboxes. You can do that with an event filter:
explicit Widget( QWidget * parent=0 )
: QWidget( parent )
{
// setup ...
Q_FOREACH( QSpinBox * sp, findChildren<QSpinBox*>() ) {
sp->installEventFilter( this );
sp->setFocusPolicy( Qt::StrongFocus );
}
}
/* reimp */ bool eventFilter( QObject * o, QEvent * e ) {
if ( e->type() == QEvent::Wheel &&
qobject_cast<QAbstractSpinBox*>( o ) )
{
e->ignore();
return true;
}
return QWidget::eventFilter( o, e );
}
edit from Grant Limberg for completeness as this got me 90% of the way there:
In addition to what mmutz said above, I needed to do a few other things. I had to create a subclass of QSpinBox and implement focusInEvent(QFocusEvent*) and focusOutEvent(QFocusEvent*). Basically, on a focusInEvent, I change the Focus Policy to Qt::WheelFocus and on the focusOutEvent I change it back to Qt::StrongFocus.
void MySpinBox::focusInEvent(QFocusEvent*)
{
setFocusPolicy(Qt::WheelFocus);
}
void MySpinBox::focusOutEvent(QFocusEvent*)
{
setFocusPolicy(Qt::StrongFocus);
}
Additionally, the eventFilter method implementation in the event filter class changes its behavior based on the current focus policy of the spinbox subclass:
bool eventFilter(QObject *o, QEvent *e)
{
if(e->type() == QEvent::Wheel &&
qobject_cast<QAbstractSpinBox*>(o))
{
if(qobject_cast<QAbstractSpinBox*>(o)->focusPolicy() == Qt::WheelFocus)
{
e->accept();
return false;
}
else
{
e->ignore();
return true;
}
}
return QWidget::eventFilter(o, e);
}
My attempt at a solution. Easy to use, no subclassing required.
First, I created a new helper class:
#include <QObject>
class MouseWheelWidgetAdjustmentGuard : public QObject
{
public:
explicit MouseWheelWidgetAdjustmentGuard(QObject *parent);
protected:
bool eventFilter(QObject* o, QEvent* e) override;
};
#include <QEvent>
#include <QWidget>
MouseWheelWidgetAdjustmentGuard::MouseWheelWidgetAdjustmentGuard(QObject *parent) : QObject(parent)
{
}
bool MouseWheelWidgetAdjustmentGuard::eventFilter(QObject *o, QEvent *e)
{
const QWidget* widget = static_cast<QWidget*>(o);
if (e->type() == QEvent::Wheel && widget && !widget->hasFocus())
{
e->ignore();
return true;
}
return QObject::eventFilter(o, e);
}
Then I set the focus policy of the problematic widget to StrongFocus, either at runtime or in Qt Designer.
And then I install my event filter:
ui.comboBox->installEventFilter(new MouseWheelWidgetAdjustmentGuard(ui.comboBox));
Done. The MouseWheelWidgetAdjustmentGuard will be deleted automatically when the parent object - the combobox - is destroyed.
Just to expand you can do this with the eventFilter instead to remove the need to derive a new QMySpinBox type class:
bool eventFilter(QObject *obj, QEvent *event)
{
QAbstractSpinBox* spinBox = qobject_cast<QAbstractSpinBox*>(obj);
if(spinBox)
{
if(event->type() == QEvent::Wheel)
{
if(spinBox->focusPolicy() == Qt::WheelFocus)
{
event->accept();
return false;
}
else
{
event->ignore();
return true;
}
}
else if(event->type() == QEvent::FocusIn)
{
spinBox->setFocusPolicy(Qt::WheelFocus);
}
else if(event->type() == QEvent::FocusOut)
{
spinBox->setFocusPolicy(Qt::StrongFocus);
}
}
return QObject::eventFilter(obj, event);
}
With help from this post we cooked a solution for Python/PySide. If someone stumbles across this. Like we did :]
class HumbleSpinBox(QtWidgets.QDoubleSpinBox):
def __init__(self, *args):
super(HumbleSpinBox, self).__init__(*args)
self.setFocusPolicy(QtCore.Qt.StrongFocus)
def focusInEvent(self, event):
self.setFocusPolicy(QtCore.Qt.WheelFocus)
super(HumbleSpinBox, self).focusInEvent(event)
def focusOutEvent(self, event):
self.setFocusPolicy(QtCore.Qt.StrongFocus)
super(HumbleSpinBox, self).focusOutEvent(event)
def wheelEvent(self, event):
if self.hasFocus():
return super(HumbleSpinBox, self).wheelEvent(event)
else:
event.ignore()
This is my Python PyQt5 port of Violet Giraffe answer:
def preventAnnoyingSpinboxScrollBehaviour(self, control: QAbstractSpinBox) -> None:
control.setFocusPolicy(Qt.StrongFocus)
control.installEventFilter(self.MouseWheelWidgetAdjustmentGuard(control))
class MouseWheelWidgetAdjustmentGuard(QObject):
def __init__(self, parent: QObject):
super().__init__(parent)
def eventFilter(self, o: QObject, e: QEvent) -> bool:
widget: QWidget = o
if e.type() == QEvent.Wheel and not widget.hasFocus():
e.ignore()
return True
return super().eventFilter(o, e)
Just to help anyone's in need, it lacks a small detail:
call focusInEvent and focusOutEvent from QSpinBox :
void MySpinBox::focusInEvent(QFocusEvent* pEvent)
{
setFocusPolicy(Qt::WheelFocus);
QSpinBox::focusInEvent(pEvent);
}
void MySpinBox::focusOutEvent(QFocusEvent*)
{
setFocusPolicy(Qt::StrongFocus);
QSpinBox::focusOutEvent(pEvent);
}