我在网格布局中包含三个小部件。当我单击它们时,我想获取它们的列位置,但我找不到小部件本身的任何属性,并且似乎无法通过访问来获取容器widget.parentWidget()
我可以使用一些间接方式,例如 itemAt,但我宁愿找到一种不那么复杂的方式。
您可以简单地询问 QGridLayout 项目在哪里。这是一个例子:
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]
您只需要知道单击了哪个小部件。然后您可以使用 查找布局索引layout.indexOf(widget)
。使用索引,您可以查找实际(row, col, rowspan, colspan)
使用layout.getItemPosition(index)
无需遍历列表的全部内容。此外,通过这种方法,您可以获得当前位置,而不是创建项目时存储的任何列位置。项目添加后可以随时在布局内移动。
如果您发现self.sender()
方法“unpythonic”,因为您必须询问调用小部件是谁,您还可以使用提前将每个回调与实际按钮小部件打包的方法:
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)
现实(?)伪代码如下。虽然没有测试。
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;
}
但是如果你觉得很复杂,那么在构建网格布局时使用 QObject::setProperty() 来存储列号。IE,
myWidget->setProperty("GridColumn", column);
myGridLayout->addWidget(myWidget, row, column);
然后你可以通过
myWidget->property("GridColumn").toInt();