Issue with programming a function template to list the QWidgets in a QDialog with a specific type



  • In the creator function of my Qdialog class, I got that code to work find :

    QList<QComboBox *> CombList2;
       QString QCBName;
       for(int i=1;; i++ )
       {
           QCBName = "comboBox_" + QString::number(i);
           if( ui->gridLayoutWidget->findChild<QComboBox *>( QCBName ) != NULL )
           {
               CombList2.append(ui->gridLayoutWidget->findChild<QComboBox *>( QCBName ) );
           }
           else {
               break;
           }
       }
    

    It constructs an ordered Qlist with QComboBox that are in my UI. The name of the QComboBox in the ui are comboBox_1, comboBox_2 ... and the comboBox numbers have been set to match the ordered fashion in which they appear in the UI.

    This actually replaces this :

       QComboBox *l_TheComboBoxs[NUMofKNOBS_BCR2000] = { ui->comboBox_1, ui->comboBox_2, ui->comboBox_3, ui->comboBox_4, ui->comboBox_5, ui->comboBox_6, ui->comboBox_7, ui->comboBox_8,
                                         ui->comboBox_9, ui->comboBox_10, ui->comboBox_11, ui->comboBox_12, ui->comboBox_13, ui->comboBox_14, ui->comboBox_15, ui->comboBox_16,
                                         ui->comboBox_17, ui->comboBox_18, ui->comboBox_19, ui->comboBox_20, ui->comboBox_21, ui->comboBox_22, ui->comboBox_23, ui->comboBox_24,
                                         ui->comboBox_25, ui->comboBox_26, ui->comboBox_27, ui->comboBox_28, ui->comboBox_29, ui->comboBox_30, ui->comboBox_31, ui->comboBox_32
                                        };
    

    I wanted to build a function that would do the same for deferent widgets QComboBox, QLabel, QDial, QSlidder ..

    I tried with this :

    template <class T>
    void fillQWidgetList(QList<T> *QWidgetList, QWidget *gridLayoutWidget, Q_Widget_Type qwidgettype, QRegExp *QWidgetName)
    {
        QString QCBName;
        for(int i=1;; i++ )
        {
            //QCBName = &QWidgetName + QString::number(i);
            if( qwidgettype == Q_Combo_Box || gridLayoutWidget->findChild<T *>( QCBName ) != NULL )
            {
                QWidgetList->append( gridLayoutWidget->findChild<T *>( QCBName ) );
            }
            else {
                break;
            }
        }
    }
    

    but compiler issue an error when I call the function for QDialogBox

    fillQWidgetList<QComboBox>( &CombList2, ui->gridLayoutWidget, Q_Combo_Box, &Exp);
    

    error : no matching function for call to 'BCR2000::fillQWidgetList(QList<QComboBox*>, QWidget&, Q_Widget_Type, QRegExp*)'
    fillQWidgetList<QComboBox>( &CombList2, ui->gridLayoutWidget, Q_Combo_Box, &Exp);
    ^
    I not sure what this means "QWidget*&". Anybody has experience with function template an this kind of issue



  • Hi!
    @PALYGAP said in Issue with programming a function template to list the QWidgets in a QDialog with a specific type:

    template <class T>
    void fillQWidgetList(QList<T> *QWidgetList, QWidget *gridLayoutWidget, Q_Widget_Type qwidgettype, QRegExp *QWidgetName)

    First thing: Don't give your own parameters / variables etc names starting with a "q" or "Q". In the context of a Qt based program that's highly misleading. E.g. you have a parameter named QWidgetList. Everyone would think that this is a Qt class (it looks similar to QListWidget).

    Second thing: Don't pass arguments by raw pointer unless you have a reason to do so. So, instead of QList<T> *widgetList better use a reference: QList<T> &widgetList.

    Third thing:
    You have a typo: void fillQWidgetList(QList<T> ... has to be void fillQWidgetList(QList<T*>.



  • Thanks @Wieland for the advices.

    I've cleaned up the code and use references in the function call, and got a version of the code that compiles :

    ****FUNCTION CALL****
        QString widgetName = "comboBox_";
        QList<QComboBox *> CombList;
        fillWidgetList<QComboBox>( &CombList, &ui->gridLayoutWidget, &widgetName);
    
    ****FUNCTION****
    template <class T>
    void MIDIControllerGenericDialog::fillWidgetList( QList<T *> *dialogWidgetList, QWidget **gridLayoutWidget, QString *widgetName )
    {
        QString QCBName;
        for(int i=1;; i++ )
        {
            QCBName = *widgetName + QString::number(i);
            if( (*gridLayoutWidget)->findChild<T *>( QCBName ) != NULL )
            {
                dialogWidgetList->append( (*gridLayoutWidget)->findChild<T *>( QCBName ) );
            }
            else {
                break;
            }
        }
    }
    

    but there is a linking issue " error : undefined reference to `void MIDIControllerGenericDialog::fillWidgetList<QComboBox>(QList<QComboBox*>, QWidget*, Widget_Type, QString*)'

    The calling calling function is in the constructor of my BCR2000 class and the BCR2000 class inherit from the MIDIControllerGenericDialog class where the fillWidgetList is defined :

    class MIDIControllerGenericDialog : public QDialog
    {
        Q_OBJECT
    
    public:
        explicit MIDIControllerGenericDialog(QWidget *parent = 0);
        ~MIDIControllerGenericDialog();
    
        void storeGeom(void);
    
        template <class T>
        void fillWidgetList( QList<T *> *dialogWidgetList, QWidget **gridLayoutWidget, Widget_Type widgetType, QString *widgetName );
    

    Putting the function in the BCR2000 class solves the linking issue. Weird and problematic since I want to move functions from the BCR2000 class to the MIDIControllerGenericDialog class.



  • Solved the linking problem. Template function definition has to be in the header file (.h) so that the linker works properly. Seems a fairly common issue : see THIS for the explanation.

    Thanks again @Wieland for the help.



  • One thing I am wondering now : wouldn't it be better to use a single function that takes a QList of QObject :

    void MIDIControllerGenericDialog::fillWidgetList( QList<QObject *> *dialogWidgetList, QWidget **gridLayoutWidget, QString *widgetName )
    

    since the important function used in the fillWidgetListfunction is QObject::findchild() (and it works on QObjects)
    and feed it with casted reference (or pointer ) like so :

        QString widgetName = "comboBox_";
        QList<QComboBox *> CombList;
        fillWidgetList( (QObject>) &CombList, &ui->gridLayoutWidget, &widgetName);
    

    Not sure if that would work. Anybody tried that ?


  • Moderators

    @PALYGAP Did you try it?
    It will not compile because QList<QObject *> is not the same as QList<QComboBox *>.



  • No I haven't.

    ctually if the both the function call and the function definition uses QObject instead of QComboBox it should compile, shouldn't it ?


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.