Last active
August 8, 2021 20:22
-
-
Save jason-s/9dcef741288b6509d362 to your computer and use it in GitHub Desktop.
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
#!/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