Trolltech Home | Qt-interest Home | Recent Threads | All Threads | Author | Date
All threads index page 2

Qt-interest Archive, August 1999
EventFilter


Message 1 in thread

If I define an eventFilter method for a class inherited from QObject, is
it correct, that the evntFilter method is called even if the QObject is
not installed as an EventFilter? The documentation for
QObject::eventFilter states "Filters events if this object has been
installed as an event filter for another object.". This would mean that
it is not correct.

The following program demonstrates the problem: The eventFilter method
of MyScrollView is called without installing an event filter. The only
way to display MyScrollView in the desired way is to call
QScrollView::eventFilter explicitly from MyScrollView::eventFilter. This
can´t be the way it is supposed to be, can it?

Save the source as myeventfiltertest.cxx and compile it with:
moc -o myeventfiltertest.moc myeventfiltertest.cxx
g++ -o myeventfiltertest -I $QTDIR/include -L$QTDIR/lib -lqt
myeventfiltertest.cxx

--- Program starts here: ---------
#include <qapp.h>
#include <qlabel.h>
#include <qvbox.h>
#include <qscrollview.h>

class MyScrollView : public QScrollView
{
    Q_OBJECT
  public:
    MyScrollView ( QWidget * parent=0, const char * name=0, WFlags f=0
);

    virtual bool eventFilter ( QObject *, QEvent * );   

  protected:
    void drawContents(QPainter *p,int cx, int cy, int cw, int ch);    
};

MyScrollView::MyScrollView(QWidget *parent,const char *name,WFlags f) :
  QScrollView(parent,name,f)
{
  resizeContents(60*20+1,20*20+1);
  setMaximumSize(60*20+1,20*20+1);
  
  enableClipper(true);

  QLabel *firstLabel = new QLabel ("Erstens",viewport());
  firstLabel->setFrameStyle(WinPanel|Raised);

//  firstLabel->installEventFilter(this);

  addChild(firstLabel,3*60,2*20);
}

bool MyScrollView::eventFilter ( QObject *object, QEvent *event )
{
  if (event->type() == QEvent::MouseButtonPress) {
    qDebug("MouseButtonPress filtered");
  }
  
  return QScrollView::eventFilter(object,event);
}

void MyScrollView::drawContents(QPainter* p, int cx, int cy, int cw, int
ch)
{
  const int xSpacing = 60;
  const int ySpacing = 20;

  int x = ((int)(cx/xSpacing))*xSpacing;
  while (x < cx + cw) {
    p->drawLine(x,cy,x,cy+ch);
    x+=xSpacing;
  }  

  int y = ((int)(cy/ySpacing))*ySpacing;
  while (y < cy + ch) {
    p->drawLine(cx,y,cx+cw,y);
    y+=ySpacing;
  }  
}

int main (int argc, char **argv)
{
  QApplication *app = new QApplication(argc,argv);

  QVBox *main = new QVBox;

  MyScrollView *sv = new MyScrollView(main);

  QObject::connect(qApp,SIGNAL(lastWindowClosed()),qApp,SLOT(quit()));

  main->show();
  
  app->exec();
}

#include "myeventfiltertest.moc"
---- End of program ----

-- 
 [ signature omitted ] 

Message 2 in thread

Cornelius Schumacher wrote:

> If I define an eventFilter method for a class inherited from QObject, is
> it correct, that the evntFilter method is called even if the QObject is
> not installed as an EventFilter? The documentation for
> QObject::eventFilter states "Filters events if this object has been
> installed as an event filter for another object.". This would mean that
> it is not correct.
>
> The following program demonstrates the problem: The eventFilter method
> of MyScrollView is called without installing an event filter. The only
> way to display MyScrollView in the desired way is to call
> QScrollView::eventFilter explicitly from MyScrollView::eventFilter. This
> can´t be the way it is supposed to be, can it?
>
> Save the source as myeventfiltertest.cxx and compile it with:
> moc -o myeventfiltertest.moc myeventfiltertest.cxx
> g++ -o myeventfiltertest -I $QTDIR/include -L$QTDIR/lib -lqt
> myeventfiltertest.cxx
>
> --- Program starts here: ---------
> #include <qapp.h>
> #include <qlabel.h>
> #include <qvbox.h>
> #include <qscrollview.h>
>
> class MyScrollView : public QScrollView
> {
>     Q_OBJECT
>   public:
>     MyScrollView ( QWidget * parent=0, const char * name=0, WFlags f=0
> );
>
>     virtual bool eventFilter ( QObject *, QEvent * );
>
>   protected:
>     void drawContents(QPainter *p,int cx, int cy, int cw, int ch);
> };
>
> MyScrollView::MyScrollView(QWidget *parent,const char *name,WFlags f) :
>   QScrollView(parent,name,f)
> {
>   resizeContents(60*20+1,20*20+1);
>   setMaximumSize(60*20+1,20*20+1);
>
>   enableClipper(true);
>
>   QLabel *firstLabel = new QLabel ("Erstens",viewport());
>   firstLabel->setFrameStyle(WinPanel|Raised);
>
> //  firstLabel->installEventFilter(this);
>
>   addChild(firstLabel,3*60,2*20);
> }
>
> bool MyScrollView::eventFilter ( QObject *object, QEvent *event )
> {
>   if (event->type() == QEvent::MouseButtonPress) {
>     qDebug("MouseButtonPress filtered");
>   }
>
>   return QScrollView::eventFilter(object,event);
> }
>
> void MyScrollView::drawContents(QPainter* p, int cx, int cy, int cw, int
> ch)
> {
>   const int xSpacing = 60;
>   const int ySpacing = 20;
>
>   int x = ((int)(cx/xSpacing))*xSpacing;
>   while (x < cx + cw) {
>     p->drawLine(x,cy,x,cy+ch);
>     x+=xSpacing;
>   }
>
>   int y = ((int)(cy/ySpacing))*ySpacing;
>   while (y < cy + ch) {
>     p->drawLine(cx,y,cx+cw,y);
>     y+=ySpacing;
>   }
> }
>
> int main (int argc, char **argv)
> {
>   QApplication *app = new QApplication(argc,argv);
>
>   QVBox *main = new QVBox;
>
>   MyScrollView *sv = new MyScrollView(main);
>
>   QObject::connect(qApp,SIGNAL(lastWindowClosed()),qApp,SLOT(quit()));
>
>   main->show();
>
>   app->exec();
> }
>
> #include "myeventfiltertest.moc"
> ---- End of program ----
>
> --
> Cornelius Schumacher
> Institut fuer Hochenergiephysik/ASIC Labor
> Universitaet Heidelberg
> Schroederstrasse 90                      Tel.: ++49 6221 54-4971
> D-69120 Heidelberg      mailto:schumacher@asic.uni-heidelberg.de
>
> --
> List archive and information: http://www.troll.no/qt-interest/

I am also interested in EventFilters so I traced the code of Qt, and found
that in the constructor of QScrollView the object installs itself as an
event filter for a viewport member data of a QScrollViewData object created
by the QScrollView. And a QScrollView object also install itself as an
event filter in its methods addChild(), enableClipper(), and thus
QScrollView has a fat eventFilter() method, that is why you have to call
the ancestor's eventFilter() in your subclass.

Miklos Nemeth
IQSOFT