PDA

View Full Version : Dynamically created buttons to one slot



rdkk
2nd June 2013, 23:55
Hi,
I am dynamically creating QPushButtons in ui and holding them in array. After clicking one of them I want to call function with integer parameter. It will be button index in array so I need to know which button was clicked to call this function.

I coded like this:



MainWindow::MainWindow(QWidget *parent, struct ProfileParams profPar) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
this->showMaximized();
QPushButton * btn[16];
QSignalMapper* sendSignalMapper = new QSignalMapper(this);//sendMessage
int k = 0, l = 1, a = 0;

for(int j=1; j<=profPar.number; j++)
{
btn[j-1] = new QPushButton;
btn[j-1]->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
sendSignalMapper->setMapping(btn[j-1],j-1);
connect(btn[j-1],SIGNAL(clicked()),sendSignalMapper,SLOT(map()));
}
connect(sendSignalMapper,SIGNAL(mapped(int)),this ,SLOT(send_data(int)));
}
else
{
QMessageBox::critical(this,"Error", "Cannot open!", QMessageBox::Ok);
exit(0);
}
}

void MainWindow::send_data(int number)
{
sendDat("#WAIT", number);
}



and it isn't working - why?

sorry for my "English" ;)

wysota
3rd June 2013, 01:27
The code above won't compile so I'd suggest to start by fixing it. It's likely that you're missing some "if" statement. By the way, in C/C++ we usually start iterating loops at 0, not 1.

karankumar1609
3rd June 2013, 05:47
Better to try to compile your code first.
or try this one.



MainWindow::MainWindow(QWidget *parent, struct ProfileParams profPar) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
this->showMaximized();
QPushButton * btn[16];
QSignalMapper* sendSignalMapper = new QSignalMapper(this);//sendMessage
int k = 0, l = 1, a = 0;

for(int j=0; j<profPar.number; j++)
{
btn[j] = new QPushButton;
btn[j]->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
sendSignalMapper->setMapping(btn[j], j);
connect(btn[j],SIGNAL(clicked()),sendSignalMapper,SLOT(map()));
}

if(!connect(sendSignalMapper,SIGNAL(mapped(int)),t his ,SLOT(send_data(int))))
{
QMessageBox::critical(this,"Error", "Cannot open!", QMessageBox::Ok);
exit(0);
}
}

void MainWindow::send_data(int number)
{
sendDat("#WAIT", number);
}


CHEERS

rdkk
3rd June 2013, 08:09
sorry, i deleted unnessesary part of code and forgot to delete "else" statement ;)
anyway:



MainWindow::MainWindow(QWidget *parent, struct ProfileParams profPar) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
this->showMaximized();
QPushButton * btn[16];
QSignalMapper* sendSignalMapper = new QSignalMapper(this);//sendMessage
int k = 0, l = 1, a = 0;

for(int j=0; j<=profPar.number; j++)
{
btn[j] = new QPushButton;
btn[j]->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
sendSignalMapper->setMapping(btn[j],j);
connect(btn[j],SIGNAL(clicked()),sendSignalMapper,SLOT(map()));
}
connect(sendSignalMapper,SIGNAL(mapped(int)),this ,SLOT(send_data(int)));
}
}

void MainWindow::send_data(int number)
{
sendDat("#WAIT", number);
}


why its not working? when i click one of buttons it calls send_data, but parameter "number" is like big random number..

wysota
3rd June 2013, 08:18
Is this your real code? Please copy&paste, don't retype.

rdkk
3rd June 2013, 09:03
ok,



#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QPushButton>
#include <QFont>
#include <QSizePolicy>
#include <QSignalMapper>
#include <QGroupBox>
#include <QFileDialog>
#include <QtCore/qmath.h>

DCB dcb;
COMMTIMEOUTS CommTimeouts;
QPushButton * btn[16];


MainWindow::MainWindow(QWidget *parent, struct ProfileParams profPar) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
memset(&dcb,0,sizeof(dcb));
dcb.DCBlength = sizeof(dcb);
dcb.BaudRate = CBR_115200;
dcb.ByteSize = 8;
dcb.Parity = NOPARITY;
dcb.StopBits = ONESTOPBIT;

memset(&CommTimeouts, 0x00, sizeof(CommTimeouts));
CommTimeouts.ReadIntervalTimeout = 20;
CommTimeouts.ReadTotalTimeoutConstant = 100;
CommTimeouts.ReadTotalTimeoutMultiplier = 10;
CommTimeouts.WriteTotalTimeoutConstant = 100;
CommTimeouts.WriteTotalTimeoutMultiplier = 10;
std::string slash = "\\\\.\\COM";
std::stringstream sstm;
sstm << slash << profPar.com;
std::string portNumber = sstm.str();
char* aaa;
aaa = new char (portNumber.size());
ComParameters ComPar = {aaa};
char* str;
str = new char(portNumber.size() + 1);
strcpy(str, portNumber.c_str());
ComPar.name = str;
ComPar.dcb = dcb;
ComPar.CommTimeouts = CommTimeouts;


