Lorenzo
Lorenzo

Reputation: 4668

Qt getting column position of clicked item

I have three widgets contained in a grid layout. When I click them I'd like to get their column position but I cannot find any property of the widget itself and cannot seem to get hold of the container by accessing widget.parentWidget()

I could use some indirect way such as itemAt but I'd rather find a less convoluted way of doing it.

Upvotes: 2

Views: 6638

Answers (2)

jdi
jdi

Reputation: 92657

You can simply ask the QGridLayout where the items are. Here is an example:

class Widget(QtGui.QWidget):

    def __init__(self):
        super(Widget, self).__init__()
        self.resize(600,600)

        self.layout = QtGui.QGridLayout(self)
        for row in xrange(3):
            for col in xrange(3):
                button = QtGui.QPushButton("Button %d-%d" % (row,col))
                button.clicked.connect(self.buttonClicked)
                self.layout.addWidget(button, row, col)

    def buttonClicked(self):
        button = self.sender()
        idx = self.layout.indexOf(button)
        location = self.layout.getItemPosition(idx)
        print "Button", button, "at row/col", location[:2]

All you need to know is which widget was clicked. Then you can look up the layout index with layout.indexOf(widget). With the index, you can lookup the actual (row, col, rowspan, colspan) using layout.getItemPosition(index)

No need to loop over the entire contents of the list. Also, with this approach you get the current location, as opposed to any stored column positions when the item was created. Item's can be moved around inside of a layout at any time after they have been added.

If you find the self.sender() approach "unpythonic" because you have to ask it who the calling widget was, you can also use the approach of packaging up each callback with the actual button widget ahead of time:

from functools import partial 

class Widget(QtGui.QWidget):

    def __init__(self):
        ...
            for col in xrange(3):
                button = QtGui.QPushButton("Button %d-%d" % (row,col))
                cbk = partial(self.buttonClicked, button)
                button.clicked.connect(cbk)
        ...
    def buttonClicked(self, button):
        idx = self.layout.indexOf(button)

Upvotes: 8

Joonhwan
Joonhwan

Reputation: 476

Realistic(?) psuedo code follows. not tested though.

int getColoumOfWidgetInGridLayout(QGridLayout* layout, QWidget* widget)
{
  for(int row=0; row<layout->rowCount(); ++row) {
    for(int col=0; col<layout->columnCount(); ++col) {
       if(layout->itemAtPosition(row, col)->widget()==widget) {
          return col;
       }
    }
  }
  return -1;
}

But if you feel like convoluted, then use QObject::setProperty() to store column number when building up grid layout. i.e,

myWidget->setProperty("GridColumn", column);
myGridLayout->addWidget(myWidget, row, column);

and then you could retrive the stored value by

myWidget->property("GridColumn").toInt();

Upvotes: 1

Related Questions