PDA

View Full Version : focusNextChild Segmentatiion Fault



croscato
23rd July 2014, 06:31
Hi, everyone!

I'm getting a SegFault while implement an eventFilter in a QDialog subclass.

The code bellow works fine in Qt 4.8.6, in Qt 5.3.1 it Segfault.



ISCBase::ISCBase(QWidget *parent) : QDialog(parent)
{
setGeometry(0, 0, 768, 450);

this->installEventFilter(this);
}

bool ISCBase::eventFilter(QObject *object, QEvent *event)
{
if (event->type() == QEvent::KeyPress) {
QKeyEvent *keyEvent = (QKeyEvent*) event;

if ((keyEvent->key() == Qt::Key_Return) || (keyEvent->key() == Qt::Key_Enter)) {
ISCBase *base = qobject_cast<ISCBase*>(object);

if (
(base) && (
(qobject_cast<QRadioButton*>(base->focusWidget())) ||
(qobject_cast<QCheckBox*>(base->focusWidget())) ||
(qobject_cast<QComboBox*>(base->focusWidget())) ||
(qobject_cast<QDateEdit*>(base->focusWidget())) ||
(qobject_cast<QDoubleSpinBox*>(base->focusWidget())) ||
(qobject_cast<QFontComboBox*>(base->focusWidget())) ||
(qobject_cast<QSlider*>(base->focusWidget())) ||
#if QT_VERSION >= 0x050000
(qobject_cast<QKeySequenceEdit*>(base->focusWidget())) ||
#endif
(qobject_cast<QLineEdit*>(base->focusWidget())) ||
(qobject_cast<QRadioButton*>(base->focusWidget())) ||
(qobject_cast<QSpinBox*>(base->focusWidget())) ||
(qobject_cast<QTimeEdit*>(base->focusWidget())))
) {
focusNextChild();

return true;
}
}
}

return QObject::eventFilter(object, event);
}


Any help will be welcome.

d_stranz
23rd July 2014, 06:54
Why are you installing an event filter on your own class? Event filters are intended so that some other class can monitor events in a different class.

If you want to handle key press events, simply reimplement the QWidget::keyPressEvent() handler in your dialog class. Have you determined that using an event filter is the only way you can trap the return key?

You are calling QObject::eventFilter() at the end, instead of QDialog::eventFilter(), but again, you shouldn't be using an event filter in this way in the first place. You are also not setting the accept() flag on the event when you do handle it.

croscato
23rd July 2014, 13:25
Installing the eventFilter in my own class give me the possibily to handle all kinds of events in one central location. And the Qt documentation doesn't point this as bad habit, nor recomend against it.

Qt Creator use this kind of eventFilter control (src/plugins/coreplugin/locator/locatorwidget.cpp (https://qt.gitorious.org/qt-creator/qt-creator/source/38f068efa721589a33a2764bcab2f916eefcd85a:src/plugins/coreplugin/locator/locatorwidget.cpp#L262)), see line 262.


// We set click focus since otherwise you will always get two popups
m_fileLineEdit->setButtonFocusPolicy(Utils::FancyLineEdit::Left, Qt::ClickFocus);
m_fileLineEdit->setAttribute(Qt::WA_MacShowFocusRect, false);
m_fileLineEdit->installEventFilter(this);
this->installEventFilter(this);


The error persists calling QObject::eventFilter or QDialog::eventFilter.

Oddly enough this same code runs correctly under Qt 5.3.1 in windows. It's seems that it could be related to the linux version of Qt.

I track the error to a QPaintEvent using gdb.

Anyway thanks for the help.

wysota
23rd July 2014, 16:37
Installing the eventFilter in my own class give me the possibily to handle all kinds of events in one central location.
In such case you should reimplement event() for the object. All events pass through there before reaching their respective event handlers. Installing an event filter on yourself is not a good solution. And in your particular case you are handling one type of event so there is no reason not to put it in keyPressEvent().

Maybe you should state what exactly you are trying to do?