Skip to content

Instantly share code, notes, and snippets.

@vsajip
Created February 5, 2011 18:18
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save vsajip/812648 to your computer and use it in GitHub Desktop.
Save vsajip/812648 to your computer and use it in GitHub Desktop.
Script showing QTreeView problem
# Copyright (C) 2011 Vinay Sajip. All rights reserved.
import PySide
import PySide.QtCore as QtCore
import PySide.QtGui as QtGui
Qt = QtCore.Qt
import bisect
import logging
import os
import sys
appname = os.path.splitext(os.path.basename(sys.argv[0]))[0]
logger = logging.getLogger(appname)
class TreeNode(object):
def __init__(self, parent, name):
self.parent = parent
self.name = name
self.children = []
@property
def path(self):
result = [self.name]
if self.parent and self.parent.parent:
result.insert(0, self.parent.path)
return '.'.join(result)
class TreeModel(QtCore.QAbstractItemModel):
def __init__(self, parent):
super(TreeModel, self).__init__(parent)
self._root = TreeNode(None, '')
self._registry = {
'': self._root,
}
def columnCount(self, parent):
return 1
def createIndex(self, row, col, ptr):
if ptr:
path = ptr.path
else:
path = ''
result = super(TreeModel, self).createIndex(row, col, ptr)
logger.debug('creating index: %d, %d, %r -> %s', row, col, path, result)
return result
def index(self, row, column, parent):
invindex = QtCore.QModelIndex()
try:
if not parent.isValid():
result = self.createIndex(row, column, self._root)
else:
node = parent.internalPointer()
result = self.createIndex(row, column, node.children[row])
except IndexError:
result = invindex
return result
def parent(self, index):
invindex = QtCore.QModelIndex()
result = invindex
if index.isValid():
node = index.internalPointer()
if node.parent is not None:
result = self.createIndex(0, 0, node.parent)
parentpath = node.parent.path
else:
parentpath = ''
valid = not (result is invindex)
if valid:
logger.debug('parent: returning %r as parent of %r', parentpath, node.path)
return result
def rowCount(self, parent):
if not parent.isValid():
result = 1
path = ''
else:
node = parent.internalPointer()
result = len(node.children)
path = node.path
logger.debug('rowCount: returning %d for %r', result, path)
return result
def data(self, index, role=Qt.DisplayRole):
result = None
if index.isValid():
node = index.internalPointer()
if role == Qt.DisplayRole:
try:
result = node.name
if not node.parent:
result = 'Root node'
except Exception:
pass
elif role == Qt.ToolTipRole:
path = node.path
if node.parent:
ppath = node.parent.path
else:
ppath = ''
rc = self.rowCount(index)
result = '%r (parent: %r, children: %d)' % (path, ppath, rc)
return result
def headerData(self, section, orientation, role):
result = None
if orientation == Qt.Horizontal and role == Qt.DisplayRole:
result = 'PySide %s on Qt %s' % (PySide.__version__, QtCore.__version__)
return result
def register_node(self, name):
logger.debug('register_node: %s', name)
if name in self._registry:
result = self._registry[name]
else:
parts = name.rsplit('.', 1)
nodename = parts[-1]
if len(parts) == 1:
parent = self._root
else:
parent = self.register_node(parts[0])
pindex = self.createIndex(0, 0, parent)
names = [c.name for c in parent.children]
pos = bisect.bisect(names, nodename)
result = TreeNode(parent, nodename)
self._registry[name] = result
self.beginInsertRows(pindex, pos, pos)
parent.children.insert(pos, result)
self.endInsertRows()
return result
NODES = [
'zmq.sheila.fred.jim',
'tcp.fred',
'udp.jim.fred',
'udp.jim.sheila.fred',
'udp.jim.sheila.fred',
'tcp.jim.fred',
'tcp.sheila.fred.jim',
'tcp.jim.fred',
'udp.sheila.fred.jim',
'zmq.fred',
'zmq.sheila',
'tcp.sheila.fred',
'udp.jim.fred.sheila',
'udp.fred.jim.sheila',
'udp.fred.jim',
'udp.sheila.fred.jim',
'tcp.jim.sheila.fred',
'zmq.jim',
'udp.sheila.jim',
'tcp.fred.sheila',
'udp.fred',
'udp.jim.sheila',
'zmq.sheila.fred.jim',
'tcp.fred.jim.sheila',
'udp.fred.jim',
'udp.fred.sheila.jim',
]
class MainWindow(QtGui.QTreeView):
def __init__(self):
super(MainWindow, self).__init__()
self.tmodel = tmodel = TreeModel(self)
self.setModel(tmodel)
for node in NODES:
tmodel.register_node(node)
def main():
app = QtGui.QApplication(sys.argv)
main = MainWindow()
main.setWindowTitle('Tree Test')
main.show()
app.exec_()
if __name__ == '__main__':
h = logging.FileHandler('%s.log' % appname, 'w')
root = logging.getLogger()
root.addHandler(h)
root.setLevel(logging.DEBUG)
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment