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. Redrawing QMenu
Forum Updated to NodeBB v4.3 + New Features

Redrawing QMenu

Scheduled Pinned Locked Moved Unsolved General and Desktop
7 Posts 2 Posters 541 Views 1 Watching
  • 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.
  • Z Offline
    Z Offline
    Zack Zheng
    wrote on last edited by
    #1

    First question:
    When I redrew QMenu, I used QStyleOptionMenuItem to redraw the menu item and reset the icon in option, but the icon size in the menu item did not change. How should I deal with this?

    1 Reply Last reply
    0
    • SGaistS Offline
      SGaistS Offline
      SGaist
      Lifetime Qt Champion
      wrote on last edited by
      #2

      Hi and welcome to devnet,

      Which version of Qt ?
      On which platform ?
      You should also share a minimal compilable example that shows this behavior.

      Interested in AI ? www.idiap.ch
      Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

      1 Reply Last reply
      0
      • Z Offline
        Z Offline
        Zack Zheng
        wrote on last edited by Zack Zheng
        #3

        Hi .
        I am using qt version 5.15.2 on windows platform.
        I am a newbie and this is my first attempt to draw a control using QStyleOption.
        This is a reimplement of paintEvent fuciton for my menu.

        void myMenu::paintEvent(QPaintEvent* event)
        {
              QMenu::paintEvent(event);
              QPainter             p(this);
         QRegion              emptyArea = QRegion(rect());
         QStyleOptionMenuItem menuOpt;
         menuOpt.initFrom(this);
         menuOpt.state        = QStyle::State_None;
         menuOpt.checkType    = QStyleOptionMenuItem::NotCheckable;
         menuOpt.maxIconWidth = 0;
         menuOpt.tabWidth     = 0;
         style()->drawPrimitive(QStyle::PE_FrameMenu, &menuOpt, &p, this);
        
         QList<QAction*> actionList = actions();
         
        for (int i = 0; i < actionList.count(); ++i)
         {
        
             QAction* action             = actionList.at(i);
             QRect    adjustedActionRect = actionGeometry(action);
        
             if (!event->rect().intersects(adjustedActionRect))
                 continue;
        
             QStyleOptionMenuItem opt;
             initStyleOption(&opt, action);
             opt.rect = adjustedActionRect;
        
             style()->drawControl(QStyle::CE_MenuItem, &opt, &p, this);
          }
        }
        

        This is the initStyleOption function used in the PaintEvent function above.

        void myMenu::initStyleOption(QStyleOptionMenuItem* option, QAction* action) const
        {
        QMenu::initStyleOption(option, action);
        int       mergin               = 0;
        int       iconWithTextDistance = 6;
        QIcon     icon                 = option->icon;
        const int widgetHeight         = option->rect.width() - mergin * 2;
        option->maxIconWidth           = widgetHeight;
        if (!icon.isNull())
        {
            QSize iconSize = icon.actualSize(QSize(widgetHeight, widgetHeight),
                                             (option->state & QStyle::State_Enabled) ? QIcon::Normal : QIcon::Disabled,
                                             (option->state & QStyle::State_Selected) ? QIcon::On : QIcon::Off);
        
        auto icona   = icon.pixmap(iconSize);
         option->icon = icona;
        }
        }
        

        This is the drawing code, if there is anything else I need to provide, please leave a message to me directly, I am very much looking forward to your reply.

        SGaistS 1 Reply Last reply
        0
        • Z Zack Zheng

          Hi .
          I am using qt version 5.15.2 on windows platform.
          I am a newbie and this is my first attempt to draw a control using QStyleOption.
          This is a reimplement of paintEvent fuciton for my menu.

          void myMenu::paintEvent(QPaintEvent* event)
          {
                QMenu::paintEvent(event);
                QPainter             p(this);
           QRegion              emptyArea = QRegion(rect());
           QStyleOptionMenuItem menuOpt;
           menuOpt.initFrom(this);
           menuOpt.state        = QStyle::State_None;
           menuOpt.checkType    = QStyleOptionMenuItem::NotCheckable;
           menuOpt.maxIconWidth = 0;
           menuOpt.tabWidth     = 0;
           style()->drawPrimitive(QStyle::PE_FrameMenu, &menuOpt, &p, this);
          
           QList<QAction*> actionList = actions();
           
          for (int i = 0; i < actionList.count(); ++i)
           {
          
               QAction* action             = actionList.at(i);
               QRect    adjustedActionRect = actionGeometry(action);
          
               if (!event->rect().intersects(adjustedActionRect))
                   continue;
          
               QStyleOptionMenuItem opt;
               initStyleOption(&opt, action);
               opt.rect = adjustedActionRect;
          
               style()->drawControl(QStyle::CE_MenuItem, &opt, &p, this);
            }
          }
          

          This is the initStyleOption function used in the PaintEvent function above.

          void myMenu::initStyleOption(QStyleOptionMenuItem* option, QAction* action) const
          {
          QMenu::initStyleOption(option, action);
          int       mergin               = 0;
          int       iconWithTextDistance = 6;
          QIcon     icon                 = option->icon;
          const int widgetHeight         = option->rect.width() - mergin * 2;
          option->maxIconWidth           = widgetHeight;
          if (!icon.isNull())
          {
              QSize iconSize = icon.actualSize(QSize(widgetHeight, widgetHeight),
                                               (option->state & QStyle::State_Enabled) ? QIcon::Normal : QIcon::Disabled,
                                               (option->state & QStyle::State_Selected) ? QIcon::On : QIcon::Off);
          
          auto icona   = icon.pixmap(iconSize);
           option->icon = icona;
          }
          }
          

          This is the drawing code, if there is anything else I need to provide, please leave a message to me directly, I am very much looking forward to your reply.

          SGaistS Offline
          SGaistS Offline
          SGaist
          Lifetime Qt Champion
          wrote on last edited by
          #4

          @Zack-Zheng why are you calling the base class implementation since you are repainting everything anyway ?

          Depending on the final goal, a QProxyStyle might be simpler.

          Interested in AI ? www.idiap.ch
          Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

          Z 2 Replies Last reply
          0
          • SGaistS SGaist

            @Zack-Zheng why are you calling the base class implementation since you are repainting everything anyway ?

            Depending on the final goal, a QProxyStyle might be simpler.

            Z Offline
            Z Offline
            Zack Zheng
            wrote on last edited by
            #5

            @SGaist Since I am not familiar with the process of control redrawing, after calling the redrawing operation of the base class, that is, making a setting to StyleOption, I want to make some changes based on the StyleOption after setting.
            I think I understand that the purpose of the InitStyleOption function is to get various information about the control to be drawn, but my purpose is to modify the style of the menu item element, and using customStyle is more suitable for my purpose.
            I'm not sure I'm understanding this correctly. If there is anything wrong, I hope you can correct me. Thank you for your reply.Looking forward to your reply.

            1 Reply Last reply
            0
            • SGaistS SGaist

              @Zack-Zheng why are you calling the base class implementation since you are repainting everything anyway ?

              Depending on the final goal, a QProxyStyle might be simpler.

              Z Offline
              Z Offline
              Zack Zheng
              wrote on last edited by
              #6

              @SGaist Hi SGaist, This is my problem.

              void RibbonPopMenu::paintEvent(QPaintEvent* event)
              
              {
              
              QPainter p(this);
              
              QRegion emptyArea = QRegion(rect());
              
              QStyleOptionMenuItem menuOpt;
              
              menuOpt.initFrom(this);
              
              menuOpt.state = QStyle::State_None;
              
              menuOpt.checkType = QStyleOptionMenuItem::NotCheckable;
              
              menuOpt.maxIconWidth = 0;
              
              menuOpt.tabWidth = 0;
              
              style()->drawPrimitive(QStyle::PE_FrameMenu, &menuOpt, &p, this);
              
              QList<QAction> actionList = actions();
              
              for (int i = 0; i < actionList.count(); ++i)
              
              {
              
              QAction action = actionList.at(i);
              
              QRect adjustedActionRect = actionGeometry(action);
              
              if (!event->rect().intersects(adjustedActionRect))
              
              continue;
              
              QStyleOptionMenuItem opt;
              
              opt.initFrom(this);
              
              initStyleOption(&opt, action);
              
              opt.rect = adjustedActionRect;
              
              style()->drawControl(QStyle::CE_MenuItem, &opt, &p, this);
              
              }
              
              }
              

              This is the PaintEvent event for my custom control, and I've also created a CustomStyle that I've already set when I enable it.

              m_AppButtonMenu->setStyle(new CustomStyle());
              

              Here, m_AppButtonMenu is of type RibbonPopMenu.
              But inside the PaintEvent function, style()->drawPrimitive(QStyle::PE_FrameMenu, &menuOpt, &p, this); this function and style()->drawControl(QStyle::CE_MenuItem, &opt, &p, this); Normally, the overloaded function in my CustomStyle should be called, but I only called the first one during debugging, but not the second one. Why?

              SGaistS 1 Reply Last reply
              0
              • Z Zack Zheng

                @SGaist Hi SGaist, This is my problem.

                void RibbonPopMenu::paintEvent(QPaintEvent* event)
                
                {
                
                QPainter p(this);
                
                QRegion emptyArea = QRegion(rect());
                
                QStyleOptionMenuItem menuOpt;
                
                menuOpt.initFrom(this);
                
                menuOpt.state = QStyle::State_None;
                
                menuOpt.checkType = QStyleOptionMenuItem::NotCheckable;
                
                menuOpt.maxIconWidth = 0;
                
                menuOpt.tabWidth = 0;
                
                style()->drawPrimitive(QStyle::PE_FrameMenu, &menuOpt, &p, this);
                
                QList<QAction> actionList = actions();
                
                for (int i = 0; i < actionList.count(); ++i)
                
                {
                
                QAction action = actionList.at(i);
                
                QRect adjustedActionRect = actionGeometry(action);
                
                if (!event->rect().intersects(adjustedActionRect))
                
                continue;
                
                QStyleOptionMenuItem opt;
                
                opt.initFrom(this);
                
                initStyleOption(&opt, action);
                
                opt.rect = adjustedActionRect;
                
                style()->drawControl(QStyle::CE_MenuItem, &opt, &p, this);
                
                }
                
                }
                

                This is the PaintEvent event for my custom control, and I've also created a CustomStyle that I've already set when I enable it.

                m_AppButtonMenu->setStyle(new CustomStyle());
                

                Here, m_AppButtonMenu is of type RibbonPopMenu.
                But inside the PaintEvent function, style()->drawPrimitive(QStyle::PE_FrameMenu, &menuOpt, &p, this); this function and style()->drawControl(QStyle::CE_MenuItem, &opt, &p, this); Normally, the overloaded function in my CustomStyle should be called, but I only called the first one during debugging, but not the second one. Why?

                SGaistS Offline
                SGaistS Offline
                SGaist
                Lifetime Qt Champion
                wrote on last edited by
                #7

                @Zack-Zheng Can you provide a minimal complete code sample ? That way we can test it on our side rather that having to put pieces together.

                Interested in AI ? www.idiap.ch
                Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                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