Question

This is a follow up question of Efficient way to make an array of labels.

I have an array of buttons made by code (not designer) which are all added to a gridlayout. What I want is to be able to click any button on that gridlayout and call one same function with the row and column as parameters. Why I want this is because I do not feel like writing 15x15 functions which all do the same thing.

Is there a way or should I try to find another solution?

Ps. All my other input is made in the qt designer via "go to slot" so if it has to happen otherwise, I'll be clueless about how to.

Edit: The array of labels is now an array of buttons.

Was it helpful?

Solution

You could connect all of your buttons to a slot with no parameters and then get the position of the sender in this steps:

  1. Cast the sender QObject to a QWidget via qobject_cast
  2. Retrieve the index of that QWidget using QLayout::indexOf(QWidget *widget)
  3. Then get the row, column, column span and row span with the QGridLayout::getItemPosition(int index, int *row, int *column, int *rowSpan, int *columnSpan)

The example code would look like this:

void MyWidgetWithAllLabels::commonSlot() 
{
   QWidget *buttonWidget = qobject_cast<QWidget*>(sender());
   if (!buttonWidget)
      return;

   int indexOfButton = ui->gridLayout->indexOf(buttonWidget);
   int rowOfButton, columnOfButton, rowSpanOfButton, columnSpanOfButton;

   ui->gridLayout->getItemPosition(indexOfButton,
                                   &rowOfButton, &columnOfButton, &rowSpanOfButton, &columnSpanOfLabel);
    // Now you can get a reference to that specific QPushButton 
    QLayoutItem *item = ui->gridLayout->itemAtPosition(rowOfButton, columnOfButton);
    QPushButton *clickedButton = qobject_cast<QPushButton*>(item->widget());
    if (!clickedButton) 
        return;
    // ... do something with that clickedButton
}

Referring to the code in your related post, you can connect your buttons to that slot like this:

connect( ui->tile_0_0, SIGNAL(clicked()),
         this, SLOT(commonSlot()));
connect( ui->tile_0_1, SIGNAL(clicked()),
         this, SLOT(commonSlot()));
    // ...

OTHER TIPS

By default, a QLabel has no "clicked" signal. But you can do your own QLabel with 2 integers (row, col) and when you've got a mouseReleaseEvent (or mousePressEvent), you send a custom signal that looks like this: clicked(int row, int col).

You can also use a QSignalMapper: http://qt-project.org/doc/qt-4.8/qsignalmapper.html#details

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