0

I am trying to disable button previously chosen by user

void pracownik2::on_pushButton_4_clicked(){

this->setWindowTitle("EKRAN");
QWidget *centralWidget = new QWidget;
        int licznik=1;
        QString licz;
        //QString kolumny = ui->lineEdit->text();
        //QString wiersze = ui->lineEdit_2->text();
        miejsca2 = ui->lineEdit_3->text().toInt();
        //QPushButton *button[wiersze.toInt()][kolumny.toInt()];
        QPushButton *button[3][6];

        QGridLayout *controlsLayout = new QGridLayout;
        for(int i=0;i<3;i++)
        {
            for(int j=0;j<6;j++)
            {
                    licz = QString::number(licznik);
                    licznik++;
                    button[i][j] = new QPushButton(licz);
                    button[i][j]->setCheckable(1);
                        if(tab[i][j]==1)
                            button[i][j]->setEnabled(false);
                    controlsLayout->addWidget(button[i][j], i, j);
            }
        }

        QPushButton *okej = new QPushButton("Zatwierdź");
        QPushButton *anul = new QPushButton("Anuluj");

        controlsLayout->addWidget(okej, 3, 0);
        controlsLayout->addWidget(anul, 3, 1);

        controlsLayout->setHorizontalSpacing(0);
        controlsLayout->setVerticalSpacing(0);
        centralWidget->setLayout(controlsLayout);

        setCentralWidget(centralWidget);



        for(int i=0;i<3;i++)
        {
            for(int j=0;j<6;j++)
            {
                    connect(button[i][j],SIGNAL(toggled(bool)),this,SLOT(tescik(bool)));
            }
        }



        connect(anul,SIGNAL(clicked()),this,SLOT(close()));

        connect(okej,SIGNAL(clicked()),this,SLOT(okay2()));}

void pracownik2::tescik(bool t){
    if (t)
{
    tab[i][j]=1;
    miejsca++;
}
else
{
    tab[i][j]=0;
    miejsca--;
}}

but my 'tescik' function doesn't know what 'i' and 'j' are and the project won't compile, my question is how to make checked button set value 1 in the array and unchecked restore it to 0. I guess I have to edit 'connect' line but I have no idea how

@EDIT I am trying to make this line

connect(button[i][j],SIGNAL(toggled(bool)),this,SLOT(tescik(bool,int i,int j)));

pass 'i' and 'j' of current button to function but it doesn't work

CentusDBWA
  • 11
  • 4
  • `connect(button[i][j], SIGNAL(toggled(bool)), button[i][j], SLOT(setDisabled(bool)));` additionaly – mip Jan 24 '15 at 13:09
  • could you write something more about it cause I don't get it – CentusDBWA Jan 24 '15 at 13:11
  • If it's going to be disabled after being pressed, then how do you want to restore value in the array to 0? – mip Jan 24 '15 at 13:13
  • @CentusDBWA does your previous call: connect(button[i][j],SIGNAL(toggled(bool)),this,SLOT(tescik(bool))); } work? – 4pie0 Jan 24 '15 at 13:14
  • because changing array values isn't doing anything instantly, when the buttons are being shown second time, some of them are not enabled @AB_ yes it works – CentusDBWA Jan 24 '15 at 13:15
  • @CentusDBWA to disable toggled button you can connect its `toggled()` signal with `setDisabled()` slot additionaly to connecting it with `tescik()` function.. – mip Jan 24 '15 at 13:16
  • What error do you receive when it "doesn't work"? Please paste what compiler and meta compiler say. – 4pie0 Jan 24 '15 at 13:17
  • No such slot pracownik2::tescik(bool,i,j) in ..\testpobi\pracownik2.cpp:83 line 83 is connect(button[i][j],SIGNAL(toggled(bool)),this,SLOT(tescik(bool,i,j))); I tried making it (bool,int,int) etc and still it doesn't work – CentusDBWA Jan 24 '15 at 13:18
  • be sure to run qmake, you must always run it after changes have been made to signal/slots – 4pie0 Jan 24 '15 at 13:22
  • Is it going to change state after user presses "OK"? If so, why don't you just check button states in the loop. You could do this inside `okay2()` slot. – mip Jan 24 '15 at 13:24
  • @CentusDBWA did you run qmake? – 4pie0 Jan 24 '15 at 13:52
  • Yes I did, the problem is I can't pass the arguements properly – CentusDBWA Jan 24 '15 at 13:59
  • You can not do `connect(button[i][j],SIGNAL(toggled(bool)),this,SLOT(tescik(bool,int i,int j)));`. Signal and slot signature must be compatible with each other. `QPushButton` would need to provide signal `toggled(bool, int, int)` to establish connection. Either extend `QPushButton` or check state of the buttons inside a loop as I said earlier. – mip Jan 24 '15 at 14:15

2 Answers2

0

You can't connect

connect(button[i][j],SIGNAL(toggled(bool)),this,SLOT(tescik(bool,int i,int j)));

because how would toggled know what values of i,j pass to tescik?

You can however write a wrapper over QPushButtons so you can connect their toggled(bool) signals to single slot toggled( int, int) of this wrapper using QSignalMapper. Then you can manage all this logic in such wrapper:

class ButtonHelperEntry
{
public:
    int i_;
    int j_;
    QPushButton* button_;
}

void ButtonHelper::initialize( const std::vector<
                                   QSharedPointer<ButtonHelperEntry> >& entries)
{
    entries_ = entries;
    mapper_.reset(new QSignalMapper(this));
    EntriesIterator it = entries_.begin();

    while ( it!=entries_.end())
    {
       connect(( *it)->button_, SIGNAL( toggled(bool)), mapper_.data(), 
                                                                   SLOT(map()));
       mapper_->setMapping( ( *it)->button_, (int)( *it)->i_, (int)( *it)->j_);
       it++;
       i++;
    }
    connect( mapper_.data(), SIGNAL( mapped(int,int)), 
                             this, SIGNAL( toggled(int,int)));
    connect( this, SIGNAL( toggled(int)), this, SLOT( updateValue(int)));
}
4pie0
  • 29,204
  • 9
  • 82
  • 118
0

I would set i and j as properties of each button:

...
button[i][j]->setProperty("i", i);
button[i][j]->setProperty("j", j);
...

Then in tescik() get the sender and load i and j:

void pracownik2::tescik(bool t) {
   QObject * pSender = sender();
   int i = pSender->property("i").toInt();
   int j = pSender->property("j").toInt();

   if (t) {
   ...
mjk99
  • 1,290
  • 11
  • 18