internalPointer方法的工作方式 [英] How internalPointer method works

查看:828
本文介绍了internalPointer方法的工作方式的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Car()Plane()下方的代码中,都是从Base类继承的.

每次单击QTableView时,OnClick()方法都会收到QModelIndex作为其传入参数.

OnClick()方法范围之内,node=index.internalPointer()行返回在模型的self.items变量中定义的Car或Plane的实例.

模型的self.items不是列表,而是子类的分层变量.但是internalPointer()方法确实使它看起来像是对一个列表变量进行了索引,并为其提供了被单击的QModelIndex行号作为参数.

如果您提供有关internalPointer()方法工作方式的更多详细信息,以便我可以相应地设计Plane,Car和Base类(这样它们将返回我想要的而不是internalPointer().

),我将不胜感激.

from PyQt4 import QtCore, QtGui
app=QtGui.QApplication(sys.argv)

class Base(object):    
    def __init__(self, name, parentNode=None):        
        self._name = name
        self._children=[]
        self._parentNode=parentNode
        if parentNode is not None:
            parentNode.addChild(self)
    def typeInfo(self):
        return "BaseNode"
    def addChild(self, child):
        self._children.append(child)
    def name(self):
        return self._name
    def setName(self, name):
        self._name = name
    def child(self, row):
        return self._children[row]
    def childCount(self):
        return len(self._children)
    def getParent(self):
        return self._parentNode
    def row(self):
        if self._parentNode is not None:
            return self._parentNode._children.index(self)

class Car(Base):    
    def __init__(self, name, parent=None):
        super(Car, self).__init__(name, parent)        
    def typeInfo(self):
        return "CarNode"
class Plane(Base):    
    def __init__(self, name, parent=None):
        super(Plane, self).__init__(name, parent)        
    def typeInfo(self):
        return "PlaneNode"

class DataModel(QtCore.QAbstractItemModel):
    def __init__(self):
        QtCore.QAbstractTableModel.__init__(self)  

        self.items = Base("Base")
        car0 = Car("Car0",  self.items)
        car1 = Car("Car1",  car0)
        car2 = Car("Car2",  car1)

        plane0 = Plane("Plane0",  self.items)
        plane1 = Plane("Plane1",  plane0)
        plane2 = Plane("Plane2",  plane1) 

    def columnCount(self, index=QtCore.QModelIndex()):
        return 3

    def getNodeFromIndex(self, index):    
        if index.isValid():
            node = index.internalPointer()
            if node:
                return node            
        return self.items

    def parent(self, index):
        node = self.getNodeFromIndex(index)
        parentNode = node.getParent()
        if parentNode == self.items:
            return QtCore.QModelIndex()
        return self.createIndex(parentNode.row(), 0, parentNode)

    def index(self, row, column, parentIndex):
        parentNode = self.getNodeFromIndex(parentIndex)
        childItem = parentNode.child(row)
        if childItem:            
            newIndex=self.createIndex(row, column, childItem)
            return newIndex
        else:
            return QtCore.QModelIndex()

    def rowCount(self, parent=QtCore.QModelIndex()):
        if not parent.isValid():
            parentNode = self.items
        else:
            parentNode = parent.internalPointer()
        return parentNode.childCount()

    def data(self, index, role):
        if not index.isValid(): return QtCore.QVariant()
        row=index.row()
        column=index.column()
        node=index.internalPointer()

        if role==QtCore.Qt.DisplayRole:
            if column==0 and not self.columnCount():
                return QtCore.QModelIndex()
            else:
                return QtCore.QModelIndex()

class Window(QtGui.QWidget):
    def __init__(self):
        super(Window, self).__init__()
        mainLayout=QtGui.QHBoxLayout()
        self.setLayout(mainLayout)   

        self.dataModel=DataModel()

        self.viewA=QtGui.QTableView()
        self.viewA.setModel(self.dataModel)
        self.viewA.clicked.connect(self.onClick)

        mainLayout.addWidget(self.viewA)  
        self.show()

    def onClick(self, index):
        node=index.internalPointer()
        print node.name(), node.getParent().name()

window=Window()
sys.exit(app.exec_())

解决方案

通过相应地设计类尚不清楚您的意思,但内部指针仅是您在QModelIndex中使用createIndex()创建的内容. /p>

请参见 createIndex 的文档.

因此,您可以在其中存储一些有用的东西.

In a code below both Car() and Plane() inherit from Base class.

Every time QTableView is clicked OnClick() method receives a QModelIndex as its incoming argument.

Inside of scope of OnClick() method node=index.internalPointer() line returns an instance of either Car or Plane defined in model's self.items variable.

Model's self.items is not a list but a sub-classed hierarchical variable. Yet internalPointer() method does make it appear it indexes a list variable with the supplied to it as an argument the row number of QModelIndex that was clicked.

I would appreciate if you supply more details on how internalPointer() method works so I could design Plane, Car and Base classes accordingly (so they return what I want and not what internalPointer().

from PyQt4 import QtCore, QtGui
app=QtGui.QApplication(sys.argv)

class Base(object):    
    def __init__(self, name, parentNode=None):        
        self._name = name
        self._children=[]
        self._parentNode=parentNode
        if parentNode is not None:
            parentNode.addChild(self)
    def typeInfo(self):
        return "BaseNode"
    def addChild(self, child):
        self._children.append(child)
    def name(self):
        return self._name
    def setName(self, name):
        self._name = name
    def child(self, row):
        return self._children[row]
    def childCount(self):
        return len(self._children)
    def getParent(self):
        return self._parentNode
    def row(self):
        if self._parentNode is not None:
            return self._parentNode._children.index(self)

class Car(Base):    
    def __init__(self, name, parent=None):
        super(Car, self).__init__(name, parent)        
    def typeInfo(self):
        return "CarNode"
class Plane(Base):    
    def __init__(self, name, parent=None):
        super(Plane, self).__init__(name, parent)        
    def typeInfo(self):
        return "PlaneNode"

class DataModel(QtCore.QAbstractItemModel):
    def __init__(self):
        QtCore.QAbstractTableModel.__init__(self)  

        self.items = Base("Base")
        car0 = Car("Car0",  self.items)
        car1 = Car("Car1",  car0)
        car2 = Car("Car2",  car1)

        plane0 = Plane("Plane0",  self.items)
        plane1 = Plane("Plane1",  plane0)
        plane2 = Plane("Plane2",  plane1) 

    def columnCount(self, index=QtCore.QModelIndex()):
        return 3

    def getNodeFromIndex(self, index):    
        if index.isValid():
            node = index.internalPointer()
            if node:
                return node            
        return self.items

    def parent(self, index):
        node = self.getNodeFromIndex(index)
        parentNode = node.getParent()
        if parentNode == self.items:
            return QtCore.QModelIndex()
        return self.createIndex(parentNode.row(), 0, parentNode)

    def index(self, row, column, parentIndex):
        parentNode = self.getNodeFromIndex(parentIndex)
        childItem = parentNode.child(row)
        if childItem:            
            newIndex=self.createIndex(row, column, childItem)
            return newIndex
        else:
            return QtCore.QModelIndex()

    def rowCount(self, parent=QtCore.QModelIndex()):
        if not parent.isValid():
            parentNode = self.items
        else:
            parentNode = parent.internalPointer()
        return parentNode.childCount()

    def data(self, index, role):
        if not index.isValid(): return QtCore.QVariant()
        row=index.row()
        column=index.column()
        node=index.internalPointer()

        if role==QtCore.Qt.DisplayRole:
            if column==0 and not self.columnCount():
                return QtCore.QModelIndex()
            else:
                return QtCore.QModelIndex()

class Window(QtGui.QWidget):
    def __init__(self):
        super(Window, self).__init__()
        mainLayout=QtGui.QHBoxLayout()
        self.setLayout(mainLayout)   

        self.dataModel=DataModel()

        self.viewA=QtGui.QTableView()
        self.viewA.setModel(self.dataModel)
        self.viewA.clicked.connect(self.onClick)

        mainLayout.addWidget(self.viewA)  
        self.show()

    def onClick(self, index):
        node=index.internalPointer()
        print node.name(), node.getParent().name()

window=Window()
sys.exit(app.exec_())

解决方案

It's not exactly clear what you mean by designing your classes accordingly, but internal pointer ist just something you create with help of createIndex() in QModelIndex.

See the documentation of createIndex.

So it's up to you to store something useful in it.

这篇关于internalPointer方法的工作方式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