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. [Solved] Dynamically change (via code) the properties of various widgets created on Designer
Forum Updated to NodeBB v4.3 + New Features

[Solved] Dynamically change (via code) the properties of various widgets created on Designer

Scheduled Pinned Locked Moved General and Desktop
14 Posts 4 Posters 7.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.
  • F Offline
    F Offline
    fredlord
    wrote on last edited by
    #1

    I've used Design to create my interface - it was easy and optimal for me (i'm a begginer at Qt and the interface is a little complex)

    So, i know that i can get a reference to any widget created on Design by using i.e. ui->nameOfObject->pos();

    But is there a way to dynamically change the properties of various widgtes by code? Let's say i have 10 buttons, with the name's being: button1, button2, button3, button4, etc.

    Can't i just use something like

    @for(int i=0;i<=10;i++) {
    pos[i] = ui->"button"+i->pos.x
    }@

    Or the one and only way is by hard-coding each ui at one time?

    @pos[0] = ui->button1->pos.x;
    pos[1] = ui->button2->pos.x;
    pos[2] = ui->button3->pos.x;@

    The above method "works" but anyone can see that this is not optimal at all. Of course the method with the for loop won't work the way i posted it. Its just a "pseudo-code" to try to translate what i am hoping to achieve...

    PS: In my actual code i have 32 buttons, not only 10..... And i want to change the icon of each one back and forth according to some rules...

    Any help will be appreciated

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

      What type of properties are you trying to change? There's a chance that there might be an easier way to approach it even beyond what you've proposed here.

      Software Engineer
      My views and opinions do not necessarily reflect those of anyone -- living or dead, real or fictional -- in this universe or any other similar multiverse node. Void where prohibited. Your mileage may vary. Caveat emptor.

      1 Reply Last reply
      0
      • F Offline
        F Offline
        fredlord
        wrote on last edited by
        #3

        [quote author="mlong" date="1334094350"]What type of properties are you trying to change? There's a chance that there might be an easier way to approach it even beyond what you've proposed here.

        [/quote]

        Hi mlong,

        Basically i want to change the icon (image) of some of those buttons.
        I'm changing them with
        @ui->button3->setIcon(icon1);@

        But i think it's not something i'll achieve just on Designer (on Disabled Off, Disabled On, Active Off, Active On, etc) 'cause i have some rules for changing these icons. That's why i want to do this by code (rules like "timers" or "the order that the user pressed each button", etc.

        1 Reply Last reply
        0
        • M Offline
          M Offline
          mlong
          wrote on last edited by
          #4

          I'm still not sure what you're trying to accomplish. By using
          @
          ui->button1->...
          @
          or whatever to reference your widgets you do have access to your items in code and can do whatever you'd like.

          If you're saying you'd like an array of widgets to work with, the easiest thing might be to have
          @
          QList<QPushButton *> m_buttonlist;

          ...

          m_buttonlist.append(ui->button0);
          m_buttonlist.append(ui->button1);
          ...
          m_buttonlist.append(ui->buttonN);
          @
          and then you can reference an individual button with
          @
          m_buttonlist[idx]->whatever();
          @

          If you're trying to avoid the 1-time manual setup of that array, you could use something like this (I think) to automate it:
          @
          for (int idx = 0; idx < numbuttons; idx++) {
          QString name = QString("button%1").arg(idx);
          QPushButton * button = ui->findChild<QPushButton>(name);
          if (button) {
          m_buttonlist.append(button);
          }
          }
          @
          (brain to terminal.. consult your friendly "docs":http://qt-project.org/doc/qt-4.8/qobject.html#findChild for exact details on how to do this).

          Software Engineer
          My views and opinions do not necessarily reflect those of anyone -- living or dead, real or fictional -- in this universe or any other similar multiverse node. Void where prohibited. Your mileage may vary. Caveat emptor.

          1 Reply Last reply
          0
          • H Offline
            H Offline
            Hostel
            wrote on last edited by
            #5

            You can try this:
            @
            QObjectList childrens = this->children(); // this is a widget which use your ui file
            foreach( QObject* obj, childrens )
            {
            QPushButton* button = qobject_cast< QPushButton* >( obj );
            if( button )
            {
            // action on button
            }
            }
            @

            1 Reply Last reply
            0
            • A Offline
              A Offline
              andre
              wrote on last edited by
              #6

              Or, you do:
              @
              QList<QPushButton*> buttons = findChildren<QPushButton*>();
              foreach { QPushButton * button, buttons) {
              // action on button
              }
              @

              Slightly shorter than Hostel's version above :-)

              If you want, you can restrict such a list to buttons marked from designer, by setting a custom dynamic property, and checking for that property in the loop above. Of course, you can combine this idea with mlongs's suggestion of builiding up a list of widgets, and then using that list. I would not use the button name for this though.

              1 Reply Last reply
              0
              • F Offline
                F Offline
                fredlord
                wrote on last edited by
                #7

                Thanks to all!

                Yesterday i was using the first approach from mlong just to create and test the list of widgets - to see if i'd be able to manipulate them easily... and it worked.

                Now to automate it i'm using Andre's version... one thing is that i didn't wanted every button to be added to that list - just some of them. So i've try to "set a custom dynamic property" and "check for that property in the loop" as suggested, and it worked.

                Actually, i didn't SET any different property - i've just used the actual width of the button:

                @QList<QPushButton*> buttons = findChildren<QPushButton*>();
                foreach ( QPushButton * button, buttons) {
                if(button->width()==20)
                m_buttonlist.append(button);
                }@

                And this works for me.. now, i don't know if any of you guys would suggest the use of another property for this check, for some reason. If that's the case, please - let me know!

                Thanks again!

                =====
                Actually, i've noticed a little "problem" now. My QList is reversed (at least to what i'd expected).
                (button32,button31,button30,button29, ... , etc, button1, button0)

                What can i do to re-reverse this? Some extra configuration in the loop, or it is easier to just reverse the QList somehow?

                1 Reply Last reply
                0
                • A Offline
                  A Offline
                  andre
                  wrote on last edited by
                  #8

                  Why does the order of the list matter?

                  There is no way to control the order in which findChildren will return its results. Because the contents of the list are pointers, just sorting is useless as well. Note that even sorting on button name will result in a different order than you want, as button10 would be sorted before button2.

                  I would not abuse another property for identification purposes. It makes the feature hard to track, and easy to break. How will somebody else working on your code know that the width is relevant in some other way than just the width? What if you decide to change your layout a bit? Or what if the users style forces a larger or smaller button?

                  1 Reply Last reply
                  0
                  • F Offline
                    F Offline
                    fredlord
                    wrote on last edited by
                    #9

                    Yes, that crossed my mind.. that's why i asked if anyone could suggest another way or property to this. I have 42 buttons on my interface, and i want to create a QList with just 32 (the smaller, 20-width ones). The current solution works, but it is certainly not optimal.

                    And why does the order of the list matter... correct me if i'm wrong, but i'll access the items of that list by index. That's what i did with the first solution

                    @QList<QPushButton *> m_buttonlist;

                    ...

                    m_buttonlist.append(ui->button0);
                    m_buttonlist.append(ui->button1);
                    ...
                    m_buttonlist.append(ui->buttonN);@

                    and, of course, it worked. I was just changing to this new version to clean it up a bit my code... maybe the "manual version" is, in the end, optimal for my needs?

                    [quote author="Andre" date="1334152754"]Why does the order of the list matter?

                    There is no way to control the order in which findChildren will return its results. Because the contents of the list are pointers, just sorting is useless as well. Note that even sorting on button name will result in a different order than you want, as button10 would be sorted before button2.

                    I would not abuse another property for identification purposes. It makes the feature hard to track, and easy to break. How will somebody else working on your code know that the width is relevant in some other way than just the width? What if you decide to change your layout a bit? Or what if the users style forces a larger or smaller button? [/quote]

                    1 Reply Last reply
                    0
                    • A Offline
                      A Offline
                      andre
                      wrote on last edited by
                      #10

                      The manual version of adding the controls to a list certainly is a serious option. It gives you full control over the order of the list, and it really isn't that much work. A bit of copy/pasting and a little editing does the trick. Note that you can also use the << operator on the list for a shorter notation:

                      Instead of
                      @QList<QPushButton *> m_buttonlist;

                      ...

                      m_buttonlist.append(ui->button0);
                      m_buttonlist.append(ui->button1);
                      ...
                      m_buttonlist.append(ui->buttonN);@
                      you can write
                      @QList<QPushButton *> m_buttonlist;

                      ...

                      m_buttonlist << ui->button0
                      << ui->button1
                      //...
                      << ui->buttonN;
                      @

                      I was wondering what the order of the items in the list matters for, yes. Of course you'll use the index to get to the pointer, but the question is if you need to do something different based on what button you are addressing. So far, nothing you said indicated that that was the case. If it is, then of course, the index matters.

                      1 Reply Last reply
                      0
                      • F Offline
                        F Offline
                        fredlord
                        wrote on last edited by
                        #11

                        Hi Andre,

                        Thanks for your help and explanations. I'll stick to the manual version then, using the << operator as you suggested. With this i'll even avoid that "width check" that was troubling me too.

                        It is wonderful to have support from guys like you here,
                        Thanks

                        1 Reply Last reply
                        0
                        • M Offline
                          M Offline
                          mlong
                          wrote on last edited by
                          #12

                          Glad you've found a solution that works for you. Just goes to show that there often a number of different ways to accomplish something, and you just have to judge the best option that works for you.

                          As an aside, I hope that you're not needing the array of buttons to help track which buttons were clicked, etc. If so, you may also want to look into "QSignalMapper":/doc/qt-4.8/qsignalmapper.html to help handle some of that work more efficiently.

                          Software Engineer
                          My views and opinions do not necessarily reflect those of anyone -- living or dead, real or fictional -- in this universe or any other similar multiverse node. Void where prohibited. Your mileage may vary. Caveat emptor.

                          1 Reply Last reply
                          0
                          • A Offline
                            A Offline
                            andre
                            wrote on last edited by
                            #13

                            Even for setting up a QSignalHandler, an array like the one constructed in this topic will be very useful :-)

                            1 Reply Last reply
                            0
                            • M Offline
                              M Offline
                              mlong
                              wrote on last edited by
                              #14

                              bq. Even for setting up a QSignalHandler, an array like the one constructed in this topic will be very useful :-)

                              Indeed, but trying to do signal handling manually can be a bear. Just saying that if he needed to take that additional step, then the QSignalHandler could be a potential help.

                              Software Engineer
                              My views and opinions do not necessarily reflect those of anyone -- living or dead, real or fictional -- in this universe or any other similar multiverse node. Void where prohibited. Your mileage may vary. Caveat emptor.

                              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