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 10 Jan 2016, 17:58 last edited by stuartx 1 Oct 2016, 17:58
    #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
    • M Offline
      M Offline
      mrjj
      Lifetime Qt Champion
      wrote on 10 Jan 2016, 18:26 last edited by mrjj 1 Oct 2016, 18:27
      #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
      • C Offline
        C Offline
        Chris Kawa
        Lifetime Qt Champion
        wrote on 10 Jan 2016, 21:18 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
        • M Offline
          M Offline
          mrjj
          Lifetime Qt Champion
          wrote on 10 Jan 2016, 21:38 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
          • C Offline
            C Offline
            Chris Kawa
            Lifetime Qt Champion
            wrote on 10 Jan 2016, 21:43 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.

            M 1 Reply Last reply 10 Jan 2016, 21:46
            0
            • C Chris Kawa
              10 Jan 2016, 21:43

              @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.

              M Offline
              M Offline
              mrjj
              Lifetime Qt Champion
              wrote on 10 Jan 2016, 21:46 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 10 Jan 2016, 23:58 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 11 Jan 2016, 00:11 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

                  1/8

                  10 Jan 2016, 17:58

                  • Login

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