Skip to content

Instantly share code, notes, and snippets.

@jason-s
Last active August 8, 2021 20:22
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save jason-s/9dcef741288b6509d362 to your computer and use it in GitHub Desktop.
Save jason-s/9dcef741288b6509d362 to your computer and use it in GitHub Desktop.
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# based on
# https://qt.gitorious.org/pyside/pyside-examples/source/060dca8e4b82f301dfb33a7182767eaf8ad3d024:examples/itemviews/simpletreemodel/simpletreemodel.py
############################################################################
##
## Copyright (C) 2005-2005 Trolltech AS. All rights reserved.
##
## This file is part of the example classes of the Qt Toolkit.
##
## This file may be used under the terms of the GNU General Public
## License version 2.0 as published by the Free Software Foundation
## and appearing in the file LICENSE.GPL included in the packaging of
## this file. Please review the following information to ensure GNU
## General Public Licensing requirements will be met:
## http://www.trolltech.com/products/qt/opensource.html
##
## If you are unsure which license is appropriate for your use, please
## review the following information:
## http://www.trolltech.com/products/qt/licensing.html or contact the
## sales department at sales@trolltech.com.
##
## This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
## WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
##
############################################################################
from PySide import QtCore, QtGui
class TreeItem(object):
def __init__(self, data, parent=None):
self.parentItem = parent
self.itemData = data
self.childItems = []
def appendChild(self, item):
self.childItems.append(item)
def child(self, row):
return self.childItems[row]
def childCount(self):
return len(self.childItems)
def columnCount(self):
return len(self.itemData)
def data(self, column):
try:
return self.itemData[column]
except IndexError:
return None
def parent(self):
return self.parentItem
def row(self):
if self.parentItem:
return self.parentItem.childItems.index(self)
return 0
def __repr__(self):
return 'TreeItem(%s)' % self.itemData
class TreeModel(QtCore.QAbstractItemModel):
def __init__(self, data, parent=None):
super(TreeModel, self).__init__(parent)
self.rootItem = TreeItem(("Region", "Abbreviation"))
self.setupModelData(data.split('\n'), self.rootItem)
def columnCount(self, parent):
if parent.isValid():
return parent.internalPointer().columnCount()
else:
return self.rootItem.columnCount()
def data(self, index, role):
if not index.isValid():
return None
if role == QtCore.Qt.EditRole:
return self.rootItem.data(0)
if role != QtCore.Qt.DisplayRole:
return None
item = index.internalPointer()
return item.data(index.column())
def flags(self, index):
if not index.isValid():
return QtCore.Qt.NoItemFlags
return QtCore.Qt.ItemIsEnabled | QtCore.Qt.ItemIsSelectable
def headerData(self, section, orientation, role):
if orientation == QtCore.Qt.Horizontal and role == QtCore.Qt.DisplayRole:
return self.rootItem.data(section)
return None
def index(self, row, column, parent):
if not self.hasIndex(row, column, parent):
return QtCore.QModelIndex()
if not parent.isValid():
parentItem = self.rootItem
else:
parentItem = parent.internalPointer()
childItem = parentItem.child(row)
if childItem:
return self.createIndex(row, column, childItem)
else:
return QtCore.QModelIndex()
def parent(self, index):
if not index.isValid():
return QtCore.QModelIndex()
childItem = index.internalPointer()
parentItem = childItem.parent()
if parentItem == self.rootItem:
return QtCore.QModelIndex()
return self.createIndex(parentItem.row(), 0, parentItem)
def rowCount(self, parent):
if parent.column() > 0:
return 0
if not parent.isValid():
parentItem = self.rootItem
else:
parentItem = parent.internalPointer()
return parentItem.childCount()
def setupModelData(self, lines, parent):
parents = [parent]
indentations = [0]
number = 0
while number < len(lines):
position = 0
while position < len(lines[number]):
if lines[number][position] != ' ':
break
position += 1
lineData = lines[number][position:].strip()
if lineData:
# Read the column data from the rest of the line.
columnData = [s for s in lineData.split('\t') if s]
if position > indentations[-1]:
# The last child of the current parent is now the new
# parent unless the current parent has no children.
if parents[-1].childCount() > 0:
parents.append(parents[-1].child(parents[-1].childCount() - 1))
indentations.append(position)
else:
while position < indentations[-1] and len(parents) > 0:
parents.pop()
indentations.pop()
# Append a new item to the current parent's list of children.
newtreeitem = TreeItem(columnData, parents[-1])
parents[-1].appendChild(newtreeitem)
number += 1
class MyCompleter(QtGui.QCompleter):
def splitPath(self, path):
return path.split('/')
def pathFromIndex(self, index):
result = []
while index.isValid():
result = [self.model().data(index, QtCore.Qt.DisplayRole)] + result
index = index.parent()
r = '/'.join(result)
return r
if __name__ == '__main__':
import sys
app = QtGui.QApplication(sys.argv)
model = TreeModel('''
Canada CAN
British Columbia BC
Vancouver
Manitoba MB
Winnipeg
Ontario ON
Toronto
Quebec QC
Montreal
United States USA
Alaska AK
Anchorage
Juneau
Arizona AZ
Phoenix
Tucson
Arkansas AR
Little Rock
Missouri MO
Kansas City
St. Louis
Mexico MEX
Chihuahua CI
Ciudad Juárez
Coahuila CU
Saltillo
Durango DG
Durango
Sonora SO
Hermosillo
Nogales
''')
mainwindow = QtGui.QMainWindow()
mainwindow.setWindowTitle("Tree Model with Completion")
mainwindow.show()
view = QtGui.QTreeView()
view.setModel(model)
mainwindow.setCentralWidget(view)
edit = QtGui.QLineEdit()
completer = MyCompleter(edit)
completer.setModel(model)
completer.setCompletionColumn(0)
completer.setCompletionRole(QtCore.Qt.DisplayRole)
completer.setCaseSensitivity(QtCore.Qt.CaseInsensitive)
edit.setWindowTitle("PySide QLineEdit Auto Complete")
edit.setCompleter(completer)
docker = QtGui.QDockWidget()
docker.setWidget(edit)
mainwindow.addDockWidget(QtCore.Qt.DockWidgetArea.BottomDockWidgetArea, docker)
sys.exit(app.exec_())
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment