Search code examples
qtqpushbutton

How to get the row/column location of a widget in a QGridLayout?


I made an own GridPushButton class to store the buttons position in gridlayout. The parent is QPushButton. I have a problem with asking it's x and y coordinates in window (like x:654, y:768). I thought it will be inherited from base class, but it doesn't. Now i have two options:

  1. Use the original QPushButton class and somehow get its position in gridlayout (like x:0, y:1 if it's in the first row and second column) or

  2. Use my GridPushButton and somehow get the x and y coordinate in window.

    class GridPushButton : public QPushButton
    {
    Q_OBJECT
    public:
      GridPushButton(int coordX, int coordY, QWidget *parent = 0);
      int coordinateX() { return _coordX; }
      int coordinateY() { return _coordY; }
    
    protected:
      int _coordX;
      int _coordY;
    };
    

This is my class. I tried to make a new private variable and give it the QPushButton::x(), but doesn't work. Any idea to get the x and y coordinate from parent? Or any idea to get the QPushButtons position in GridLayout?


Solution

  • There are two notions of coordinates that you're mixing up. There is the position within the parent widget. That's available via QWidget::x(), QWidget::y() and QWidget::pos() methods. You don't need to implement anything here: it already works.

    Then there's the notion of the row and column within the grid layout. This can be obtained without a need for any subclassing. The grid layout knows where its widgets are, you can simply ask it for the row/column location of any widget.

    screenshot

    #include <QtWidgets>
    
    struct Pos { int row = -1, col = -1; };
    
    Pos gridPosition(QWidget * widget) {
      if (! widget->parentWidget()) return {};
      auto layout = qobject_cast<QGridLayout*>(widget->parentWidget()->layout());
      if (! layout) return {};
      int index = layout->indexOf(widget);
      Q_ASSERT(index >= 0);
      int _;
      Pos pos;
      layout->getItemPosition(index, &pos.row, &pos.col, &_, &_);
      return pos;
    }
    
    int main(int argc, char *argv[])
    {
       QApplication a(argc, argv);
       QWidget w;
       QGridLayout l(&w);
       QLabel gridPos;
       l.addWidget(&gridPos, 0, 0, 1, 4);
       for (int i = 1; i < 4; ++ i)
          for (int j = 0; j < 3; ++ j) {
             auto b = new QPushButton(QString("%1,%2").arg(i).arg(j));
             l.addWidget(b, i, j);
             QObject::connect(b, &QPushButton::clicked, [&gridPos, b]{
                auto p = gridPosition(b);
                gridPos.setText(QString("Grid Pos: %1,%2")
                                .arg(p.row).arg(p.col));
             });
          }
       w.show();
       return a.exec();
    }