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.
  • K Offline
    K Offline
    kshegunov
    Moderators
    wrote on 8 Feb 2016, 13:15 last edited by kshegunov 2 Aug 2016, 14:10
    #3

    @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).

    Read and abide by the Qt Code of Conduct

    M 1 Reply Last reply 9 Feb 2016, 05:19
    1
    • 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

                              12/16

                              9 Feb 2016, 23:25

                              • Login

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