Created
February 5, 2011 18:18
-
-
Save vsajip/812648 to your computer and use it in GitHub Desktop.
Script showing QTreeView problem
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# 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