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 pass "ui" object to colors class from mainwindow.cpp
QtWS25 Last Chance

How to pass "ui" object to colors class from mainwindow.cpp

Scheduled Pinned Locked Moved Unsolved General and Desktop
c++static classui objectqmainwindowparameters
12 Posts 3 Posters 4.8k 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.
  • M Offline
    M Offline
    maximo
    wrote on last edited by
    #1

    In my mainwindow.cpp, I'm reading a colors.ini out of my resource file and colorizing my widgets. This allows me to white label my software to multiple vendors by swapping logos and colors. However, I was wondering if there's a way to make my code more tidy so that I have like a colors.h and colors.cpp, and to pass the ui object to it so that I can interact with my widgets just as easily as I can in mainwindow.cpp, including the IntelliSense popups that occur as I type in QTCreator. For instance, I would like to be inside colors.cpp and type ui->btn and up would pop a list of my widgets starting with btn in their name.

    So, to restate this a little more clearly:

    1. Is there a way to take my mainwindow.cpp ui object and pass it to a Colors class (static class would be fine with me) in colors.cpp/colors.h?

    2. Is there a way to allow this ui object to have the same IntelliSense popups as I type that I enjoy with mainwindow.cpp?

    See, my mainwindow.cpp is already full of other stuff, and I'm trying to thin it down into more organized pieces, each clearly thought out and documented. That's why I want a place to put all this colorization stuff.

    The things I've tried cause symbols missing errors.

    1 Reply Last reply
    0
    • M Offline
      M Offline
      maximo
      wrote on last edited by maximo
      #2

      Okay, I got it to work, although perhaps you can suggest a better tactic:

      1. I created the following colors.h, and skipped the colors.cpp step:
      #include "mainwindow.h"
      #include "ui_mainwindow.h"
      
      class Colors {
      public: // class methods
          Colors(QMainWindow *mw,Ui::MainWindow *ui)
          {
              qDebug() << mw;
              qDebug() << ui;
          }
      };
      
      1. Inside mainwindow.cpp, I added this header:
      #include "colors.h"
      
      1. Then, in mainwindow.cpp, after the setupUI call in the constructor class method, I did:
      Colors *colors = new Colors(this,ui);
      
      1. I didn't have to do anything else except start redoing colors inside the Colors class, using the mw variable if I wanted to work on colors for the MainWindow, or the ui variable if I wanted to work on colors through the ui object.
      1 Reply Last reply
      0
      • mrjjM Offline
        mrjjM Offline
        mrjj
        Lifetime Qt Champion
        wrote on last edited by
        #3

        Hi are there a reason you do not use style sheets ?
        Besides changing colors, it can change many other things. Like a logo (image)
        like
        http://thesmithfam.org/blog/2009/09/10/qt-stylesheets-tutorial/
        You can then change colors and logo without even recompile.

        You can make Color Class Friend of QMainwinow, and it will be able to use its private members.
        http://www.cprogramming.com/tutorial/friends.html

        But Im not sure why a stylesheet would not be much better. ?

        M 1 Reply Last reply
        0
        • mrjjM mrjj

          Hi are there a reason you do not use style sheets ?
          Besides changing colors, it can change many other things. Like a logo (image)
          like
          http://thesmithfam.org/blog/2009/09/10/qt-stylesheets-tutorial/
          You can then change colors and logo without even recompile.

          You can make Color Class Friend of QMainwinow, and it will be able to use its private members.
          http://www.cprogramming.com/tutorial/friends.html

          But Im not sure why a stylesheet would not be much better. ?

          M Offline
          M Offline
          maximo
          wrote on last edited by maximo
          #4

          @mrjj Good question. I had to keep putting stylesheets on every little thing, whereas with my colors class I can grab things by class and apply things in bulk. I still use stylesheets, but use my colors class to recolor what was already styled. For instance, I may have a series of buttons that are of a certain class, and unfortunately Qt doesn't allow me to put widgets in a certain class and apply a stylesheet to that class. So, my colors class loads a colors.ini in my resource file that is short and sweet. I change that little file, and the whole application changes, while not touching the other styling.

          The way I achieved "class" was to take a little-used property "accessibleDescription" and put something in there like "success", "info", "warning", "danger" (if you are familiar with how Twitter Bootstrap does their color classes). Then, my colors class grabs all the buttons, looks at that property, applies the appropriate color combination from that, and then removes the accessibleDescription value. So, as I draw a widget on a page, I can say, "Oh, well, I'm adding something -- this is an add function button, so I'll want to apply the 'success' style to it," or, I can say, "On this button, I'm removing something, so I'll want to apply the 'danger' style to it."

          It would be nice if a future version of Qt would have a class property on each widget. That way, we could make a global stylesheet where I could take buttons of say, class 'danger', and make them all red. Lacking that, I came up with another system.

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

            Hi,

            You might be interested by this article

            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
            1
            • M maximo

              @mrjj Good question. I had to keep putting stylesheets on every little thing, whereas with my colors class I can grab things by class and apply things in bulk. I still use stylesheets, but use my colors class to recolor what was already styled. For instance, I may have a series of buttons that are of a certain class, and unfortunately Qt doesn't allow me to put widgets in a certain class and apply a stylesheet to that class. So, my colors class loads a colors.ini in my resource file that is short and sweet. I change that little file, and the whole application changes, while not touching the other styling.

              The way I achieved "class" was to take a little-used property "accessibleDescription" and put something in there like "success", "info", "warning", "danger" (if you are familiar with how Twitter Bootstrap does their color classes). Then, my colors class grabs all the buttons, looks at that property, applies the appropriate color combination from that, and then removes the accessibleDescription value. So, as I draw a widget on a page, I can say, "Oh, well, I'm adding something -- this is an add function button, so I'll want to apply the 'success' style to it," or, I can say, "On this button, I'm removing something, so I'll want to apply the 'danger' style to it."

              It would be nice if a future version of Qt would have a class property on each widget. That way, we could make a global stylesheet where I could take buttons of say, class 'danger', and make them all red. Lacking that, I came up with another system.

              mrjjM Offline
              mrjjM Offline
              mrjj
              Lifetime Qt Champion
              wrote on last edited by mrjj
              #6

              @maximo
              Hi
              Well you can do the same with style sheet. If you apply stylesheet to mainwindow, its
              applies to all widgets within. You can define By class, like sample where
              its all QFrame and subtypes. If you made your own frame, like HappyFrame, you could use that
              as Type also to have it apply to all of that type.
              Here we also say, must to named "TestDisplayFrame" and
              have the dynamic property error set to true.
              So you can group/mass apply with stylesheets.

              QFrame#TestDisplayFrame[error="true"]
              {
              background-color: red;
              border: 2px solid rgba(205, 92, 92, 255);
              border-radius: 20px;
              }

              So you can easy get all of class danger, by use its Type. And if its mixed widget you can use
              the [error="true"] where you just use your own property , that you can easy define in Designer and then
              use in stylesheet. So it can do it already :)

              M 1 Reply Last reply
              0
              • mrjjM mrjj

                @maximo
                Hi
                Well you can do the same with style sheet. If you apply stylesheet to mainwindow, its
                applies to all widgets within. You can define By class, like sample where
                its all QFrame and subtypes. If you made your own frame, like HappyFrame, you could use that
                as Type also to have it apply to all of that type.
                Here we also say, must to named "TestDisplayFrame" and
                have the dynamic property error set to true.
                So you can group/mass apply with stylesheets.

                QFrame#TestDisplayFrame[error="true"]
                {
                background-color: red;
                border: 2px solid rgba(205, 92, 92, 255);
                border-radius: 20px;
                }

                So you can easy get all of class danger, by use its Type. And if its mixed widget you can use
                the [error="true"] where you just use your own property , that you can easy define in Designer and then
                use in stylesheet. So it can do it already :)

                M Offline
                M Offline
                maximo
                wrote on last edited by
                #7

                @mrjj said:

                So you can easy get all of class danger, by use its Type. And if its mixed widget you can use
                the [error="true"] where you just use your own property , that you can easy define in Designer and then
                use in stylesheet. So it can do it already :)

                Interesting. I'm still a bit new to Qt. What's a "mixed widget"? How do I set "my own property" easily in the Designer? So there's an ability to add a custom property to a widget in the Designer that I can then edit the value on? If so, I could create one called widgetClass where I can use a MainWindow Stylesheet to adjust it.

                mrjjM 1 Reply Last reply
                0
                • M maximo

                  @mrjj said:

                  So you can easy get all of class danger, by use its Type. And if its mixed widget you can use
                  the [error="true"] where you just use your own property , that you can easy define in Designer and then
                  use in stylesheet. So it can do it already :)

                  Interesting. I'm still a bit new to Qt. What's a "mixed widget"? How do I set "my own property" easily in the Designer? So there's an ability to add a custom property to a widget in the Designer that I can then edit the value on? If so, I could create one called widgetClass where I can use a MainWindow Stylesheet to adjust it.

                  mrjjM Offline
                  mrjjM Offline
                  mrjj
                  Lifetime Qt Champion
                  wrote on last edited by mrjj
                  #8

                  @maximo
                  By mixed, I mean Like the following situation:
                  You have 15 Labels. Only some of them you want to change color of.
                  If you do
                  QLabel {
                  background-color: rgb(170, 85, 127);
                  }

                  All of them will change.

                  Then you can use their Objectname (set in designer)
                  QLabel#label_2{
                  background-color: rgb(170, 85, 127);
                  }
                  QLabel#label_3{
                  background-color: rgb(170, 85, 127);
                  }
                  ..
                  For those you want to change. (Case important for name!)

                  If you then need to do it more dynamic, then in Designer

                  Over the Properties List , right of "filter" is Big Green +.

                  That let you add new property, you can then check for.

                  Do read the link SGaist provided on how to update if you change this
                  Dynamic property from code to make it really update.

                  So overall you can group on ClassType, Like "All QLabels",
                  with subgroups using a dynamic property, so you can say
                  All QLabels that has DoMe=true.
                  Or simply by names, Like All QLabels, Named a and b and c

                  Not saying it is better than your color setup, but just want to note
                  that StyleSheet applies from Object set on and all subchildren and
                  does provides ways to point to which WIdgets you want to change.

                  Note: I had issues getting it to check in Designer when using dynamic properties and had to use
                  code. Might have done something wrong. But By Type and by Name works as expected in Designer.

                  M 1 Reply Last reply
                  1
                  • mrjjM mrjj

                    @maximo
                    By mixed, I mean Like the following situation:
                    You have 15 Labels. Only some of them you want to change color of.
                    If you do
                    QLabel {
                    background-color: rgb(170, 85, 127);
                    }

                    All of them will change.

                    Then you can use their Objectname (set in designer)
                    QLabel#label_2{
                    background-color: rgb(170, 85, 127);
                    }
                    QLabel#label_3{
                    background-color: rgb(170, 85, 127);
                    }
                    ..
                    For those you want to change. (Case important for name!)

                    If you then need to do it more dynamic, then in Designer

                    Over the Properties List , right of "filter" is Big Green +.

                    That let you add new property, you can then check for.

                    Do read the link SGaist provided on how to update if you change this
                    Dynamic property from code to make it really update.

                    So overall you can group on ClassType, Like "All QLabels",
                    with subgroups using a dynamic property, so you can say
                    All QLabels that has DoMe=true.
                    Or simply by names, Like All QLabels, Named a and b and c

                    Not saying it is better than your color setup, but just want to note
                    that StyleSheet applies from Object set on and all subchildren and
                    does provides ways to point to which WIdgets you want to change.

                    Note: I had issues getting it to check in Designer when using dynamic properties and had to use
                    code. Might have done something wrong. But By Type and by Name works as expected in Designer.

                    M Offline
                    M Offline
                    maximo
                    wrote on last edited by
                    #9

                    @mrjj said:

                    I had issues getting it to check in Designer when using dynamic properties and had to use
                    code.

                    Yeah, I see what you mean. I tried getting the stylesheet to recognize my dynamic property and it just wouldn't do it. I then tried to set the stylesheet from code on the main window, pulling from a CSS in a resource file, and the moment I used QPushButton[buttonClass="danger"]{ blah blah} , it generated a non-fatal runtime error (but still load) that said something like, "could not parse stylesheet for object [some hex number]". I think this is because I need to do the steps for QPROPERTY(), and that looked confusing and difficult for every button on my form, and more work than the way I was doing it in my colors class. Diminishing returns.

                    So, I went back to doing it my code way where I read a colors.ini file from the resource file, and then apply that to the objects in a colors class. However, because you showed me how to do a dynamic property, I was able to use this dynamic property in code with .property("buttonClass").toString() so that I didn't have to kludge it by using .accessibleDescription(). So, thanks! :)

                    mrjjM 1 Reply Last reply
                    0
                    • M maximo

                      @mrjj said:

                      I had issues getting it to check in Designer when using dynamic properties and had to use
                      code.

                      Yeah, I see what you mean. I tried getting the stylesheet to recognize my dynamic property and it just wouldn't do it. I then tried to set the stylesheet from code on the main window, pulling from a CSS in a resource file, and the moment I used QPushButton[buttonClass="danger"]{ blah blah} , it generated a non-fatal runtime error (but still load) that said something like, "could not parse stylesheet for object [some hex number]". I think this is because I need to do the steps for QPROPERTY(), and that looked confusing and difficult for every button on my form, and more work than the way I was doing it in my colors class. Diminishing returns.

                      So, I went back to doing it my code way where I read a colors.ini file from the resource file, and then apply that to the objects in a colors class. However, because you showed me how to do a dynamic property, I was able to use this dynamic property in code with .property("buttonClass").toString() so that I didn't have to kludge it by using .accessibleDescription(). So, thanks! :)

                      mrjjM Offline
                      mrjjM Offline
                      mrjj
                      Lifetime Qt Champion
                      wrote on last edited by
                      #10

                      @maximo
                      Well, i did try the
                      style()->unpolish();
                      style()->polish();
                      for Mainwindow but ended up checking the dynamic property
                      in code and then assign a single style sheet to those I had flagged.
                      Maybe you are right and it must be for widgets for it to work.

                      Btw if you ever need to do something to all Widgets, its not that much code.

                      QList<QWidget *> widgets = findChildren<QWidget *>();
                      foreach (QWidget* b, widgets) {
                      b->SOMETHING
                      }
                      

                      and you can replace QWidget * with say QPushButton * to get all buttons.

                      Anyways, good that you found use for Dynamic Properties.

                      M 1 Reply Last reply
                      0
                      • mrjjM mrjj

                        @maximo
                        Well, i did try the
                        style()->unpolish();
                        style()->polish();
                        for Mainwindow but ended up checking the dynamic property
                        in code and then assign a single style sheet to those I had flagged.
                        Maybe you are right and it must be for widgets for it to work.

                        Btw if you ever need to do something to all Widgets, its not that much code.

                        QList<QWidget *> widgets = findChildren<QWidget *>();
                        foreach (QWidget* b, widgets) {
                        b->SOMETHING
                        }
                        

                        and you can replace QWidget * with say QPushButton * to get all buttons.

                        Anyways, good that you found use for Dynamic Properties.

                        M Offline
                        M Offline
                        maximo
                        wrote on last edited by
                        #11

                        @mrjj said:

                        Btw if you ever need to do something to all Widgets

                        Yep, I use that very technique in my colors class to iterate the widgets.

                        mrjjM 1 Reply Last reply
                        0
                        • M maximo

                          @mrjj said:

                          Btw if you ever need to do something to all Widgets

                          Yep, I use that very technique in my colors class to iterate the widgets.

                          mrjjM Offline
                          mrjjM Offline
                          mrjj
                          Lifetime Qt Champion
                          wrote on last edited by mrjj
                          #12

                          @maximo
                          Ok :)
                          I am going to test again with stylesheets.
                          It would be very nice it it worked as docs says.
                          Or at least to understand why it did not.

                          Update:
                          Ok, one must unpolish/ polish each widget as doing it to
                          Mainwindow doesn't seems to work.
                          But it also works with
                          setStyleSheet(styleSheet());
                          in MainWindow to reload (whole) style sheet.

                          Update 2:
                          Ok. Having qframes with bool error property.
                          It will update in Designer, if setting it.
                          No code. Sheet on MWindow.
                          So it does work with properties it seems.

                          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