PDA

View Full Version : Qt event filter hides the widget



Cupidvogel
8th April 2015, 10:29
I have a parent widget inside which I have to place a custom widget (say a QFrame). Inside that custom widget, I have to place a number of child widgets (derived from QPushButton). I want the child widgets to have a certain background under normal circumstances, and another one when hovered upon. This is my code:



//parent widget code, where the QFrame derived widget is initialized
QFrameDerivedWidget *qFrameWidget = new QFrameDerivedWidget(this, someString);


This is the QFrameDerivedWidget header file:



//QFrameDerivedWidget header file
class QFrameDerivedWidget: public QFrame
{
Q_OBJECT

public:
QFrameDerivedWidget(QWidget *aParent,
std::string someValue);
bool eventFilter(QObject *obj, QEvent *event);
}


This is the QFrameDerivedWidget implementation file, the ChildWidget class is defined and declared inline:



class ChildWidget: public QPushButton
{
Q_Object
public:
ChildWidget(std::string aText, QWidget *aParent);

};

ChildWidget::ChildWidget(std::string aText, QWidget *aParent):
QPushButton(QString::fromStdString(aText),aParent)
{
this->setFixedHeight(30);
this->setMouseTracking(true);
this->setCursor(Qt::PointingHandCursor);
/* ---other custom styling--- */
}

bool QFrameDerivedWidget::eventFilter(QObject *obj, QEvent *event)
{
// this never prints out anything, even though it should for any mouseenter, mouseleave, click, etc event on it
qDebug() << obj->metaObject()->className() << endl;

if (obj->metaObject()->className() == "ChildWidget")
{
//including this line throws a 'missing QObject missing macro error' as well
ChildWidget *option = qobject_cast<ChildWidget* >(obj);
if (event->type() == QEvent::Enter)
{
option->setStyleSheet("---");

}
if (event->type() == QEvent::Leave)
{
option->setStyleSheet("---");
}
return QWidget::eventFilter(obj, event);
}
else
{
// pass the event on to the parent class
return QWidget::eventFilter(obj, event);
}
}

QFrameDerivedWidget::QFrameDerivedWidget(QWidget *aParent,
std::string someVal): fParent(aParent)
{
initUI();
}

QFrameDerivedWidget::initUI()
{
this->setParent(fParent);
this->setAttribute(Qt::WA_Hover);
this->setMouseTracking(true);
QWidget *dd = new QWidget(this);
QVBoxLayout *layout = new QVBoxLayout();
dd->setLayout(layout);
for (int i = 0; i < fValues.size(); i++)
{
ChildWidget *button = new ChildWidget(fValues[i],dd);
button->addEventFilter(this);
layout->addWidget(button);
}
}


The idea is, whenever I hover over the QFrameDerivedWidget and enter any ChildWidget, its background color should change. Additionally, I have set a qDebug() statement inside the eventFilter. It is currently not working, the ChildWidget buttons are not visible, but they are there, for the cursor turns pointer when I hover over where they are supposed to be.

What am I doing wrong, and how do I make it work? (I have also tried moving ChildWidget to a separate class, just in case. Same result).

I have observed that the line
button->installEventFilter(this); is the one which causes the child widgets to be invisible.

wysota
8th April 2015, 10:46
Why are you using event filters? If you want to use stylesheets then use the :hover selector to define a background when the mouse pointer is over the button.

Cupidvogel
8th April 2015, 10:52
I tried that as well. Removed all code, simply set mouseTracking to true, and in the stylesheet added a style like
QPushButton:hover { background: red; }. Still not working.

wysota
8th April 2015, 12:30
This works fine for me (no need for mouse tracking):

QPushButton { background: "blue" }
QPushButton:hover { background: "red" }