【问题标题】:python call parent method from child widgetpython从子小部件调用父方法
【发布时间】:2015-10-28 17:40:57
【问题描述】:

我正在尝试从子小部件 treeView 调用父方法 printName 但得到类似的错误

  1. AttributeError: 'QSplitter' 对象没有属性 'printName'
  2. QObject::startTimer:QTimer 只能用于以 QThread 启动的线程

为什么 parent 指的是 QSplitter ?

TreeView 的父级应该是 compositeWidget,因为 TreeView 是在 compositeWidget 中创建的

代码:

from PyQt4.QtCore import *
from PyQt4.QtGui import *
import sys


class MainExample(QMainWindow):

    def __init__(self, parent=None):
        super(MainExample, self).__init__(parent)
        self.initUI()

    def initUI(self):
        self.mainWidget = compositeWidget(self)
        self.setCentralWidget(self.mainWidget)
        self.mainWidget.treeView.setPath('D:\DATA')
        self.setGeometry(300, 300, 300, 200)


class TreeView(QTreeView):

    def __init__(self, parent):
        super(TreeView, self).__init__(parent)
        self.clicked.connect(self.on_treeView_clicked)

    @pyqtSlot(QModelIndex)
    def on_treeView_clicked(self, index):
        indexItem = self.FileSystemModel.index(index.row(), 0, index.parent())
        filePath = self.FileSystemModel.filePath(indexItem)
        self.parent().printName(filePath)
        #

    def setPath(self, path):
        self.FileSystemModel = QFileSystemModel()
        self.FileSystemModel.setFilter(QDir.Dirs | QDir.NoDotAndDotDot)
        self.FileSystemModel.setRootPath(path)
        self.setModel(self.FileSystemModel)
        index = self.FileSystemModel.index(path)
        self.setRootIndex(index)


class compositeWidget(QWidget):

    def __init__(self, parent):
        super(compositeWidget, self).__init__(parent)
        self.treeView = TreeView(self)
        self.frame = QFrame()
        splitterHorizontal = QSplitter(Qt.Horizontal)
        splitterHorizontal.addWidget(self.treeView)
        splitterHorizontal.addWidget(self.frame)
        splitterHorizontal.setSizes([10, 190])
        self.layout = QHBoxLayout(self)
        self.layout.addWidget(splitterHorizontal)
        self.setLayout(self.layout)

    def printName(self):
        print 'fileName'


def main():

    app = QApplication(sys.argv)
    ex = MainExample()
    ex.show()
    sys.exit(app.exec_())


if __name__ == '__main__':
    main()

【问题讨论】:

  • 嗨,在我看来,splitterHorizontal 在调用addWidget(self.treeView) 时将自己注册为父级,因此会出现错误。如果您修改TreeView 构造函数并添加一个额外的参数compWidget 以指向您想要的对象(存储它并稍后使用)会发生什么?然后您将使用self.treeView = TreeView(self, self) 进行初始化。另外,如果您在addWiget() 之后执行treeView.parent(),会打印什么?

标签: python pyqt pyqt4


【解决方案1】:

QTreeView 在QSplitter 下,女巫在compositeWidget 下。 你需要打电话

self.parent().parent().printName(filePath)

【讨论】:

  • 在构造函数中使用参数不是更好吗?所以类是独立于布局的?但是,如果您的方法有效,则可以将其设为函数并向上搜索(调用parent())直到他/她找到compositeWidget 的一个实例! :)
【解决方案2】:

不幸的是,这似乎没有记录在案(这似乎有点疏忽),但与 Qt 中的其他 addWidget() 方法(如 QLayout.addWidget())一样,QSplitter.addWidget() 方法通过以下方式获得孩子的所有权成为它的父母。

这就是QSplitterTreeview.parent() 返回的原因。您应该使用另一种方式来访问您想要的父级(例如,显式存储对您传递给构造函数的父级的引用)

class TreeView(QTreeView):

    def __init__(self, parent):
        super(TreeView, self).__init__(parent)
        self.clicked.connect(self.on_treeView_clicked)
        self.composite_widget = parent

    @pyqtSlot(QModelIndex)
    def on_treeView_clicked(self, index):
        indexItem = self.FileSystemModel.index(index.row(), 0, index.parent())
        filePath = self.FileSystemModel.filePath(indexItem)
        self.composite_widget.printName(filePath)
        #

    def setPath(self, path):
        self.FileSystemModel = QFileSystemModel()
        self.FileSystemModel.setFilter(QDir.Dirs | QDir.NoDotAndDotDot)
        self.FileSystemModel.setRootPath(path)
        self.setModel(self.FileSystemModel)
        index = self.FileSystemModel.index(path)
        self.setRootIndex(index)

【讨论】:

    猜你喜欢
    • 2020-04-23
    • 2021-02-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-01-01
    • 1970-01-01
    • 2014-09-23
    • 2020-09-11
    相关资源
    最近更新 更多