简体   繁体   中英

How to reference dynamically created label when the button next to it is clicked [Qt]

Each time the "Add Client" button is pressed - a minus button, the name of the client, a counter for the client and a plus button are added in a horizontal line to the gridLayout. I want to update the count (QLabel) when the plus/minus button is pressed.

Here is my code:

#include "widget.h"
#include "ui_widget.h"
#include <QDebug>
#include <QGridLayout>
#include <QLabel>

int row = 0;

Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);
}

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

void Widget::on_pushButton_clicked()
{
    QPushButton* minus_button = new QPushButton();
    QPushButton* plus_button = new QPushButton();
    minus_button->setText("-");
    plus_button->setText("+");

    QLabel* client_name = new QLabel(ui->lineEdit->text(), this);
    QLabel* client_count = new QLabel("", this);

    ui->gridLayout->addWidget(minus_button, row, 1, Qt::AlignTop|Qt::AlignHCenter);
    ui->gridLayout->addWidget(client_name, row, 2, Qt::AlignTop|Qt::AlignHCenter);
    ui->gridLayout->addWidget(client_count, row, 3, Qt::AlignTop|Qt::AlignHCenter);
    ui->gridLayout->addWidget(plus_button, row++, 4, Qt::AlignTop|Qt::AlignHCenter);

    connect(minus_button, SIGNAL(clicked(bool)), this, SLOT(minusCount()));
    connect(plus_button, SIGNAL(clicked(bool)), this, SLOT(plusCount()));
}

void Widget::minusCount(){
    //Here I want to somehow reference the client_count label which is in the same row
}
void Widget::plusCount(){
    //Here I want to somehow reference the client_count label which is in the same row
}

EDIT: After Kevin's comment, here is the working code for anyone who may need it.

#include "widget.h"
#include "ui_widget.h"
#include <QDebug>
#include <QGridLayout>
#include <QLabel>
#include <QSignalMapper>

QSignalMapper* m_minusMapper;
QSignalMapper* m_plusMapper;

Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);
    m_minusMapper = new QSignalMapper(this);
    connect(m_minusMapper, SIGNAL(mapped(QWidget*)), this, SLOT(minusCount(QWidget*)));

    m_plusMapper = new QSignalMapper(this);
    connect(m_plusMapper, SIGNAL(mapped(QWidget*)), this, SLOT(plusCount(QWidget*)));
}

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

void Widget::on_pushButton_clicked()
{
    QPushButton* minus_button = new QPushButton();
    minus_button->setObjectName("minus" + QString::number(row));
    minus_button->setText("-");

    QPushButton* plus_button = new QPushButton();
    plus_button->setObjectName("plus" + QString::number(row));
    plus_button->setText("+");

    QLabel* client_name = new QLabel(ui->lineEdit->text(), this);
    QLabel* client_count = new QLabel("0", this);

    ui->gridLayout->addWidget(minus_button, row, 1, Qt::AlignVCenter|Qt::AlignHCenter);
    ui->gridLayout->addWidget(client_name, row, 2, Qt::AlignVCenter|Qt::AlignHCenter);
    ui->gridLayout->addWidget(client_count, row, 3, Qt::AlignVCenter|Qt::AlignHCenter);
    ui->gridLayout->addWidget(plus_button, row++, 4, Qt::AlignVCenter|Qt::AlignHCenter);

    connect(minus_button, SIGNAL(clicked()), m_minusMapper, SLOT(map()));
    connect(plus_button, SIGNAL(clicked()), m_plusMapper, SLOT(map()));

    m_minusMapper->setMapping(minus_button, client_count);
    m_plusMapper->setMapping(plus_button, client_count);
}

void Widget::minusCount(QWidget *widget)
{
    QLabel *client_count = qobject_cast<QLabel*>(widget);
    QString initCount = client_count->text();
    int newCount = initCount.toInt() - 1;
    client_count->setText(QString::number(newCount));
}

void Widget::plusCount(QWidget *widget)
{
    QLabel *client_count = qobject_cast<QLabel*>(widget);
    QString initCount = client_count->text();
    int newCount = initCount.toInt() + 1;
    client_count->setText(QString::number(newCount));
}

Kevin's answer in principle is fine, but since we've got 2016 now and MSVC2010, gcc 4.7, and Clang 3.1 (and possibly earlier versions) support lambdas/C++11, I'd like to add a version without QSignalMapper:

static void minusCount(QLabel *label)
{
    QString initCount = label->text();
    int newCount = initCount.toInt() - 1;
    label->setText(QString::number(newCount));
}

static void plusCount(QLabel *label)
{
    QString initCount = label->text();
    int newCount = initCount.toInt() + 1;
    label->setText(QString::number(newCount));
}

void Widget::on_pushButton_clicked()
{
    // ... add the labels and buttons, then:
    connect(minus_button, &QPushButton::clicked,
            client_count, [client_count]() { minusCount(client_count); });
    connect(plus_button, &QPushButton::clicked,
            client_count, [client_count]() { plusCount(client_count); });
}

Here the client_count label that the button click should change is captured in the lambda, and directly passed to the function handling it.

The minusCount and plusCount also can be static functions then, since they only operate on the label that is passed as an argument, so they are independent from any Widget instance.

The easiest way is to use a QSignalMapper

// in the constructor of your class
m_minusSignalMapper = new QSignalMapper(this);
connect(m_minusSignalMapper, SIGNAL(mapped(QWidget*)), this, SLOT(minusCount(QWidget*)));

m_plusSignalMapper = new QSignalMapper(this);
connect(m_plusSignalMapper, SIGNAL(mapped(QWidget*)), this, SLOT(plusCount(QWidget*)));


// in your button slot you connect to the respective mapper instead
connect(minus_button, SIGNAL(clicked()), m_minusMapper, SLOT(map()));
connect(plus_button, SIGNAL(clicked()), m_plusMapper, SLOT(map()));

// and you set up the mapping
m_minusMapper->setMapping(minus_button, client_count);
m_plusMapper->setMapping(plus_button, client_count);

// in the the two receiver slots, the argument is the label
void Widget::minusCount(QWidget *widget)
{
    QLabel *client_count = qobject_cast<QLabel*>(widget);
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM