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. How to apply CSS styles only to certain items in menu and tool bar?
Forum Updated to NodeBB v4.3 + New Features

How to apply CSS styles only to certain items in menu and tool bar?

Scheduled Pinned Locked Moved Unsolved General and Desktop
8 Posts 4 Posters 1.1k 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.
  • NotNypicalN Offline
    NotNypicalN Offline
    NotNypical
    wrote on last edited by
    #1

    I have a menu and a tool bar with a bunch of action items.

    menu->setStyleSheet("QMenu { text-decoration: line-through; }");
    toolbar->setStyleSheet("QToolButton { text-decoration: line-through; }");
    

    It works fine for all items, but I need it for specific items.

    So how to apply CSS styles only to certain items in the menu and tool bar?

    "If you've met one individual with autism, you've met one individual with autism." - Stephen Shore

    1 Reply Last reply
    0
    • Christian EhrlicherC Online
      Christian EhrlicherC Online
      Christian Ehrlicher
      Lifetime Qt Champion
      wrote on last edited by
      #2

      You can do this with a dynamic property: https://wiki.qt.io/Dynamic_Properties_and_Stylesheets

      Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
      Visit the Qt Academy at https://academy.qt.io/catalog

      1 Reply Last reply
      3
      • NotNypicalN Offline
        NotNypicalN Offline
        NotNypical
        wrote on last edited by
        #3

        "Customizing Using Dynamic Properties" is the way to go , but how to do it right?

        #include "mainwindow.h"
        
        #include <QDebug>
        #include <QStyle>
        #include <QToolBar>
        
        
        MainWindow::MainWindow(QWidget *parent)
            : QMainWindow(parent)
        {
            setStyleSheet("*[invertItem=true] { text-decoration: line-through }");
        
            QAction *actionQuit = new QAction("Quit", this);
            connect(actionQuit, &QAction::triggered, this, &MainWindow::close);
        
            m_actionItem = new QAction("Item", this);
            m_actionItem->setProperty("invertItem", false);
        
            QAction *actionInvert = new QAction("Invert", this);
            actionInvert->setCheckable(true);
            connect(actionInvert, &QAction::toggled, [=](bool checked) { this->on_actionInvert_toggled(checked); });
        
            m_toolBar = addToolBar("Toolbar");
            m_toolBar->addAction(actionQuit);
            m_toolBar->addSeparator();
            m_toolBar->addAction(m_actionItem);
            m_toolBar->addSeparator();
            m_toolBar->addAction(actionInvert);
        }
        
        void MainWindow::on_actionInvert_toggled(bool checked)
        {
            qInfo() << checked;
        
            m_actionItem->setProperty("invertItem", checked);
        }
        

        what am i missing?

        "If you've met one individual with autism, you've met one individual with autism." - Stephen Shore

        JonBJ 1 Reply Last reply
        0
        • NotNypicalN NotNypical

          "Customizing Using Dynamic Properties" is the way to go , but how to do it right?

          #include "mainwindow.h"
          
          #include <QDebug>
          #include <QStyle>
          #include <QToolBar>
          
          
          MainWindow::MainWindow(QWidget *parent)
              : QMainWindow(parent)
          {
              setStyleSheet("*[invertItem=true] { text-decoration: line-through }");
          
              QAction *actionQuit = new QAction("Quit", this);
              connect(actionQuit, &QAction::triggered, this, &MainWindow::close);
          
              m_actionItem = new QAction("Item", this);
              m_actionItem->setProperty("invertItem", false);
          
              QAction *actionInvert = new QAction("Invert", this);
              actionInvert->setCheckable(true);
              connect(actionInvert, &QAction::toggled, [=](bool checked) { this->on_actionInvert_toggled(checked); });
          
              m_toolBar = addToolBar("Toolbar");
              m_toolBar->addAction(actionQuit);
              m_toolBar->addSeparator();
              m_toolBar->addAction(m_actionItem);
              m_toolBar->addSeparator();
              m_toolBar->addAction(actionInvert);
          }
          
          void MainWindow::on_actionInvert_toggled(bool checked)
          {
              qInfo() << checked;
          
              m_actionItem->setProperty("invertItem", checked);
          }
          

          what am i missing?

          JonBJ Online
          JonBJ Online
          JonB
          wrote on last edited by JonB
          #4

          @NotNypical
          At a glance, have you remembered that after changing the value of a dynamic property you have to polish() any widgets using it? If not it does not update, if that's what you're seeing?

          That was in the link @Christian-Ehrlicher gave you:

          Limitations

          There are limitations to using this trick. The main one is that the style will not update itself automatically when the value of a property referenced from the style sheet changes. Instead, you must manually trigger an update of the visual appearance of a widget when a styled property changes. For example:

          myLineEdit->setProperty("urgent", true); myLineEdit->style()->unpolish(myLineEdit); myLineEdit->style()->polish(myLineEdit);

          Note that this must be done in the widget to which the style was applied. QStyle::polish accepts either a QWidget or a QApplication as a parameter.

          In my (old, Python) code I defined:

          def widgetPropertyChanged(widget: QWidget):
              # Whenever a widget property is changed
              # (widget.setProperty() or something like QLineEdit.setReadOnly()) called to alter a property after initialisation)
              # we have to "alter" widget's stylesheet to cause Qt to refresh for the property change
              # ss = widget.styleSheet()
              # widget.setStyleSheet("/* */" + (ss if ss is not None else ""))
              # widget.setStyleSheet(ss)
              widget.style().unpolish(widget)
              widget.style().polish(widget)
          
          NotNypicalN 1 Reply Last reply
          0
          • JonBJ JonB

            @NotNypical
            At a glance, have you remembered that after changing the value of a dynamic property you have to polish() any widgets using it? If not it does not update, if that's what you're seeing?

            That was in the link @Christian-Ehrlicher gave you:

            Limitations

            There are limitations to using this trick. The main one is that the style will not update itself automatically when the value of a property referenced from the style sheet changes. Instead, you must manually trigger an update of the visual appearance of a widget when a styled property changes. For example:

            myLineEdit->setProperty("urgent", true); myLineEdit->style()->unpolish(myLineEdit); myLineEdit->style()->polish(myLineEdit);

            Note that this must be done in the widget to which the style was applied. QStyle::polish accepts either a QWidget or a QApplication as a parameter.

            In my (old, Python) code I defined:

            def widgetPropertyChanged(widget: QWidget):
                # Whenever a widget property is changed
                # (widget.setProperty() or something like QLineEdit.setReadOnly()) called to alter a property after initialisation)
                # we have to "alter" widget's stylesheet to cause Qt to refresh for the property change
                # ss = widget.styleSheet()
                # widget.setStyleSheet("/* */" + (ss if ss is not None else ""))
                # widget.setStyleSheet(ss)
                widget.style().unpolish(widget)
                widget.style().polish(widget)
            
            NotNypicalN Offline
            NotNypicalN Offline
            NotNypical
            wrote on last edited by
            #5

            @JonB

            m_actionItem is not a widget, it's an action. so how do i polish an action?

            "If you've met one individual with autism, you've met one individual with autism." - Stephen Shore

            JonBJ 1 Reply Last reply
            0
            • NotNypicalN NotNypical

              @JonB

              m_actionItem is not a widget, it's an action. so how do i polish an action?

              JonBJ Online
              JonBJ Online
              JonB
              wrote on last edited by JonB
              #6

              @NotNypical
              When you wrote earlier

              what am i missing?

              without any comment at all as to what was/was not happening which you did/did not expect. So I have no idea what your issue is, if any. I don't even know what behaviour you are or are not seeing.

              If the object you are setting a property on is not a widget, what is a stylesheet testing the property going to do?

              If it's to work at all, maybe you need to polish the app/main window/menu/toolbar, I don't know.

              Maybe I'm mistaken, so I'll back out now....

              P.S.
              I think the first thing I would try is:

                  m_actionItem = new QAction("Item", this);
                  m_actionItem->setProperty("invertItem", true);
                  ...
                  m_toolBar->addAction(m_actionItem);
              

              Note I have set it to true before adding it. This eliminates changing the dynamic property. I'm thinking/hoping this should work because it's before adding the action to the menu/showing it. This needs to work right before you worry about altering it dynamically, I don't know whether it does or not.

              NotNypicalN 1 Reply Last reply
              0
              • JonBJ JonB

                @NotNypical
                When you wrote earlier

                what am i missing?

                without any comment at all as to what was/was not happening which you did/did not expect. So I have no idea what your issue is, if any. I don't even know what behaviour you are or are not seeing.

                If the object you are setting a property on is not a widget, what is a stylesheet testing the property going to do?

                If it's to work at all, maybe you need to polish the app/main window/menu/toolbar, I don't know.

                Maybe I'm mistaken, so I'll back out now....

                P.S.
                I think the first thing I would try is:

                    m_actionItem = new QAction("Item", this);
                    m_actionItem->setProperty("invertItem", true);
                    ...
                    m_toolBar->addAction(m_actionItem);
                

                Note I have set it to true before adding it. This eliminates changing the dynamic property. I'm thinking/hoping this should work because it's before adding the action to the menu/showing it. This needs to work right before you worry about altering it dynamically, I don't know whether it does or not.

                NotNypicalN Offline
                NotNypicalN Offline
                NotNypical
                wrote on last edited by
                #7

                @JonB

                This works:

                void MainWindow::on_actionInvert_toggled(bool checked)
                {
                    auto widgetItem = m_toolBar->widgetForAction(m_actionItem);
                    widgetItem->setProperty("invertItem", checked);
                    widgetItem->style()->unpolish(widgetItem);
                    widgetItem->style()->polish(widgetItem);
                }
                

                https://doc.qt.io/qt-5/qtoolbar.html#widgetForAction
                It returns the widget associated with the specified action.

                Now I am looking for a solution for menu items.

                "If you've met one individual with autism, you've met one individual with autism." - Stephen Shore

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

                  Hi,

                  Why not set everything up first and the. Apply the style sheet at the end ?

                  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