[solved]Qt 4.8 signalMapper doesn't work



  • I have been trying to implement signal mapper. I have used the example code below.
    But, this example code from 4.8 doesn't have SLOT getting signal from 'mapped'.

    So, I added my own SLOT(doThings(int)). But signal mapper doesn't send any signal to the slot.
    Any help would be really appreciated.

    ButtonWidget::ButtonWidget(QStringList texts, QWidget *parent)
    : QWidget(parent)
    {
    signalMapper = new QSignalMapper(this);

     QGridLayout *gridLayout = new QGridLayout;
     for (int i = 0; i < texts.size(); ++i) {
         QPushButton *button = new QPushButton(texts[i]);
         connect(button, SIGNAL(clicked()), signalMapper, SLOT(map()));
         signalMapper->setMapping(button, i);
         gridLayout->addWidget(button, i / 3, i % 3);
     }
    
     connect(signalMapper, SIGNAL(mapped(const QString &)),
             this, SIGNAL(clicked(int)));
    
     setLayout(gridLayout);
    

    }



  • Welcome to forum. Your last connection t statement is wrong. Change string to int. it works.



  • Thank you for your reply. But this code was not actually mine, I just copied Example code from QT website and just changed from string to int.

    This is mine below.

    mySlot method is to test if signalMapper is sending a right id value. But nothing happens with buttons clicked.

    @vector<QPushButton *> button;
    QSignalMapper *signalMapper;

    signalMapper = new QSignalMapper(this);

    for (int i = 0; i<10; i++)
    {
    button.push_back(newQPushButton("myButton");
    QObject::connect(button[i], SIGNAL(clicked()), signalMapper, SLOT(map()));
    signalMapper->setMapping(button[i], i);
    }

    QObject::connect(signalMapper, SIGNAL(mapped(int)), this, SLOT(mySlot(int)));

    void class::mySlot(int position)
    {
    QMessageBox msgBox;
    msgBox.setText(QString("Button #: %1").arg(position));
    msgBox.exec();
    }@



  • Hope you are clicking on the button. Just try with following and see how things work. Based on this you can modify your example. In your example, I did not see where the buttons are shown and where the clicked signal is coming. Just running the program nothing happens.

    @QPushButton *button = new QPushButton("Pthinks");
    signalMapper->setMapping(button, 1);
    button.show();
    QObject::connect(button[i], SIGNAL(clicked()), signalMapper, SLOT(map()));

    QObject::connect(signalMapper, SIGNAL(mapped(int)), this, SLOT(mySlot(int)));

    void class::mySlot(int position)
    {
    QMessageBox msgBox;
    msgBox.setText(QString("Button #: %1").arg(position));
    msgBox.exec();
    }@



  • Of course, clicking buttons...

    BTW, what you have posted is exactly same code with mine...

    I just omitted some redundant part.

    Buttons are added on gridLayout
    @
    gridLayout->addWidget(button[i], labelRowNumber, labelColumnNumber, 1, 1, Qt::AlignRight);
    @



  • yes, I have taken few things from your code and modified slightly. See the following code. Just try with simple one first and see how it works.

    @QPushButton *button = new QPushButton("Pthinks");
    signalMapper->setMapping(button, 1);
    button.show();
    QObject::connect(button, SIGNAL(clicked()), signalMapper, SLOT(map()));

    QObject::connect(signalMapper, SIGNAL(mapped(int)), this, SLOT(mySlot(int)));

    void class::mySlot(int position)
    {
    QMessageBox msgBox;
    msgBox.setText(QString("Button #: %1").arg(position));
    msgBox.exec();
    }@



  • I have already tried with another method with a single slot not using signalMapper. And it works fine. What I did is to use mySlot_test function

    @
    void class::mySlot_test()
    {
    QMessageBox msgBox;
    msgBox.setText(QString("Button clicked");
    msgBox.exec();
    }

    QObject::connect(button[i], SIGNAL(clicked()), this, SLOT(mySlot_test()));
    @

    When I clicked every single button, this function is called and works fine.



  • Looks like you are missing something. Here is the complete code. Just try this. Make program like the following. It will work.

    @===main.cpp=====
    #include "widget.h"
    #include <QApplication>

    int main(int argc, char *argv[])
    {
    QApplication a(argc, argv);
    Widget w;
    w.show();

    return a.exec&#40;&#41;;
    

    }

    ====widget.h=====
    #ifndef WIDGET_H
    #define WIDGET_H

    #include <QWidget>
    #include <QMessageBox>
    class Widget : public QWidget
    {
    Q_OBJECT

    public:
    Widget(QWidget *parent = 0);
    ~Widget();
    public slots:
    void myslot(int);
    };
    ===widget.cpp====

    #include "widget.h"
    #include <QPushButton>
    #include <QSignalMapper>
    Widget::Widget(QWidget *parent)
    : QWidget(parent)
    {
    QSignalMapper *signalMapper = new QSignalMapper;
    QPushButton *button = new QPushButton("Pthinks");
    signalMapper->setMapping(button, 1);
    button->show();
    connect(button, SIGNAL(clicked()), signalMapper, SLOT(map()));
    connect(signalMapper, SIGNAL(mapped(int)), this, SLOT(myslot(int)));

    }

    void Widget::myslot(int position)
    {
    QMessageBox msgBox;
    msgBox.setText(QString("Button #: %1").arg(position));
    msgBox.exec();;
    }

    Widget::~Widget()
    {

    }
    @



  • I have been trying to figure out this problem for more than a day... Thank you for providing simple code. But my program is a bit huge and mixed (more than 16,000 lines). I am using Visual Studio 2010 with osg library. And I am using Qt for GUI.

    @
    QsignalMapper *signalMapper = new QSignalMapper;
    QPushButton *buttonTest = new QPushButton("Test");
    signalMapper->setMapping(buttonTest, 1);
    gridLayout>addWidget(buttonTest, 0, 0, 1, 1);

    QObject::connect(buttonTest, SIGNAL(clicked()), signalMapper, SLOT(QSignalMapper::map()));
    signalMapper->setMapping(buttonTest, 1);

    // Check if signalMapper works ->* this doesn't work
    QObject::connect(signalMapper, SIGNAL(QSignalMapper::mapped(int)), this, SLOT(mySlot(int)));

    // Check if button clicked -> this works fine
    QObject::connect(buttonTest, SIGNAL(clicked()), this, SLOT(mySlot_Test()));

    void Widget::mySlot(int position)
    {
    QMessageBox msgBox;
    msgBox.setText(QString("Button #%1").arg(position));
    msgBox.exec();
    }

    void Widget::mySlot_Test()
    {
    QMessageBox msgBox;
    msgBox.setText(QString("Button Clicked"));
    msgBox.exec();
    }
    @

    mySlot method is not called through signalMapper but mySlot_Test which can confirm if the button is clicked works. The button is showing without any problems. The message of "Button Clicked" pops up, but "Button #1" message windows never comes up. If mySlot_Test function goes can receive signal. There is nothing wrong with the other part of my code, such as deceleration of header file etc...


  • Lifetime Qt Champion

    Hi,

    @QObject::connect(signalMapper, SIGNAL(QSignalMapper::mapped(int)), this, SLOT(mySlot(int)));@

    is wrong, it should be

    @QObject::connect(signalMapper, SIGNAL(mapped(int)), this, SLOT(mySlot(int)));@



  • Why those are different? How about these?
    @
    QObject::connect(buttonTest, SIGNAL(clicked()), signalMapper, SLOT(QSignalMapper::map()));

    QObject::connect(buttonTest, SIGNAL(clicked()), signalMapper, SLOT(map()))
    @


  • Lifetime Qt Champion

    For connections to work with the old syntax, connect expects only the signal/slot signatures, no class name, no variable name etc.



  • LoL... That did a trick... I do really appreciate your help!

    Originally, I was avoiding calling osgEarth::map() for the connector. I had same methods (map() and mapped()). This is something I need to be aware of when I implement these SIGNAL-SLOT.

    Thanks again! Problem Solved.


  • Lifetime Qt Champion

    You're welcome !

    Since you have your mapper running, please update the thread title prepending [solved] so other forum users may know a solution has been found :)



  • Thank you again. I have just updated title.


Log in to reply
 

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