Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. QFrame properties do not work in extended QFrame sub-class

QFrame properties do not work in extended QFrame sub-class

Scheduled Pinned Locked Moved Solved General and Desktop
qframe
8 Posts 3 Posters 3.2k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • S Offline
    S Offline
    stuartx
    wrote on last edited by stuartx
    #1

    Hi, I want to use a QFrame to organize some labels in my application. I creates a MFrame class based on QFrame to enable the QEvent::Hover Events. The Hover enter/move/leave events all work fine. However, the QFrame properties, such as frameShape, frameShadow, and lineWidth do not work. Though those properties show correctly in the designer, they do not show correctly when run the application. In the application, the frame always shows a no-frame plain shape. I attach the code below. Please advise me what I missed. Thanks a lot.

    
    ====mframe.h=====
    
    class MFrame : public QFrame
    {
        Q_OBJECT
        
    public:
        explicit MFrame(QWidget *parent = 0);
        
        void paintEvent(QPaintEvent *);
    
    protected:
        bool event(QEvent *e);
    
    signals:
        void hoverEnter();
        void hoverMove();
        void hoverLeave();
    
    private:
    
    };
    
    
    ===== mframe.cpp=====
    
    MFrame::MFrame(QWidget *parent) :
        QFrame(parent)
    {
       setAttribute(Qt::WA_Hover);
    }
    
    bool MFrame::event(QEvent *e) {
        if (e->type() == QEvent::HoverEnter)
            emit hoverEnter();
        else if (e->type() == QEvent::HoverMove)
            emit hoverMove();
        else if (e->type() == QEvent::HoverLeave)
            emit hoverLeave();
        else {
            return false;
        }
        return true;
    }
    
    void MFrame::paintEvent(QPaintEvent *e)
    {
        QFrame::paintEvent(e);
    }
    
    
    =====in mainwidown.cpp=====
    
    ...
    connect(ui->frame, SIGNAL(hoverEnter()), this, SLOT(handleHoverEnter()));
    connect(ui->frame, SIGNAL(hoverMove()), this, SLOT(handleHoverMove()));
    connect(ui->frame, SIGNAL(hoverLeave()), this, SLOT(handleHoverLeave()));
    ....
    
    void MainWindow::handleHoverLeave()
    {
        if (m_hovered == 0)
            return;
    
        qDebug() << "hoverLeave";
        ui->frame->setStyleSheet("");
        ui->label->hide();
        m_hovered = 0;
    }
    
    void MainWindow::handleHoverMove()
    {
        if (m_hovered == 1)
            return;
    
        qDebug() << "hoverMove";
        m_hovered = 1;
        QString sty = "background-color: #00ff00;";
        ui->frame->setStyleSheet(sty);
        ui->label->show();
    }
    
    void MainWindow::handleHoverEnter()
    {
        if (m_hovered == 1)
            return;
    
        qDebug() << "hoverEnter";
        m_hovered = 1;
        QString sty = "background-color: #00ff00;";
        ui->frame->setStyleSheet(sty);
        ui->label->show();
    }
    
    
    1 Reply Last reply
    0
    • mrjjM Offline
      mrjjM Offline
      mrjj
      Lifetime Qt Champion
      wrote on last edited by mrjj
      #2

      hi
      I think you paint is not called as its normally
      protected and yours are placed in public.
      However Since you don't call
      QFrame::event(e);
      in MFrame::event(QEvent *e)

      you are eating the paint events that the parent frame would get.

      There is no need for custom paint. ( unless u need to add extra painting)

      bool MFrame::event(QEvent *e) {
          if (e->type() == QEvent::HoverEnter)
              emit hoverEnter();
          else if (e->type() == QEvent::HoverMove)
              emit hoverMove();
          else if (e->type() == QEvent::HoverLeave)
              emit hoverLeave();
          else {
               QFrame::event(e); <<<< let parent handle paint
              return false;
          }
        
          return true;
      
      }
      
      1 Reply Last reply
      0
      • Chris KawaC Online
        Chris KawaC Online
        Chris Kawa
        Lifetime Qt Champion
        wrote on last edited by
        #3

        @mrjj There's no overloading on access specifiers in c++ so it doesn't matter if it's public, protected, or even private.

        @stuartx Nevertheless it's a good practice to put overridekeyword on your virtual method overrides. It will save you from wasted time debugging typos. Another unrelated thing is you should not return true from your event like that. It prevents correct passing hover events between parents and children. It doesn't matter that you emit a custom signal, you should still return false and let Qt handle it, i.e.

        bool MFrame::event(QEvent* e) {
            if (e->type() == QEvent::HoverEnter)
                emit hoverEnter();
            else if (e->type() == QEvent::HoverMove)
                emit hoverMove();
            else if (e->type() == QEvent::HoverLeave)
                emit hoverLeave();
            
            return QFrame::event(e);
        }
        

        Back to the point. The code you shown doesn't have any obvious problems related to painting. Do you promote your widget in the designer? What shape and shadow value do you set? Is that all the stylesheets you use? Some (like border) can interact with the frame properties and override/disable them.

        1 Reply Last reply
        0
        • mrjjM Offline
          mrjjM Offline
          mrjj
          Lifetime Qt Champion
          wrote on last edited by
          #4

          Hi
          I know, was badly written.
          What I meant is that it seems he eats all paints events
          so his paint is never called. Nor his or parent's.
          as I show in the modified code.

          I tried the code and with QFrame::event(e);
          and promoted widget it starts drawing.

          Before nothing was shown so I assume his
          MFrame::event(QEvent* e) was to blame.
          (it has no QFrame::event(e);)

          Was i wrong?

          1 Reply Last reply
          0
          • Chris KawaC Online
            Chris KawaC Online
            Chris Kawa
            Lifetime Qt Champion
            wrote on last edited by
            #5

            @mrjj Seems the OP modified his post. I haven't seen the first version, so what you said might have very well be the issue.

            mrjjM 1 Reply Last reply
            0
            • Chris KawaC Chris Kawa

              @mrjj Seems the OP modified his post. I haven't seen the first version, so what you said might have very well be the issue.

              mrjjM Offline
              mrjjM Offline
              mrjj
              Lifetime Qt Champion
              wrote on last edited by
              #6

              well the first version is
              ...
              else if (e->type() == QEvent::HoverLeave)
              emit hoverLeave();
              else {
              return false; << here is the bad part, correct?

              Ok. I was just suddenly confused. Thank you.

              1 Reply Last reply
              0
              • S Offline
                S Offline
                stuartx
                wrote on last edited by
                #7

                @Chris Kawa and @mrjj: thanks for the response.

                Based on your advice, I removed the paintEvent(QPaintEvent *) from the Frame class; I couldn't add override keyword before event() since my compiler is not c++11 capable; I return QFrame::event(e) in the overloaded function:

                bool MFrame::event(QEvent* e) {
                ....
                return QFrame::event(e);
                }

                But the frame shape is still not drawn.

                I promoted the QFrame to MFrame in the designer. In the designer I set frameShape=Box, frameShadow=raised, and the lineWidth=4. I only used the stylesheet in the following way:

                in hoverEnter:
                QString sty = "background-color: #00ff00;";
                ui->frame->setStyleSheet(sty);

                in hoverLeave:
                ui->frame->setStyleSheet("");

                Please let me know if you need more information from me. In addition, I edited my OP once, only changed a typo in title.

                Thanks.

                1 Reply Last reply
                0
                • S Offline
                  S Offline
                  stuartx
                  wrote on last edited by
                  #8

                  Hi Guys, It works. I forget to remove
                  ...
                  else {
                  return false;
                  }

                  in bool MFrame::event(QEvent* e).

                  The function "bool MFrame::event(QEvent* e)" returns QFrame::event(e) is the fix.

                  Thanks a lot.

                  1 Reply Last reply
                  0

                  • Login

                  • Login or register to search.
                  • First post
                    Last post
                  0
                  • Categories
                  • Recent
                  • Tags
                  • Popular
                  • Users
                  • Groups
                  • Search
                  • Get Qt Extensions
                  • Unsolved