Использование QSignalMapper; Несколько кнопок QPushButton, назначенных одному сигналу

Изменить: приведенный ниже код был обновлен до рабочего решения.

Пытаясь познакомиться с QT, я пытаюсь создать шахматную доску из 64 кнопок QPushButton. Я знаю, что это может быть не лучший способ сделать это, но я считаю, что начать с основ — это хороший способ научиться. В любом случае, все 64 кнопки будут делать одно и то же. Все сигналы нажатия кнопки будут вызывать одну и ту же функцию, передавая ей соответствующий QPushButton. Вместо индивидуального создания каждой кнопки QPushButton в qtcreator и qtdesigner и индивидуального создания каждой функции сигнала on_clicked для каждой кнопки я пытаюсь применить QSignalMapper. Это то, что у меня есть до сих пор:

шахматы.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

шахматы.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();

}

Это создает следующий вывод:

введите здесь описание изображения

Я надеялся, что поведение при нажатии на любую кнопку вызовет QMessageBox, сообщающий, что кнопка была нажата, как определено в функции On_Clicked. Очевидно, я что-то не понимаю, но не могу понять. Предназначен ли QSignalMapper для такого поведения? Я подумал, что это произошло после прочтения этого примера.

Спасибо!


person halexh    schedule 21.03.2014    source источник
comment
Похоже, что Qt наконец-то отказался от преобразователей сигналов в пользу bind   -  person nurettin    schedule 07.07.2018


Ответы (1)


On_Clicked — это сигнал, поэтому к нему нужно подключить слот. Или просто измените On_clicked на слот и подключите к нему сигнал mapped(int) (тогда используйте ключевое слово SLOT).

И обратите внимание, что определенная вами функция On_Clicked не является методом класса, который вам понадобится.

person Bogdan    schedule 21.03.2014
comment
Спасибо! Это сделало это. Для всех, кто может столкнуться, я обновил код до рабочего решения. - person halexh; 22.03.2014