Python QScrollArea子项无法访问父项
我有一个内部有几个按钮的QScrollArea。我无法使parent()方法在子窗口小部件上工作,以便它返回parent对象。在创建子按钮时,我确实将self.scroll作为父级传递,但这似乎不起作用 为什么我需要使用parent()3次才能访问QScrollArea对象?我希望单亲()会给我这样的机会 这是代码。我从中借用了代码作为示例Python QScrollArea子项无法访问父项,python,pyqt,pyqt5,qscrollarea,Python,Pyqt,Pyqt5,Qscrollarea,我有一个内部有几个按钮的QScrollArea。我无法使parent()方法在子窗口小部件上工作,以便它返回parent对象。在创建子按钮时,我确实将self.scroll作为父级传递,但这似乎不起作用 为什么我需要使用parent()3次才能访问QScrollArea对象?我希望单亲()会给我这样的机会 这是代码。我从中借用了代码作为示例 from PyQt5.QtWidgets import (QWidget, QScrollArea, QVBoxLayout, QMainWindow) f
from PyQt5.QtWidgets import (QWidget, QScrollArea, QVBoxLayout, QMainWindow)
from PyQt5.QtCore import Qt
from PyQt5 import QtWidgets
import sys
class ChildWidget(QtWidgets.QPushButton):
def __init__(self, parent):
super(ChildWidget, self).__init__(parent)
def mousePressEvent(self, event):
print(self.parent().metaObject().className())
print(self.parent().parent().metaObject().className())
print(self.parent().parent().parent().metaObject().className())
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
self.scroll = QScrollArea()
self.widget = QWidget()
self.vbox = QVBoxLayout()
for i in range(1, 5):
object = ChildWidget(self.scroll)
self.vbox.addWidget(object)
self.widget.setLayout(self.vbox)
self.scroll.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOn)
self.scroll.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
self.scroll.setWidgetResizable(True)
self.scroll.setWidget(self.widget)
self.setCentralWidget(self.scroll)
self.setGeometry(600, 100, 1000, 900)
self.setWindowTitle('Scroll Area Demonstration')
self.show()
return
def main():
app = QtWidgets.QApplication(sys.argv)
main = MainWindow()
sys.exit(app.exec_())
if __name__ == '__main__':
main()
按钮按下的返回为:
QWidget
QWidget
QScrollArea
将小部件添加到布局时,该小部件是处理布局的容器(QWidget)的子部件 在您的情况下,只需添加一些打印即可了解父项何时更改:
# ...
# variable that stores the first ChildWidget:
first_widget = None
for i in range(1, 5):
object = ChildWidget(self.scroll)
if first_widget is None:
first_widget = object
self.vbox.addWidget(object)
print(first_widget.parent())
self.widget.setLayout(self.vbox)
print(first_widget.parent())
输出:
<PyQt5.QtWidgets.QScrollArea object at 0x7fb699721dc0>
<PyQt5.QtWidgets.QWidget object at 0x7fb699721e50>
MainWindow::
QMainWindowLayout::_layout
QScrollArea::
QWidget::qt_scrollarea_viewport
QWidget::
QVBoxLayout::
ChildWidget::
ChildWidget::
ChildWidget::
ChildWidget::
QWidget::qt_scrollarea_hcontainer
QScrollBar::
QBoxLayout::
QPropertyAnimation::
QPropertyAnimation::
QWidget::qt_scrollarea_vcontainer
QScrollBar::
QBoxLayout::
输出:
<PyQt5.QtWidgets.QScrollArea object at 0x7fb699721dc0>
<PyQt5.QtWidgets.QWidget object at 0x7fb699721e50>
MainWindow::
QMainWindowLayout::_layout
QScrollArea::
QWidget::qt_scrollarea_viewport
QWidget::
QVBoxLayout::
ChildWidget::
ChildWidget::
ChildWidget::
ChildWidget::
QWidget::qt_scrollarea_hcontainer
QScrollBar::
QBoxLayout::
QPropertyAnimation::
QPropertyAnimation::
QWidget::qt_scrollarea_vcontainer
QScrollBar::
QBoxLayout::
观察到ChildWidget和QScrolArea的层次结构的地方。将小部件添加到布局时,该小部件是处理布局的容器(QWidget)的子部件 在您的情况下,只需添加一些打印即可了解父项何时更改:
# ...
# variable that stores the first ChildWidget:
first_widget = None
for i in range(1, 5):
object = ChildWidget(self.scroll)
if first_widget is None:
first_widget = object
self.vbox.addWidget(object)
print(first_widget.parent())
self.widget.setLayout(self.vbox)
print(first_widget.parent())
输出:
<PyQt5.QtWidgets.QScrollArea object at 0x7fb699721dc0>
<PyQt5.QtWidgets.QWidget object at 0x7fb699721e50>
MainWindow::
QMainWindowLayout::_layout
QScrollArea::
QWidget::qt_scrollarea_viewport
QWidget::
QVBoxLayout::
ChildWidget::
ChildWidget::
ChildWidget::
ChildWidget::
QWidget::qt_scrollarea_hcontainer
QScrollBar::
QBoxLayout::
QPropertyAnimation::
QPropertyAnimation::
QWidget::qt_scrollarea_vcontainer
QScrollBar::
QBoxLayout::
输出:
<PyQt5.QtWidgets.QScrollArea object at 0x7fb699721dc0>
<PyQt5.QtWidgets.QWidget object at 0x7fb699721e50>
MainWindow::
QMainWindowLayout::_layout
QScrollArea::
QWidget::qt_scrollarea_viewport
QWidget::
QVBoxLayout::
ChildWidget::
ChildWidget::
ChildWidget::
ChildWidget::
QWidget::qt_scrollarea_hcontainer
QScrollBar::
QBoxLayout::
QPropertyAnimation::
QPropertyAnimation::
QWidget::qt_scrollarea_vcontainer
QScrollBar::
QBoxLayout::
观察到ChildWidget和QScrolArea的层次结构。设置父项不是“最终的”
来自(以及所有QLayout子类的重新实现):
[…]此函数使用addItem()
发件人:
注意:项目的所有权转移到版面,版面有责任删除它
当版面已经设置为小部件时,所有权转移到版面的小部件(如果版面新设置为小部件,也会发生同样的情况)
此外,当您使用QabStretchScrollArea子体(显然包括QScrollArea)时,您将使用一个QWidget作为“视口”(滚动区域内的小部件),它将滚动区域作为父对象。使用QScrollArea时,setWidget(widget)
将小部件重新复制到视口
因此,实际的层次结构是:
scrollarea
viewport
"container" widget
button
如果要查找父滚动区域(假设未使用嵌套滚动区域,包括项目视图子体),可以执行以下操作:
class ChildWidget(QtWidgets.QPushButton):
def __init__(self, parent):
super(ChildWidget, self).__init__(parent)
def mousePressEvent(self, event):
obj = self
while not isinstance(obj.parent(), QAbstractScrollArea):
parent = obj.parent()
if not parent:
break
obj = parent
print(obj)
设置父项不是“最终的”
来自(以及所有QLayout子类的重新实现):
[…]此函数使用addItem()
发件人:
注意:项目的所有权转移到版面,版面有责任删除它
当版面已经设置为小部件时,所有权转移到版面的小部件(如果版面新设置为小部件,也会发生同样的情况)
此外,当您使用QabStretchScrollArea子体(显然包括QScrollArea)时,您将使用一个QWidget作为“视口”(滚动区域内的小部件),它将滚动区域作为父对象。使用QScrollArea时,setWidget(widget)
将小部件重新复制到视口
因此,实际的层次结构是:
scrollarea
viewport
"container" widget
button
如果要查找父滚动区域(假设未使用嵌套滚动区域,包括项目视图子体),可以执行以下操作:
class ChildWidget(QtWidgets.QPushButton):
def __init__(self, parent):
super(ChildWidget, self).__init__(parent)
def mousePressEvent(self, event):
obj = self
while not isinstance(obj.parent(), QAbstractScrollArea):
parent = obj.parent()
if not parent:
break
obj = parent
print(obj)
谢谢你的dumpObjectTree(),我正准备要它呢!谢谢你的dumpObjectTree(),我正准备要它呢!