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. Changing Q_PROPERTY in pseudo state of a widget stylesheet does not notify

Changing Q_PROPERTY in pseudo state of a widget stylesheet does not notify

Scheduled Pinned Locked Moved Unsolved General and Desktop
qproperty
8 Posts 2 Posters 3.4k 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.
  • A Offline
    A Offline
    Arie
    wrote on 10 Feb 2016, 10:46 last edited by
    #1

    Hi,

    I customized QLineEdit by deriving from it. Then added an action and set an icon. The icon is set via a propery in the stylesheet.
    For the read-only pseudo state of the line edit, another icon must be selected. The stylesheet defines this by having a different value for the icon property at the read-only state.

    The icon property has a notify function that signals the IconChanged function.
    ClearIconChanged is called once at initialization but not when the widget is set to read-only later.

    For testing I defined in the stylesheet a green background color for the read-only state. This works, the background color changes when toggling read-only.

    Class:

    class QMyLineEdit : public QLineEdit
    {
        Q_OBJECT
        Q_PROPERTY( QString action_icon MEMBER m_strIcon NOTIFY IconChanged )
    
    public:
        explicit QMyLineEdit( QWidget* parent )
    		: QLineEdit( parent )
    		, m_pAction( nullptr )
    	{
    		m_pAction = new QAction( this );
    		connect( m_pClearAction, &QAction::triggered, this, &QMyLineEdit::MyAction );
    		addAction( m_pAction, QLineEdit::TrailingPosition );
    		connect( this, &QMyLineEdit::IconChanged, this, &QMyLineEdit::UpdateIcon );
    	}
    
    private:
        QAction* m_pAction;
        QString  m_strIcon;
    
    signals:
        void IconChanged();
    
    private slots:
        void UpdateIcon()
    	{
    		QIcon ClearIcon( m_strClearIcon );
    		m_pAction->setIcon( ClearIcon );
    	}
    	
        void MyAction()
    	{
    		/* ... */
    	}  
    };
    

    Stylesheet

    .QMyLineEdit {
        qproperty-action_icon: url(:/Widgets/action.png);
    }
    
    .QMyLineEdit:read-only {
        background-color: green;
        qproperty-action_icon: url(:/Widgets/action_readonly.png);
    }
    

    Now my questions.

    Are changing properties in a pseudo state supported?
    What is the common way to get such behavior?

    1 Reply Last reply
    0
    • K Offline
      K Offline
      kshegunov
      Moderators
      wrote on 10 Feb 2016, 12:44 last edited by kshegunov 2 Oct 2016, 12:44
      #2

      @Arie
      You have to raise the signal on your own.

      void UpdateIcon()
      {
          QIcon ClearIcon( m_strClearIcon );
          m_pAction->setIcon( ClearIcon );
          emit IconChanged(); //< Did you forget this?
      }
      

      Kind regards.

      Read and abide by the Qt Code of Conduct

      1 Reply Last reply
      0
      • A Offline
        A Offline
        Arie
        wrote on 10 Feb 2016, 15:49 last edited by
        #3

        I believed NOTIFY means that Qt emits the signal when the property was changed.

        Now I changed the property definition to

        Q_PROPERTY( QString action_icon READ GetActionIcon WRITE SetActionIcon )
        

        so I can debug when its read and written.

        The breakpoints were hit on initialization, the property was read once before it was set and later it was set with the default (non-pseudo state value). They were not hit when the state changed.

        K 1 Reply Last reply 10 Feb 2016, 15:53
        0
        • A Arie
          10 Feb 2016, 15:49

          I believed NOTIFY means that Qt emits the signal when the property was changed.

          Now I changed the property definition to

          Q_PROPERTY( QString action_icon READ GetActionIcon WRITE SetActionIcon )
          

          so I can debug when its read and written.

          The breakpoints were hit on initialization, the property was read once before it was set and later it was set with the default (non-pseudo state value). They were not hit when the state changed.

          K Offline
          K Offline
          kshegunov
          Moderators
          wrote on 10 Feb 2016, 15:53 last edited by
          #4

          @Arie
          If you use MEMBER you specify the READ, WRITE and NOTIFY and the moc will generate those for you. If you don't use MEMBER you specify READ, WRITE and NOTIFY and implement them yourself.

          Read and abide by the Qt Code of Conduct

          A 1 Reply Last reply 10 Feb 2016, 16:28
          0
          • K kshegunov
            10 Feb 2016, 15:53

            @Arie
            If you use MEMBER you specify the READ, WRITE and NOTIFY and the moc will generate those for you. If you don't use MEMBER you specify READ, WRITE and NOTIFY and implement them yourself.

            A Offline
            A Offline
            Arie
            wrote on 10 Feb 2016, 16:28 last edited by
            #5

            @kshegunov
            I think my last version of Q_PROPERTY definition is right. If somehow the property changes, it must call the SetActionIcon function.

            But why is SetActionIcon function not called when toggling the read-only pseudo state of QMyLineEdit?

            K 1 Reply Last reply 10 Feb 2016, 16:35
            0
            • A Arie
              10 Feb 2016, 16:28

              @kshegunov
              I think my last version of Q_PROPERTY definition is right. If somehow the property changes, it must call the SetActionIcon function.

              But why is SetActionIcon function not called when toggling the read-only pseudo state of QMyLineEdit?

              K Offline
              K Offline
              kshegunov
              Moderators
              wrote on 10 Feb 2016, 16:35 last edited by
              #6

              @Arie
              Maybe there's some confusion. You either do this:

              Q_PROPERTY( QString action_icon MEMBER m_icon READ GetActionIcon WRITE SetActionIcon NOTIFY actionChanged)
              

              and when SetActionIcon is called the actionChanged will be emitted.

              Or you do it like this:

              class QMyLineEdit : public QLineEdit
              {
                  Q_PROPERTY( QString action_icon READ GetActionIcon WRITE SetActionIcon NOTIFY actionChanged)
                  // ...
              };
              
              QString QMyLineEdit::GetActionIcon()
              {
                  return m_icon;
              }
              
              void QMyLineEdit::SetActionIcon(const QString & icon)
              {
                  m_icon = icon;
                  emit actionChanged();
              }
              

              In any case emitting actionChanged() will not trigger SetActionIcon, because it's to notify others that the property has changed, not the other way around.

              Kind regards.

              Read and abide by the Qt Code of Conduct

              A 1 Reply Last reply 11 Feb 2016, 09:47
              0
              • K kshegunov
                10 Feb 2016, 16:35

                @Arie
                Maybe there's some confusion. You either do this:

                Q_PROPERTY( QString action_icon MEMBER m_icon READ GetActionIcon WRITE SetActionIcon NOTIFY actionChanged)
                

                and when SetActionIcon is called the actionChanged will be emitted.

                Or you do it like this:

                class QMyLineEdit : public QLineEdit
                {
                    Q_PROPERTY( QString action_icon READ GetActionIcon WRITE SetActionIcon NOTIFY actionChanged)
                    // ...
                };
                
                QString QMyLineEdit::GetActionIcon()
                {
                    return m_icon;
                }
                
                void QMyLineEdit::SetActionIcon(const QString & icon)
                {
                    m_icon = icon;
                    emit actionChanged();
                }
                

                In any case emitting actionChanged() will not trigger SetActionIcon, because it's to notify others that the property has changed, not the other way around.

                Kind regards.

                A Offline
                A Offline
                Arie
                wrote on 11 Feb 2016, 09:47 last edited by Arie 2 Nov 2016, 15:02
                #7

                @kshegunov
                I think too there is some confusion.
                This is the updated version of the class. QPROPERTY now only takes READ and WRITE functions, NOTIFY is left out.

                class QMyLineEdit : public QLineEdit
                {
                    Q_OBJECT
                    Q_PROPERTY( QString action_icon READ GetIcon WRITE SetIcon )
                
                public:
                    explicit QMyLineEdit( QWidget* parent )
                		: m_pAction( nullptr )
                	{
                		m_pAction = new QAction( this );
                		connect( m_pAction, &QAction::triggered, this, &QMyLineEdit::MyAction );
                		addAction( m_pAction, QLineEdit::TrailingPosition );
                	}
                
                private:
                    QAction* m_pAction;
                    QString  m_strIcon;
                
                    const QString& GetIcon() const
                    {	/* Breakpoint hit at initialization, before SetIcon */
                        return m_strClearIcon;
                    }
                    
                    void SetIcon( const QString& strIcon )
                	{	/* Breakpoint hit at initialization but not when read-only was
                		 * toggled via QLineEdit::setReadOnly() */
                		m_strIcon = strIcon;
                		QIcon Icon( m_strIcon );
                		m_pAction->setIcon( Icon );
                	}
                    
                    void MyAction(){ /* ... */ } 
                };
                

                The stylesheet part remained same.

                .QMyLineEdit {
                    qproperty-action_icon: url(:/Widgets/action.png);
                }
                
                .QMyLineEdit:read-only {
                    background-color: green;
                    qproperty-action_icon: url(:/Widgets/action_readonly.png);
                }
                

                In short my issue: Toggling read-only with setReadOnly( bool ) toggles the background color but not my action's icon.

                1 Reply Last reply
                0
                • A Offline
                  A Offline
                  Arie
                  wrote on 15 Feb 2016, 13:11 last edited by
                  #8

                  Any other idea why the WRITE function is not called at the widget’s pseudo state change when the stylesheet has different qproperty values defined for the states?

                  1 Reply Last reply
                  0

                  1/8

                  10 Feb 2016, 10:46

                  • 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