Page 1 of 2 12 LastLast
Results 1 to 20 of 29

Thread: dynamcly allocated buttons

  1. #1
    Join Date
    Jan 2006
    Location
    Ljubljana
    Posts
    687
    Thanks
    111
    Thanked 4 Times in 4 Posts
    Qt products
    Qt5 Qt/Embedded
    Platforms
    MacOS X Unix/X11 Windows Android

    Default dynamcly allocated buttons

    Hi to all!

    I've dynamically created buttons (the number of them is NOT known at compile time, but at runtime). It works ok, buttons are shown as I wanted. But now, I need to connect every button's signal clicked() to some slot function. How do I provide slot functions at runtime??
    Qt 5.3 Opensource & Creator 3.1.2

  2. #2
    Join Date
    Jan 2006
    Location
    Ljubljana
    Posts
    687
    Thanks
    111
    Thanked 4 Times in 4 Posts
    Qt products
    Qt5 Qt/Embedded
    Platforms
    MacOS X Unix/X11 Windows Android

    Default Re: dynamcly allocated buttons

    It look like I did it on my own. But it does not work. Is it allowed to setup slot from one object and then call slot from different object?

    I got to gdb and i get following message:
    Qt Code:
    1. warning: Object::connect: No such slot COperationWIndow::m_pMerchandizeBrowser->fillMerchandize(iIndex)
    To copy to clipboard, switch view to plain text mode 

    Why this does not work?
    Last edited by MarkoSan; 10th December 2007 at 17:18.
    Qt 5.3 Opensource & Creator 3.1.2

  3. #3
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,368
    Thanks
    3
    Thanked 5,017 Times in 4,793 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: dynamcly allocated buttons

    Quote Originally Posted by MarkoSan View Post
    How do I provide slot functions at runtime??
    I don't think you can add methods to classes at runtime in C++

    Quote Originally Posted by MarkoSan View Post
    Is it allowed to setup slot from one object and then call slot from different object?
    If you think about something like this:
    Qt Code:
    1. connect(object1, SIGNAL(sig()), object2, SLOT(sl())); // "this" is neither object1 nor object2
    To copy to clipboard, switch view to plain text mode 
    then yes.

  4. #4
    Join Date
    Jan 2006
    Location
    Ljubljana
    Posts
    687
    Thanks
    111
    Thanked 4 Times in 4 Posts
    Qt products
    Qt5 Qt/Embedded
    Platforms
    MacOS X Unix/X11 Windows Android

    Default Re: dynamcly allocated buttons

    Well, if I got it right, then:
    Qt Code:
    1. m_MerchandizeSelectorButtons.at(iIndex)->connect(m_pButtonMerchandizeConfirmer,
    2. SIGNAL(clicked()),
    3. this. SLOT(m_pMerchandizeBrowser->fillMerchandize(iIndex)));
    To copy to clipboard, switch view to plain text mode 

    then second "this" is the name of "target" object?
    Qt 5.3 Opensource & Creator 3.1.2

  5. #5
    Join Date
    Feb 2006
    Location
    Oslo, Norway
    Posts
    6,264
    Thanks
    36
    Thanked 1,519 Times in 1,389 Posts
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows Symbian S60 Maemo/MeeGo

    Default Re: dynamcly allocated buttons

    You can't put a statement into SLOT() macro like that. Take a look at QButtonGroup or QSignalMapper.
    J-P Nurmi

  6. #6
    Join Date
    Jan 2006
    Location
    Ljubljana
    Posts
    687
    Thanks
    111
    Thanked 4 Times in 4 Posts
    Qt products
    Qt5 Qt/Embedded
    Platforms
    MacOS X Unix/X11 Windows Android

    Default Re: dynamcly allocated buttons

    QSIgnalMapper? I hate it, I've never understood it, I've read the docs about QSignalMapper but it is my humble opinion these docs are not written at the best ...
    Qt 5.3 Opensource & Creator 3.1.2

  7. #7
    Join Date
    Feb 2006
    Location
    Oslo, Norway
    Posts
    6,264
    Thanks
    36
    Thanked 1,519 Times in 1,389 Posts
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows Symbian S60 Maemo/MeeGo

    Default Re: dynamcly allocated buttons

    Quote Originally Posted by MarkoSan View Post
    QSIgnalMapper? I hate it, I've never understood it, I've read the docs about QSignalMapper but it is my humble opinion these docs are not written at the best ...
    To be direct and honest, you should start with reading the article about signals and slots. It's the very basic principle of signals and slots that the SLOT() macro takes a slot name plus optional parameter types, without parameter names, and nothing more. Once you understand how signals and slots work, it should be straightforward to understand QSignalMapper docs. Besides, QButtonGroup should be even easier to use...
    J-P Nurmi

  8. #8
    Join Date
    Jan 2006
    Location
    Ljubljana
    Posts
    687
    Thanks
    111
    Thanked 4 Times in 4 Posts
    Qt products
    Qt5 Qt/Embedded
    Platforms
    MacOS X Unix/X11 Windows Android

    Default Re: dynamcly allocated buttons

    Ok, but I simply must overcome this QSignalMapper since it is very useful. I understand signal/slots feature, but this QSignalMapper is giving me headache. Now let me dig into it ...
    Qt 5.3 Opensource & Creator 3.1.2

  9. #9
    Join Date
    Jan 2006
    Location
    Ljubljana
    Posts
    687
    Thanks
    111
    Thanked 4 Times in 4 Posts
    Qt products
    Qt5 Qt/Embedded
    Platforms
    MacOS X Unix/X11 Windows Android

    Default Re: dynamcly allocated buttons

    Does every button in a QList <QPushButton*> need its own QSIgnalMapper?
    Qt 5.3 Opensource & Creator 3.1.2

  10. #10
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    5,372
    Thanks
    28
    Thanked 976 Times in 912 Posts
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11 Windows

    Default Re: dynamcly allocated buttons

    Quote Originally Posted by MarkoSan View Post
    Does every button in a QList <QPushButton*> need its own QSIgnalMapper?
    No, you need only one signal mapper for the whole list.

    In Qt docs you can find such example:
    Qt Code:
    1. ...
    2. for (int i = 0; i < texts.size(); ++i) {
    3. QPushButton *button = new QPushButton(texts[i]);
    4. connect(button, SIGNAL(clicked()), signalMapper, SLOT(map()));
    5. signalMapper->setMapping(button, texts[i]);
    6. ...
    7. }
    8.  
    9. connect(signalMapper, SIGNAL(mapped(const QString &)),
    10. this, SIGNAL(clicked(const QString &)));
    11. ...
    To copy to clipboard, switch view to plain text mode 

    The setMapping() line tells the signal mapper that whenever the particular button invokes map(), the signal mapper should emit mapped(const QString &) signal with given parameter. So in this case you can replace all clicked() signals coming from different buttons with a single mapped( const QString & ) signal that comes from the signal mapper (of course parameter value depends on which button sent the original signal).

    You can have a mapped() signal also with integer, QObject * or QWidget * parameter --- you just have to use the other setMapping() method variants instead.

    In your case you can use QButtonGroup as jpn has suggested. Basically it's like a QSignalMapper but crafted especially for buttons.

  11. The following user says thank you to jacek for this useful post:

    MarkoSan (11th December 2007)

  12. #11
    Join Date
    Jan 2006
    Location
    Ljubljana
    Posts
    687
    Thanks
    111
    Thanked 4 Times in 4 Posts
    Qt products
    Qt5 Qt/Embedded
    Platforms
    MacOS X Unix/X11 Windows Android

    Question Re: dynamcly allocated buttons

    I would stick to QSignalMapper because I simply must overcome this topic. So, let me dig into it and try to reprogramm the example...

    Well, I've done this:
    Qt Code:
    1. m_MerchandizeSelectorButtons.at(iIndex)->connect(m_MerchandizeSelectorButtons.at(iIndex),
    2. SIGNAL(clicked()),
    3. m_pMerchandizeSelectorButtonSignalMapper,
    4. SLOT(map()));
    To copy to clipboard, switch view to plain text mode 

    What should I now put into map() slot? Call to other's object slot?
    Last edited by MarkoSan; 11th December 2007 at 00:19.
    Qt 5.3 Opensource & Creator 3.1.2

  13. #12
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,368
    Thanks
    3
    Thanked 5,017 Times in 4,793 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: dynamcly allocated buttons

    Do you know why you were suggested to use a signal mapper or do you just follow the advice blindly without trying to understand the problem first?

  14. #13
    Join Date
    Jan 2006
    Location
    Ljubljana
    Posts
    687
    Thanks
    111
    Thanked 4 Times in 4 Posts
    Qt products
    Qt5 Qt/Embedded
    Platforms
    MacOS X Unix/X11 Windows Android

    Default Re: dynamcly allocated buttons

    I know why i was suggested to use signal mapper. That is because I cannot send a slot to other object, or am I wrong again??
    Qt 5.3 Opensource & Creator 3.1.2

  15. #14
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,368
    Thanks
    3
    Thanked 5,017 Times in 4,793 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: dynamcly allocated buttons

    Quote Originally Posted by MarkoSan View Post
    That is because I cannot send a slot to other object, or am I wrong again??
    Yes, you are right - you are wrong again.

    The signal mapper is used so that you can pass an integer argument to a slot connected to a signal that doesn't emit any arguments. If you just want to connect a signal to a slot, you don't need a signal mapper:

    Qt Code:
    1. for(int i=0;i<10;i++){
    2. QPushButton *b = new QPushButton(this);
    3. ((QHBoxLayout*)layout())->addWidget(b);
    4. connect(b, SIGNAL(clicked()), this, SLOT(fillMerchandize())); // see? no mapper
    5. }
    To copy to clipboard, switch view to plain text mode 

    Compare your original code and this one. As you see fillMerchandize() doesn't take an int argument as you'd probably like it to. To get that index you have two solutions:
    1. inside fillMerchandize() use QObject::sender() to compare the pointer of the object that sent the signal to each and every pointer stored in your list to determine the index of the list occupied by the button you want.

    or

    2. use a QSignalMapper as already advised (which basically does the same).

    Note, that if you don't need the index (number) of the list but only a pointer to the button, you don't need the signal mapper - you can cast sender() to your button class and use the pointer. Just use a smart casting technique like qobject_cast.

  16. The following user says thank you to wysota for this useful post:

    MarkoSan (11th December 2007)

  17. #15
    Join Date
    Jan 2006
    Location
    Ljubljana
    Posts
    687
    Thanks
    111
    Thanked 4 Times in 4 Posts
    Qt products
    Qt5 Qt/Embedded
    Platforms
    MacOS X Unix/X11 Windows Android

    Red face Re: dynamcly allocated buttons

    Guys, this is what I've done:
    Qt Code:
    1. for(iIndex=0; iIndex<m_MerchandizeGroupsNames.size(); iIndex++)
    2. {
    3. // creates new button
    4. //QString buttonText=m_MerchandizeGroupsNames.at(iIndex); // gets button text
    5. QPushButton* pTempButton=new QPushButton(m_MerchandizeGroupsNames.at(iIndex), this);
    6. Q_CHECK_PTR(pTempButton);
    7. // adds button to list
    8. m_MerchandizeSelectorButtons.append(pTempButton);
    9. m_cPalette=m_MerchandizeSelectorButtons.at(iIndex)->palette(); // gets current pallete of button
    10. m_cPalette.setColor(QPalette::Button, Qt::red); // sets up new palette componenet
    11. m_cPalette.setColor(QPalette::ButtonText, Qt::black); // sets up new palette componenet
    12. m_MerchandizeSelectorButtons.at(iIndex)->setPalette(m_cPalette); // sets new pallete
    13. m_MerchandizeSelectorButtons.at(iIndex)->setFont(merchandizeButtonFont); // sets font
    14. // connects buttons's slick to merchandize browser slot for filling pictures of selected group
    15. /*
    16.   m_MerchandizeSelectorButtons.at(iIndex)->connect(m_pButtonMerchandizeConfirmer,
    17.   SIGNAL(clicked()),
    18.   m_pMerchandizeBrowser,
    19.   SLOT(m_pMerchandizeBrowser->fillMerchandize(iIndex)));
    20. */
    21. m_MerchandizeSelectorButtons.at(iIndex)->connect(m_MerchandizeSelectorButtons.at(iIndex),
    22. SIGNAL(clicked()),
    23. m_pMerchandizeSelectorButtonSignalMapper,
    24. SLOT(map()));
    25. m_pMerchandizeSelectorButtonSignalMapper->setMapping(m_MerchandizeSelectorButtons.at(iIndex), iIndex);
    26. // adds newly created button to layout
    27. m_pMerchandizeSelectorButtonsLayout->addWidget(m_MerchandizeSelectorButtons.at(iIndex));
    28. //delete pTempButton; // deletes temp button
    29. }
    30.  
    31. /*
    32.   connect(m_pMerchandizeSelectorButtonSignalMapper, SIGNAL(mapped(qint16 iIndex)),
    33.   m_pMerchandizeBrowser, SIGNAL(clicked(qint16 iIndex)));
    34. */
    35. connect(m_pMerchandizeSelectorButtonSignalMapper, SIGNAL(mapped(qint16 iIndex)),
    36. this, SIGNAL(clicked(qint16 iIndex)));
    To copy to clipboard, switch view to plain text mode 

    I still get gdb warnings about there is not signalmapper::map slot. I might be stupid or something, but please help me!!
    Qt 5.3 Opensource & Creator 3.1.2

  18. #16
    Join Date
    Feb 2006
    Location
    Oslo, Norway
    Posts
    6,264
    Thanks
    36
    Thanked 1,519 Times in 1,389 Posts
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows Symbian S60 Maemo/MeeGo

    Default Re: dynamcly allocated buttons

    Quote Originally Posted by MarkoSan View Post
    Qt Code:
    1. connect(m_pMerchandizeSelectorButtonSignalMapper, SIGNAL(mapped(qint16 iIndex)),
    2. this, SIGNAL(clicked(qint16 iIndex)));
    To copy to clipboard, switch view to plain text mode 
    Go take a look at QSignalMapper docs. Which signals does it offer? Does it offer a signal with qint16 parameter? Notice that qint16 is not same type as int.
    J-P Nurmi

  19. #17
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,368
    Thanks
    3
    Thanked 5,017 Times in 4,793 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: dynamcly allocated buttons

    And we don't pass variable names in SIGNAL and SLOT signatures.

  20. #18
    Join Date
    Jan 2006
    Location
    Ljubljana
    Posts
    687
    Thanks
    111
    Thanked 4 Times in 4 Posts
    Qt products
    Qt5 Qt/Embedded
    Platforms
    MacOS X Unix/X11 Windows Android

    Default Re: dynamcly allocated buttons

    I've finally rewritten the code as follows:
    Qt Code:
    1. for(iIndex=0; iIndex<m_MerchandizeGroupsNames.size(); iIndex++)
    2. {
    3. // creates new button
    4. //QString buttonText=m_MerchandizeGroupsNames.at(iIndex); // gets button text
    5. QPushButton* pTempButton=new QPushButton(m_MerchandizeGroupsNames.at(iIndex), this);
    6. Q_CHECK_PTR(pTempButton);
    7. // adds button to list
    8. m_MerchandizeSelectorButtons.append(pTempButton);
    9. m_cPalette=m_MerchandizeSelectorButtons.at(iIndex)->palette(); // gets current pallete of button
    10. m_cPalette.setColor(QPalette::Button, Qt::red); // sets up new palette componenet
    11. m_cPalette.setColor(QPalette::ButtonText, Qt::black); // sets up new palette componenet
    12. m_MerchandizeSelectorButtons.at(iIndex)->setPalette(m_cPalette); // sets new pallete
    13. m_MerchandizeSelectorButtons.at(iIndex)->setFont(merchandizeButtonFont); // sets font
    14. // connects buttons's slick to merchandize browser slot for filling pictures of selected group
    15. /*
    16.   m_MerchandizeSelectorButtons.at(iIndex)->connect(m_MerchandizeSelectorButtons.at(iIndex),
    17.   SIGNAL(clicked()),
    18.   this,
    19.   SLOT(setGroup()));
    20.   m_pMerchandizeSelectorButtonSignalMapper->setMapping(m_MerchandizeSelectorButtons.at(iIndex), iIndex);
    21. */
    22. connect(pTempButton, SIGNAL(clicked()),
    23. m_pMerchandizeSelectorButtonSignalMapper, SLOT(map())); // connects button to signal mapper
    24. m_pMerchandizeSelectorButtonSignalMapper->setMapping(pTempButton, (int)iIndex); // sets mapping
    25. // adds newly created button to layout
    26. m_pMerchandizeSelectorButtonsLayout->addWidget(m_MerchandizeSelectorButtons.at(iIndex));
    27. //delete pTempButton; // deletes temp button
    28. } // for
    29. connect(m_pMerchandizeSelectorButtonSignalMapper, SIGNAL(mapped(const int&)),
    30. this, SIGNAL(clicked(const int&))); // connects signal mapper to button
    To copy to clipboard, switch view to plain text mode 
    Now, how do I "catch" SIGNAL "clicked"? I've declared it in .h file with:
    Qt Code:
    1. signals:
    2. void clicked(const int &iIndex); // pushbutton slot
    To copy to clipboard, switch view to plain text mode 
    and If I try to write appropriate code for it in the .cpp file, I get following error:
    Qt Code:
    1. Severity and Description Path Resource Location Creation Time Id
    2. ./debug\moc_COperationWIndow.o In function `ZN16COperationWIndow7clickedERKi': eROSystem line 0 1200210789421 2773
    3. C:/Documents and Settings/markofr/workspace/eROSystem/debug/moc_COperationWIndow.cpp multiple definition of `COperationWIndow::clicked(int const&)' eROSystem line 85 1200210789421 2774
    4. first defined here eROSystem COperationWIndow.cpp line 348 1200210789421 2775
    5. make: *** [debug] Error 2 eROSystem line 0 1200210789421 2777
    6. make[1]: *** [debug\eROSystem.exe] Error 1 eROSystem line 0 1200210789421 2776
    To copy to clipboard, switch view to plain text mode 
    Why??
    Qt 5.3 Opensource & Creator 3.1.2

  21. #19
    Join Date
    Aug 2006
    Location
    Bangalore,India
    Posts
    419
    Thanks
    37
    Thanked 53 Times in 40 Posts
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11

    Default Re: dynamcly allocated buttons

    Quote Originally Posted by MarkoSan View Post
    I've finally rewritten the code as follows:[code] {snip}
    Why??
    Because you can only implement the code for slots not signals Make "clicked(const int&))" this a slot rather than a signal.

    Please make sure you know the basics of signals and slots first.
    The biggest difference between time and space is that you can't reuse time.
    -- Merrick Furst

  22. #20
    Join Date
    Jan 2006
    Location
    Ljubljana
    Posts
    687
    Thanks
    111
    Thanked 4 Times in 4 Posts
    Qt products
    Qt5 Qt/Embedded
    Platforms
    MacOS X Unix/X11 Windows Android

    Default Re: dynamcly allocated buttons

    I've read signal/slot mechanism, but I saw nowhere in the docs slot can take parameters, so it can or not???
    Qt 5.3 Opensource & Creator 3.1.2

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Qt is a trademark of The Qt Company.