June 15, 2011

yan bellavance yan bellavance
Lab Rat
50 posts

[SOLVED] QFrame subclass not keeping properties set in Qt Designer

 

I have a UI form which contains a set of QFrames. I need extra functionality so I created a QFrame subclass in my project and, using Qt Designer, I promoted them to rgbFrame (my QFrame subclass). The problem is that the frame disappears completely at run time. If I set stylesheet programatically to set background color I see a widget with no frame. Doing a complete styling finally gives me a visible QFrame but this is not what I want, I want it to be native and use the OS style and be able to control it like a normal QFrame. What am I doing wrong to make this happen? Here is my subclass:

  1. #include <QObject>
  2. #include <QFrame>
  3. #include <QEvent>
  4.  
  5. class rgbFrame : public QFrame
  6. {
  7.     Q_OBJECT
  8. public:
  9.     rgbFrame(QWidget * parent = 0, Qt::WindowFlags f = 0): QFrame(parent, f){
  10.     }
  11. signals:
  12.     void colorClick();
  13. protected:
  14.     int counter;
  15.     int stop;
  16.     bool event ( QEvent * e ){
  17.         if(e->type()==QEvent::MouseButtonRelease){
  18.             emit colorClick();
  19.             counter++;            
  20.         }
  21.     }
  22. };

SOLVED: I ended up overriding the paintEvent function but even that was not getting called. So I then installed an event filter and called paintevent from there which solved the problem:

  1. rgbFrame::rgbFrame(QWidget * parent, Qt::WindowFlags f): QFrame(parent, f)
  2. {
  3.     installEventFilter(this);
  4. }
  5.  
  6. void rgbFrame::paintEvent(QPaintEvent *e)
  7. {
  8.     QFrame::paintEvent(e); // pass event to base class
  9. }
  10.  
  11.  
  12. bool rgbFrame::eventFilter(QObject *o, QEvent *e)
  13. {
  14.     if (e->type() == QEvent::Paint) {
  15.         paintEvent((QPaintEvent *)e);
  16.     }
  17.     return QFrame::eventFilter(o, e);
  18. }

4 replies

June 17, 2011

alexisdm alexisdm
Lab Rat
141 posts

You forgot to call

  1. return QFrame::event(e);
in rgbFrame::event().
If you fix that, you shouldn’t need to reimplement paintEvent or install an event filter anymore.

You could also only reimplement mouseReleaseEvent instead of event if you are only interested in that type of event.

Edit: added a return

July 21, 2011

yan bellavance yan bellavance
Lab Rat
50 posts

What I didn’t understand is why I had to do this in the first place, I had sub-classed other qobjects before without having to do this. But now that I look at it I think know what you mean:

Even though the class has paintEvent(), mouseMoveEvent(), mousePressEvent(), mouseReleaseEvent(), moveEvent() etc … if a subclass re-implements Event() then all the event functions don’t get called because they all go through event first.

July 21, 2011

alexisdm alexisdm
Lab Rat
141 posts

To be more precise, event is the one calling all the “sub event functions” (paintEvent, mouseMoveEvent…), so you need to call the base class function if you don’t handle the event or if you don’t want to filter it out.

And since widgets can also use the sub event functions to act upon them, you should call the base class corresponding function for these too, when you don’t handle the events (it is at least indicated in QWidget::keyPressEvent documentation [doc.qt.nokia.com] ).

July 21, 2011

yan bellavance yan bellavance
Lab Rat
50 posts

yeah I have already done this with QWidget::keyPressEvent() and other sub-event functions but it just did not dawn on me that I was cutting of all sub events() by reimplementing event(), I simply considered that both the event and sub-event functions would get called.

 
  ‹‹ Dock button on Menu bar      QProcess messaging and hidden? ››

You must log in to post a reply. Not a member yet? Register here!