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

1

6

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?

Roping answered 12/6, 2014 at 16:15 Comment(0)
C
15

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();
}
Capacitor answered 12/6, 2014 at 19:2 Comment(3)
and what if the cell is empty, but exists and you need it`s row and column for placing some widget? you have only coordinates. And you have 2,3 or more such cells?Schaab
@Schaab You'll have to iterate the layout and get the rects of its items, then, unless QLayout provides a hit test (I don't recall at the moment).Premolar
yeh, it is 'containes(QPos)' but another problem I got - it`s variable row cols count unless i used to create empty determined (for example 10x10) empty items in grid. I just keeping experiments in that way and debug.Schaab

© 2022 - 2024 — McMap. All rights reserved.