Question

Edit: The code below has been updated to the working solution.

As an attempt to introduce myself to QT, I am trying to design a chessboard out of 64 QPushButtons. I know this might not be the best way to do this, but I believe starting with the basics is a good way to learn. Anyways, all of the 64 pushbuttons will essentially do the same thing. All of the button's clicked signals will call the same function, passing to the function the associated QPushButton. Instead of individually creating each QPushButton in qtcreator & qtdesigner, and individually creating each on_clicked signal function for each button, I am trying to apply a QSignalMapper. This is what I have so far:

chess.h

#ifndef CHESS_H
#define CHESS_H

#include <QMainWindow>
#include <QSignalMapper>
#include <QPushButton>
#include <QGridLayout>
#include <QMessageBox>

namespace Ui {
class Chess;
}

class Chess : public QMainWindow
{
    Q_OBJECT

public:
    explicit Chess(QWidget *parent = 0);
    ~Chess();

public slots:
    void On_Clicked(int location);

private:
    Ui::Chess *ui;

    QPushButton *buttons[64];
};

#endif // CHESS_H

chess.cpp

#include "chess.h"
#include "ui_chess.h"

Chess::Chess(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::Chess)
{
    QSize button_size(100, 100);
    ui->setupUi(this);

    QGridLayout *layout = new QGridLayout;
    QSignalMapper *signalMapper = new QSignalMapper(this);
    connect(signalMapper, SIGNAL(mapped(int)), this, SLOT(On_Clicked(int)));

    for (int i = 0; i < 64; i++) {
        QString t = QString::number(i);
        buttons[i] = new QPushButton(t, this);
        buttons[i]->setMinimumSize(button_size);
        signalMapper->setMapping(buttons[i], i);
        connect(buttons[i], SIGNAL(clicked()), signalMapper, SLOT(map()));
        layout->addWidget(buttons[i], i / 8, i % 8);
    }

    QWidget* central_widget = new QWidget(this);
    central_widget->setLayout(layout);
    setCentralWidget(central_widget);

}

Chess::~Chess()
{
    delete ui;
}

void Chess::On_Clicked(int location) {
    QMessageBox msgbox;
    msgbox.setText(QString::number(location) + " was pushed");
    msgbox.exec();

}

This creates the following output:

enter image description here

I was hoping the behavior of clicking on any buttons would bring up a QMessageBox saying that the button was pushed, as defined in the On_Clicked function. Obviously I am misunderstanding something but I cannot figure it out. Is the QSignalMapper designed for this type of behavior? I thought it was after reading this example.

Thanks!

Was it helpful?

Solution

On_Clicked is a signal, thus you need to connect a slot to it. Or just change On_clicked into slot and connect signal mapped(int) to it (use SLOT keyword then).

And notice that On_Clicked function you defined is not a class method which you would need.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top