if(comHandle = initCom(ComPar))
{
ui->setupUi(this);
this->showMaximized();
ui->statusBar->showMessage("Port COM"+QString::number(profPar.com)+" opened", 3000);
ui->networkBox->setTitle(QString::fromStdString(profPar.name));

QList<QLayout*> m_layouts;
QSignalMapper* sendSignalMapper = new QSignalMapper(this);//sendMessage
int k = 0, l = 1, a = 0;



for(int b=0; b<profPar.sectors; b++)
{
QGroupBox *groupBox = new QGroupBox(QString::fromStdString(profPar.sectorTab[b][1]));
groupBox->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
QVBoxLayout *vbox = new QVBoxLayout;
groupBox->setLayout(vbox);
ui->tlayout->addWidget(groupBox);
m_layouts.append(vbox);
}

for(int j=0; j<profPar.number; j++)
{
btn[j] = new QPushButton;
int x = QString::fromStdString(profPar.nameTab[j][2]).toInt() - 1;
btn[j]->setObjectName(QString::fromStdString(profPar.nameT ab[j][1]));
btn[j]->setText(QString::fromStdString(profPar.nameTab[j][1]));
btn[j]->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
btn[j]->setFont(QFont("MS Shell Dlq 2", 14, 1));
sendSignalMapper->setMapping(btn[j],j);
connect(btn[j],SIGNAL(clicked()),sendSignalMapper,SLOT(map()));
m_layouts[x]->addWidget(btn[j]);
}
connect(sendSignalMapper,SIGNAL(mapped(int)),this ,SLOT(send_data(int)));
connect(ui->startButton, SIGNAL(clicked()), this, SLOT(startLstn()));
connect(ui->stopButton, SIGNAL(clicked()), this, SLOT(stopLstn()));
connect(ui->checkButton, SIGNAL(clicked()), this, SLOT(close()));
connect(ui->logButton, SIGNAL(clicked()), this, SLOT(openLog()));

}
else
{
QMessageBox::critical(this,"Error", "Cannot open", QMessageBox::Ok);
exit(0);
}
}

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

void MainWindow::send_data(int number)
{
sendDat("#WAITER_OFF", 1);
}

void MainWindow::startLstn()
{
if(startListen())
{
ui->statusBar->showMessage("Listening...");
ui->checkButton->setEnabled(false);
ui->startButton->setEnabled(false);
ui->stopButton->setEnabled(true);
ui->atButton->setEnabled(false);
ui->logButton->setEnabled(false);
}
}


void MainWindow::stopLstn()
{
if(stopListen())
{
ui->statusBar->showMessage("Stopped", 2000);
ui->checkButton->setEnabled(true);
ui->startButton->setEnabled(true);
ui->stopButton->setEnabled(false);
ui->atButton->setEnabled(true);
ui->logButton->setEnabled(true);
}
}

void MainWindow::openLog()
{
QString file = QFileDialog::getOpenFileName(this,tr("Load log file..."),"",tr("Log Files (*.bin)"));
if(!file.isEmpty())
{
logfile *lgfile = new logfile(this,file);
lgfile ->show();
}
}

wysota
3rd June 2013, 09:16
Apart from global array of buttons the code looks correct.

karankumar1609
3rd June 2013, 11:26
Your code seems good but try to create a separate QPushButton Object and then add it to your array.
Look below code


QPushButton* button = new QPushButton(this);
btn[j] = button;
...
...
sendSignalMapper->setMapping(button, j);
connect(button, SIGNAL(clicked()), sendSignalMapper, SLOT(map()), Qt::uniqueConnection);


Try to write your code with list of pointers instead of array.
Don't use global variable make it member of class.

CHEERS

anda_skoa
3rd June 2013, 11:55
QButtonGroup

less methods to call, no need for an array just to address buttons per index later on.

Cheers,
_

rdkk
4th June 2013, 16:11
thanks for replies mates ;) it solved itself and now works fine ;)

amleto
5th June 2013, 23:00
thanks for replies mates ;) it solved itself and now works fine ;)

I wish my code would do that. WHAT IS YOUR SECRET!?

wysota
5th June 2013, 23:33
I wish my code would do that. WHAT IS YOUR SECRET!?

Maybe he wrote a program that modifies its own source code, rebuilds itself and re-executes.