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. Dynamic Handling of Hundreds of UI elements
Forum Updated to NodeBB v4.3 + New Features

Dynamic Handling of Hundreds of UI elements

Scheduled Pinned Locked Moved Unsolved General and Desktop
ui object
16 Posts 4 Posters 5.1k 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.
  • M Offline
    M Offline
    mrjj
    Lifetime Qt Champion
    wrote on 8 Feb 2016, 13:43 last edited by
    #4

    also be sure to check
    http://www.qtcentre.org/threads/65146-Dynamic-Handling-of-Hundreds-of-UI-elements

    1 Reply Last reply
    0
    • K kshegunov
      8 Feb 2016, 13:15

      @mrsurge
      Hello,
      For one you could make Qt do the casting for you:

      QList<QLineEdit *> list = ui->doubleSpinBox->children<QLineEdit *>();
      foreach (QLineEdit * item, list)
          item->installEventFilter(this);
      

      And then in your event filter you could connect the dialog's accepted signal to the line edit:

      bool MainWindow::eventFilter(QObject * obj, QEvent * event)
      {
          if(event->type() == QEvent::MouseButtonPress)
          {
              Dialog mdialog;
      
              QSignalMapper mapper(&mdialog);
              mapper.setMapping(qobject_cast<QWidget *>(obj));
              QObject::connect(&mdialog, SIGNAL(accepted()), &mapper, SLOT(map()));
              QObject::connect(&mapper, SIGNAL(mapped(QWidget *)), this, SLOT(saveDataToLineEdit(QWidget *)));
      
              mdialog.exec();
          }
          return false;
      }
      
      void MainWindow::saveDataToLineEdit(QWidget * widget)
      {
          QLineEdit * lineEdit = qobject_cast<QLineEdit *>(widget);
          Dialog * dialog = qobject_cast<Dialog *>(sender()->parent());
          // ... Transfer data between the dialog and the line edit here ...
      }
      

      Is this what you were asking for?

      Kind regards.

      EDIT:
      I've moved the mapper to the stack, as it's not necessary to create it with new (since you're using a modal dialog).

      M Offline
      M Offline
      mrsurge
      wrote on 9 Feb 2016, 05:19 last edited by mrsurge 2 Sept 2016, 05:21
      #5

      @kshegunov

      QList<QLineEdit *> list = ui->doubleSpinBox->children<QLineEdit *>();
      foreach (QLineEdit * item, list)
          item->installEventFilter(this);
      

      returns

      **error: 'QLineEdit' does not refer to a value
      QList<QLineEdit > list = ui->doubleSpinBox->children<QLineEdit >();

      in my compiler. Remember I may be doing something really stupid, I'm new at qt

      K 1 Reply Last reply 9 Feb 2016, 05:27
      0
      • M mrsurge
        9 Feb 2016, 05:19

        @kshegunov

        QList<QLineEdit *> list = ui->doubleSpinBox->children<QLineEdit *>();
        foreach (QLineEdit * item, list)
            item->installEventFilter(this);
        

        returns

        **error: 'QLineEdit' does not refer to a value
        QList<QLineEdit > list = ui->doubleSpinBox->children<QLineEdit >();

        in my compiler. Remember I may be doing something really stupid, I'm new at qt

        K Offline
        K Offline
        kshegunov
        Moderators
        wrote on 9 Feb 2016, 05:27 last edited by
        #6

        @mrsurge
        No, the problem is with my code, it happens sometimes when I don't double-check my examples. The proper function to use would be QObject::findChildren. I usually use it similarly to this:

        QList<QLineEdit *> list = ui->doubleSpinBox->findChildren<QLineEdit *>(QString(), Qt::FindDirectChildrenOnly);
        

        This should compile fine.

        Kind regards.

        Read and abide by the Qt Code of Conduct

        M 1 Reply Last reply 9 Feb 2016, 06:14
        0
        • K kshegunov
          9 Feb 2016, 05:27

          @mrsurge
          No, the problem is with my code, it happens sometimes when I don't double-check my examples. The proper function to use would be QObject::findChildren. I usually use it similarly to this:

          QList<QLineEdit *> list = ui->doubleSpinBox->findChildren<QLineEdit *>(QString(), Qt::FindDirectChildrenOnly);
          

          This should compile fine.

          Kind regards.

          M Offline
          M Offline
          mrsurge
          wrote on 9 Feb 2016, 06:14 last edited by mrsurge 2 Sept 2016, 06:15
          #7

          @kshegunov
          your right that did compile just fine, but it only works for doubleSpinBox not doubleSpinBox_2 - doubleSpinBox_312

          K 1 Reply Last reply 9 Feb 2016, 06:25
          0
          • M mrsurge
            9 Feb 2016, 06:14

            @kshegunov
            your right that did compile just fine, but it only works for doubleSpinBox not doubleSpinBox_2 - doubleSpinBox_312

            K Offline
            K Offline
            kshegunov
            Moderators
            wrote on 9 Feb 2016, 06:25 last edited by kshegunov 2 Sept 2016, 06:28
            #8

            @mrsurge

            Just apply the same principle:

            MainWindow::MainWindow(QWidget *parent)
                : QMainWindow(parent), ui(new Ui::MainWindow)
            {
                ui->setupUi(this);
            
                QList<QSpinBox *> sbList = findChildren<QSpinBox *>(QString(), Qt::FindDirectChildrenOnly);
                foreach (QSpinBox * spinBox, sbList)  {
                        spinBox->installEventFilter(this);  //< Do you need this??
            
                        QList<QLineEdit *> leList = spinBox->findChildren<QLineEdit *>(QString(), Qt::FindDirectChildrenOnly);
                        foreach (QLineEdit * lineEdit, leList)
                            lineEdit->installEventFilter(this);
                }
            }
            

            Read and abide by the Qt Code of Conduct

            M 1 Reply Last reply 9 Feb 2016, 18:41
            1
            • K kshegunov
              9 Feb 2016, 06:25

              @mrsurge

              Just apply the same principle:

              MainWindow::MainWindow(QWidget *parent)
                  : QMainWindow(parent), ui(new Ui::MainWindow)
              {
                  ui->setupUi(this);
              
                  QList<QSpinBox *> sbList = findChildren<QSpinBox *>(QString(), Qt::FindDirectChildrenOnly);
                  foreach (QSpinBox * spinBox, sbList)  {
                          spinBox->installEventFilter(this);  //< Do you need this??
              
                          QList<QLineEdit *> leList = spinBox->findChildren<QLineEdit *>(QString(), Qt::FindDirectChildrenOnly);
                          foreach (QLineEdit * lineEdit, leList)
                              lineEdit->installEventFilter(this);
                  }
              }
              
              M Offline
              M Offline
              mrsurge
              wrote on 9 Feb 2016, 18:41 last edited by mrsurge 2 Sept 2016, 18:46
              #9

              @kshegunov
              This worked :

              QList<QDoubleSpinBox *> sbList = ui->centralWidget->findChildren<QDoubleSpinBox *>(QString());
              foreach (QDoubleSpinBox * spinBox, sbList)  {
                          //spinBox->installEventFilter(this);  //< Do you need this??//<-no I don't
              
                 QList<QLineEdit *> leList = spinBox->findChildren<QLineEdit *>(QString(), Qt::FindDirectChildrenOnly);
                 foreach (QLineEdit * lineEdit, leList)
                              lineEdit->installEventFilter(this);
              }
              

              many thanks for steering me in the right direction.

              now on to saving the item to the specific line item

              K 1 Reply Last reply 9 Feb 2016, 18:54
              0
              • M mrsurge
                9 Feb 2016, 18:41

                @kshegunov
                This worked :

                QList<QDoubleSpinBox *> sbList = ui->centralWidget->findChildren<QDoubleSpinBox *>(QString());
                foreach (QDoubleSpinBox * spinBox, sbList)  {
                            //spinBox->installEventFilter(this);  //< Do you need this??//<-no I don't
                
                   QList<QLineEdit *> leList = spinBox->findChildren<QLineEdit *>(QString(), Qt::FindDirectChildrenOnly);
                   foreach (QLineEdit * lineEdit, leList)
                                lineEdit->installEventFilter(this);
                }
                

                many thanks for steering me in the right direction.

                now on to saving the item to the specific line item

                K Offline
                K Offline
                kshegunov
                Moderators
                wrote on 9 Feb 2016, 18:54 last edited by
                #10

                @mrsurge
                Yes, of course, I forgot we're in a main window. Anyway, I'm glad it worked. One note, though, if possible use the QObject::findChildren with Qt::FindDirectChildrenOnly so Qt will not go about recursively looking for all. If your spin boxes are in layouts, but not inside other widgets, this should also work:

                QList<QDoubleSpinBox *> sbList = ui->centralWidget->findChildren<QDoubleSpinBox *>(QString(), Qt::FindDirectChildrenOnly);
                

                Kind regards.

                Read and abide by the Qt Code of Conduct

                M 1 Reply Last reply 9 Feb 2016, 23:18
                0
                • K kshegunov
                  9 Feb 2016, 18:54

                  @mrsurge
                  Yes, of course, I forgot we're in a main window. Anyway, I'm glad it worked. One note, though, if possible use the QObject::findChildren with Qt::FindDirectChildrenOnly so Qt will not go about recursively looking for all. If your spin boxes are in layouts, but not inside other widgets, this should also work:

                  QList<QDoubleSpinBox *> sbList = ui->centralWidget->findChildren<QDoubleSpinBox *>(QString(), Qt::FindDirectChildrenOnly);
                  

                  Kind regards.

                  M Offline
                  M Offline
                  mrsurge
                  wrote on 9 Feb 2016, 23:18 last edited by
                  #11

                  @kshegunov

                  ok now how do I return a value from the dialog box to the doubleSpinBox that was clicked?

                  K 1 Reply Last reply 9 Feb 2016, 23:25
                  0
                  • M mrsurge
                    9 Feb 2016, 23:18

                    @kshegunov

                    ok now how do I return a value from the dialog box to the doubleSpinBox that was clicked?

                    K Offline
                    K Offline
                    kshegunov
                    Moderators
                    wrote on 9 Feb 2016, 23:25 last edited by
                    #12

                    @mrsurge
                    I've provided some guidelines here.
                    If this is working,

                    QList<QLineEdit *> leList = spinBox->findChildren<QLineEdit *>(QString(), Qt::FindDirectChildrenOnly);
                    

                    then the line edit has a QSpinBox for a parent. You have the line edit that'd been clicked here:

                    void MainWindow::saveDataToLineEdit(QWidget * widget)
                    {
                        QLineEdit * lineEdit = qobject_cast<QLineEdit *>(widget);
                        // ... Then the line edit parent is ...
                        QSpinBox * spinBox = qobject_cast<QSpinBox *>(lineEdit->parent());
                        // ... and so on ...
                    }
                    

                    Read and abide by the Qt Code of Conduct

                    M 1 Reply Last reply 9 Feb 2016, 23:43
                    0
                    • K kshegunov
                      9 Feb 2016, 23:25

                      @mrsurge
                      I've provided some guidelines here.
                      If this is working,

                      QList<QLineEdit *> leList = spinBox->findChildren<QLineEdit *>(QString(), Qt::FindDirectChildrenOnly);
                      

                      then the line edit has a QSpinBox for a parent. You have the line edit that'd been clicked here:

                      void MainWindow::saveDataToLineEdit(QWidget * widget)
                      {
                          QLineEdit * lineEdit = qobject_cast<QLineEdit *>(widget);
                          // ... Then the line edit parent is ...
                          QSpinBox * spinBox = qobject_cast<QSpinBox *>(lineEdit->parent());
                          // ... and so on ...
                      }
                      
                      M Offline
                      M Offline
                      mrsurge
                      wrote on 9 Feb 2016, 23:43 last edited by mrsurge 2 Sept 2016, 23:43
                      #13

                      @kshegunov said:

                      bool MainWindow::eventFilter(QObject * obj, QEvent * event)
                      {
                      if(event->type() == QEvent::MouseButtonPress)
                      {
                      Dialog mdialog;

                          QSignalMapper mapper(&mdialog);
                          mapper.setMapping(qobject_cast<QWidget *>(obj));
                          QObject::connect(&mdialog, SIGNAL(accepted()), &mapper, SLOT(map()));
                          QObject::connect(&mapper, SIGNAL(mapped(QWidget *)), this, SLOT(saveDataToLineEdit(QWidget *)));
                      
                          mdialog.exec();
                      }
                      return false;
                      

                      }

                      my compiler says

                      mapper.setMapping(qobject_cast<QWidget *>(obj));
                      

                      requires a second argument

                      mapper.setMapping(qobject_cast<QWidget *>(obj),0);
                      

                      works but i have no idea what thats doing

                      K 1 Reply Last reply 9 Feb 2016, 23:59
                      0
                      • M mrsurge
                        9 Feb 2016, 23:43

                        @kshegunov said:

                        bool MainWindow::eventFilter(QObject * obj, QEvent * event)
                        {
                        if(event->type() == QEvent::MouseButtonPress)
                        {
                        Dialog mdialog;

                            QSignalMapper mapper(&mdialog);
                            mapper.setMapping(qobject_cast<QWidget *>(obj));
                            QObject::connect(&mdialog, SIGNAL(accepted()), &mapper, SLOT(map()));
                            QObject::connect(&mapper, SIGNAL(mapped(QWidget *)), this, SLOT(saveDataToLineEdit(QWidget *)));
                        
                            mdialog.exec();
                        }
                        return false;
                        

                        }

                        my compiler says

                        mapper.setMapping(qobject_cast<QWidget *>(obj));
                        

                        requires a second argument

                        mapper.setMapping(qobject_cast<QWidget *>(obj),0);
                        

                        works but i have no idea what thats doing

                        K Offline
                        K Offline
                        kshegunov
                        Moderators
                        wrote on 9 Feb 2016, 23:59 last edited by
                        #14

                        @mrsurge
                        Yes, I forgot the sender. That should be:

                        mapper.setMapping(&mdialog, qobject_cast<QWidget *>(obj));
                        

                        QSignalMapper is a simple utility class to provide mapping of signals without parameters to signals/slots with a single parameter. This is done, because QDialog::accepted has no notion of the QLineEdit that triggers the event filter, so what the line does is simply to remap the signal to a slot that accepts the QLineEdit object as a parameter.

                        Kind regards.

                        Read and abide by the Qt Code of Conduct

                        M 1 Reply Last reply 13 Feb 2016, 04:03
                        0
                        • K kshegunov
                          9 Feb 2016, 23:59

                          @mrsurge
                          Yes, I forgot the sender. That should be:

                          mapper.setMapping(&mdialog, qobject_cast<QWidget *>(obj));
                          

                          QSignalMapper is a simple utility class to provide mapping of signals without parameters to signals/slots with a single parameter. This is done, because QDialog::accepted has no notion of the QLineEdit that triggers the event filter, so what the line does is simply to remap the signal to a slot that accepts the QLineEdit object as a parameter.

                          Kind regards.

                          M Offline
                          M Offline
                          mrsurge
                          wrote on 13 Feb 2016, 04:03 last edited by
                          #15

                          @kshegunov

                          Ok I have a separate form, cpp, and .h for my dialog, does all this still apply? do i need to add anything to my dialog.cpp or .h?

                          K 1 Reply Last reply 13 Feb 2016, 09:20
                          0
                          • M mrsurge
                            13 Feb 2016, 04:03

                            @kshegunov

                            Ok I have a separate form, cpp, and .h for my dialog, does all this still apply? do i need to add anything to my dialog.cpp or .h?

                            K Offline
                            K Offline
                            kshegunov
                            Moderators
                            wrote on 13 Feb 2016, 09:20 last edited by
                            #16

                            @mrsurge
                            Hello,

                            Ok I have a separate form, cpp, and .h for my dialog, does all this still apply? do i need to add anything to my dialog.cpp or .h?

                            It shouldn't matter how you initialize the dialog, provided you call QDialog::accept() at the appropriate place, i.e. when a save/ok button is clicked.

                            Kind regards.

                            Read and abide by the Qt Code of Conduct

                            1 Reply Last reply
                            0

                            13/16

                            9 Feb 2016, 23:43

                            • Login

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