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

Dynamic Handling of Hundreds of UI elements

Scheduled Pinned Locked Moved Unsolved General and Desktop
ui object
16 Posts 4 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.
  • kshegunovK Offline
    kshegunovK Offline
    kshegunov
    Moderators
    wrote on last edited by kshegunov
    #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
    1
    • mrjjM Offline
      mrjjM Offline
      mrjj
      Lifetime Qt Champion
      wrote on 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
      • kshegunovK kshegunov

        @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 last edited by mrsurge
        #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

        kshegunovK 1 Reply Last reply
        0
        • M mrsurge

          @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

          kshegunovK Offline
          kshegunovK Offline
          kshegunov
          Moderators
          wrote on 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
          0
          • kshegunovK kshegunov

            @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 last edited by mrsurge
            #7

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

            kshegunovK 1 Reply Last reply
            0
            • M mrsurge

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

              kshegunovK Offline
              kshegunovK Offline
              kshegunov
              Moderators
              wrote on last edited by kshegunov
              #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
              1
              • kshegunovK kshegunov

                @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 last edited by mrsurge
                #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

                kshegunovK 1 Reply Last reply
                0
                • M mrsurge

                  @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

                  kshegunovK Offline
                  kshegunovK Offline
                  kshegunov
                  Moderators
                  wrote on 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
                  0
                  • kshegunovK kshegunov

                    @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 last edited by
                    #11

                    @kshegunov

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

                    kshegunovK 1 Reply Last reply
                    0
                    • M mrsurge

                      @kshegunov

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

                      kshegunovK Offline
                      kshegunovK Offline
                      kshegunov
                      Moderators
                      wrote on 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
                      0
                      • kshegunovK kshegunov

                        @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 last edited by mrsurge
                        #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

                        kshegunovK 1 Reply Last reply
                        0
                        • M mrsurge

                          @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

                          kshegunovK Offline
                          kshegunovK Offline
                          kshegunov
                          Moderators
                          wrote on 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
                          0
                          • kshegunovK kshegunov

                            @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 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?

                            kshegunovK 1 Reply Last reply
                            0
                            • M mrsurge

                              @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?

                              kshegunovK Offline
                              kshegunovK Offline
                              kshegunov
                              Moderators
                              wrote on 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

                              • Login

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