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. Updating widget stylesheet in succession
Forum Updated to NodeBB v4.3 + New Features

Updating widget stylesheet in succession

Scheduled Pinned Locked Moved Unsolved General and Desktop
15 Posts 4 Posters 1.5k Views 2 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.
  • E Offline
    E Offline
    EaccB
    wrote on last edited by
    #1

    Suppose I have something like the following:

    ui->lineEdit->setStyleSheet("background-color: orange");
    ui->lineEdit->setStyleSheet("background-color: grey");

    As both are added to the event loop, will lineEdit flash orange for a split second (maybe so fast it's unnoticeable) before setting to grey?

    The above is a simplified version of a problem I'm facing. I have a series of widgets which need their stylesheet updated according to the selected row of a tableview. Upon each selection, some widgets may appear orange, while others grey. I've achieved this by do the following:

    When a row is selected, set all widgets to grey (to clear). 
    
    Set relevant widgets to orange, while others remain on grey.
    

    Is there a better way to do this?

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

      There are several levels of paranoia you can employ here, and you just need to check how much of it is enough for your case.

      AFAIK It's not documented whether the change will be instant or not. Qt is double buffered, so there's little chance you see flicker, but you may in some cases.

      So the first thing you can do is use setUpdatesEnabled(false) on the parent, apply your changes and turn updates back on which will repaint the whole thing once.

      The second thing is stylesheets are generally slow. Because of the caching they work better when set once and not changed after, but if you have to change them try to do it only where needed. So in your case if the algorithm is something like this:

      for all widgets
          set background to gray
      
      for some widgets
         set background to orange
      

      change it to

      for each widget
         if some condition
             set background to orange
         else
            set background to gray
      

      This way you only change the stylesheet once for each widget.
      Another level of optimization is checking if the widget actually needs to change its styleshet. If it's already gray there's no need to re-apply the same stylesheet, so

      for each widget
         new_state = some condition ? orange : gray
         if new_state is different than current
            set background to new_state
      

      You might think that it's a lot of extra branching in those loops, but all those checks will be nothing next to reparsing, recaching and reapplying the stylesheets.

      So as mentioned before - how much of it is enough for your case you'll have to check on your own.

      1 Reply Last reply
      2
      • E Offline
        E Offline
        EaccB
        wrote on last edited by
        #3

        So, originally, I was going to do something along the lines of:

        for each widget
          if widget is in selected tableview list
              set to orange
         else
              set to grey
        

        However, this changes the complexity to N^2 (instead of 2N). In reality, given the number of widgets (up to 50), this would probably have a negligible impact on performance. Regardless, I wondered whether it was acceptable given the circumstances.

        Also, I'll probably be moving to dynamic properties which I believe are more efficient. Would a flicker show in this case?

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

          @EaccB said:

          So, originally, I was going to do something along the lines of:

          Nah, don't do that. A pre-pass to mark the selected ones in some way is a better option.

          Also, I'll probably be moving to dynamic properties

          I'm usually skeptical about those in tight loops like this, because it's a string based dictionary lookup and a type cast (variant to whatever). Not great. I usually only use them to mark a single thing that I won't be checking too often, but you'll have to measure how much it matters to you.

          Would a flicker show in this case?

          If you use that setUpdatesEnabled method I mentioned then no. Otherwise you'll have to see for yourself, but I wouldn't rely on it. My advice is to focus on modifying only what is needed to change and only doing it once.

          1 Reply Last reply
          3
          • E Offline
            E Offline
            EaccB
            wrote on last edited by
            #5

            Might be best if I describe my actual problem in more detail.

            I have a series custom widgets which are displayed in a grid. Each widget can be either "Active" or "Inactive". This. is achieved via 2 functions, activate() and deactivate(). Amongst other things, these functions set the widget's border to orange and grey respectively.

            Back in Mainwindow, I have a table view where each row is associated with a QList which contains a struct of data which will be passed to the widget for processing (also contains a pointer to the relevant widget). If the QList for the selected row contains a struct pointing to a widget, that widget should be "Active". Everything else should be "Inactive".

            On selection of a row, I see no other way to update the widgets than checking whether every widget in the grid is present in the QList of the selected row. An alternative is to populate each QList with a struct for every widget and specify which should be active/inactive, although not too keen on this idea.

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

              Hold the pointers to the widgets in your struct so you can directly access them when the struct is moved from active to inactive and back.

              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
              0
              • E Offline
                E Offline
                EaccB
                wrote on last edited by EaccB
                #7

                I think we got out wires crossed. The structs contained in the QLists are only for widgets which should be active for that row. Setting the relevant widgets to active is trivial, as you say access them directly. Setting everything else to inactive seems to be more difficult.

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

                  Then hold the inactive ones in another QList and move them around.

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

                  E 1 Reply Last reply
                  0
                  • S Offline
                    S Offline
                    SimonSchroeder
                    wrote on last edited by
                    #9

                    How about using QWidget::setEnabled(bool) to toggle the enabled state of the widgets. The stylesheet can then have a different style for enabled and disabled states. One thing to consider here is that child widgets would inherit this state. So, this works for non-interactive widgets only (like showing text).

                    1 Reply Last reply
                    0
                    • Christian EhrlicherC Christian Ehrlicher

                      Then hold the inactive ones in another QList and move them around.

                      E Offline
                      E Offline
                      EaccB
                      wrote on last edited by
                      #10

                      @Christian-Ehrlicher

                      I'm not sure what you mean. Could you provide an example please?

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

                        Hold an additional container with the inactive ones. When you move them between the two containers you know which style to set.

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

                        E 1 Reply Last reply
                        0
                        • Christian EhrlicherC Christian Ehrlicher

                          Hold an additional container with the inactive ones. When you move them between the two containers you know which style to set.

                          E Offline
                          E Offline
                          EaccB
                          wrote on last edited by
                          #12

                          @Christian-Ehrlicher

                          In which case each row would need to have 2 QLists, one for Active and Inactive. Seems a bit redundant to store empty structs for widgets which are inactive.

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

                            @EaccB said in Updating widget stylesheet in succession:

                            Seems a bit redundant to store empty structs for widgets which are inactive.

                            I never said you should store some structs, only the pointers to the widgets. But it's up to you. If you need the information you have to store it somewhere.

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

                            E 1 Reply Last reply
                            0
                            • Christian EhrlicherC Christian Ehrlicher

                              @EaccB said in Updating widget stylesheet in succession:

                              Seems a bit redundant to store empty structs for widgets which are inactive.

                              I never said you should store some structs, only the pointers to the widgets. But it's up to you. If you need the information you have to store it somewhere.

                              E Offline
                              E Offline
                              EaccB
                              wrote on last edited by
                              #14

                              @Christian-Ehrlicher

                              How about something like this?:

                              setEnabled(false);
                              
                              for all widgets:
                                 widget.deactivate();
                              
                              for widgets in QList:
                                widget.activate();
                              
                              setEnabled(true);
                              

                              I don't think that would be terribly inefficient. What do you think?

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

                                It depends on the size but yes. Still don't understand why you can't the state when it changes from active to inactive and back.

                                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
                                1

                                • Login

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