簡單的樹結構,目前的殘留問題是無法自動調整QTreeView的寬度
1、建立檔案夾,任意英文名字,比如Main
建立py檔案,内容如下:
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'GUI.ui'
#
# Created: Mon Jan 08 19:54:27 2018
# by: PyQt4 UI code generator 4.11.1
#
# WARNING! All changes made in this file will be lost!
import os
import sys
import locale
from PyQt4.QtGui import *
from PyQt4.QtCore import *
from PyQt4 import QtCore, QtGui
from PyQt4 import QtCore, QtGui
# try:
# import simpletreemodel_rc3
# except ImportError:
# import simpletreemodel_rc2
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
class TreeModel(QtCore.QAbstractItemModel):
def __init__(self, data, parent=None):
# app = QApplication(sys.argv)
# mycode = locale.getpreferredencoding()
# code = QTextCodec.codecForName(mycode)
# QTextCodec.setCodecForLocale(code)
# QTextCodec.setCodecForTr(code)
# QTextCodec.setCodecForCStrings(code)
super(TreeModel, self).__init__(parent)
self.checkLisk = []
self.rootItem = TreeItem(["Name"])
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
item = index.internalPointer()
if role == QtCore.Qt.CheckStateRole: # 被選中項是checkbox
# if item.parent() == self.rootItem: # 如果是根的話,直接傳回
# return None
# if item.childCount() > 0: # 如果是有子項的話,直接傳回,這個可以根據需要調整。當需要成組選擇的時候,必須保留
# return None
if index.column() == 0:
for x in self.checkLisk: # 檢查該項是否在checkList中,如果在将其設為選中狀态
if x == index:
return QtCore.Qt.Checked
else:
return QtCore.Qt.Unchecked
if role != QtCore.Qt.DisplayRole:
return None
return item.data(index.column())
def setData(self, index, value, role=QtCore.Qt.EditRole):
if role == QtCore.Qt.CheckStateRole and index.column() == 0:
if value == QtCore.Qt.Unchecked: # 撤銷選中的情況
self.checkLisk.remove(index) # 将節點的index從checklist中移除
self.emit(QtCore.SIGNAL("dataChanged(QModelIndex,QModelIndex)"),
index, index)
else: # 選中的情況
self.checkLisk.append(index) # 将節點的index加到checklist中
self.emit(QtCore.SIGNAL("dataChanged(QModelIndex,QModelIndex)"),
index, index)
return True
def flags(self, index):
if not index.isValid():
return QtCore.Qt.NoItemFlags
result = QtCore.Qt.ItemIsEnabled | QtCore.Qt.ItemIsSelectable
if index.column() == 0: # 隻讓第一列顯示checkbox
result |= QtCore.Qt.ItemIsUserCheckable
return result
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:]
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.
parents[-1].appendChild(TreeItem(columnData, parents[-1]))
number += 1
2、建立GUI.py,代碼如下
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'GUI.ui'
#
# Created: Mon Jan 08 19:54:27 2018
# by: PyQt4 UI code generator 4.11.1
#
# WARNING! All changes made in this file will be lost!
import os
import sys
import locale
from PyQt4.QtGui import *
from PyQt4.QtCore import *
from PyQt4 import QtCore, QtGui
from treeCaseList import TreeModel
try:
_fromUtf8 = QtCore.QString.fromUtf8
except AttributeError:
def _fromUtf8(s):
return s
try:
_encoding = QtGui.QApplication.UnicodeUTF8
def _translate(context, text, disambig):
return QtGui.QApplication.translate(context, text, disambig, _encoding)
except AttributeError:
def _translate(context, text, disambig):
return QtGui.QApplication.translate(context, text, disambig)
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
super(TreeModel)
MainWindow.setObjectName(_fromUtf8("MainWindow"))
MainWindow.resize(800, 600)
self.centralwidget = QtGui.QWidget(MainWindow)
self.centralwidget.setObjectName(_fromUtf8("centralwidget"))
self.CaseList = QtGui.QTreeView(self.centralwidget)
self.initCaseList()
self.CaseList.setModel(self.model)
self.CaseList.setGeometry(QtCore.QRect(0, 10, 230, 471))
self.CaseList.setObjectName(_fromUtf8("CaseList"))
MainWindow.setCentralWidget(self.centralwidget)
self.menubar = QtGui.QMenuBar(MainWindow)
self.menubar.setGeometry(QtCore.QRect(0, 0, 800, 23))
self.menubar.setObjectName(_fromUtf8("menubar"))
MainWindow.setMenuBar(self.menubar)
self.statusbar = QtGui.QStatusBar(MainWindow)
self.statusbar.setObjectName(_fromUtf8("statusbar"))
MainWindow.setStatusBar(self.statusbar)
self.toolBar = QtGui.QToolBar(MainWindow)
self.toolBar.setObjectName(_fromUtf8("toolBar"))
MainWindow.addToolBar(QtCore.Qt.TopToolBarArea, self.toolBar)
self.toolBar.addSeparator()
self.retranslateUi(MainWindow)
QtCore.QObject.connect(self.CaseList, QtCore.SIGNAL(_fromUtf8("activated(QModelIndex)")), self.CaseList.update)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def retranslateUi(self, MainWindow):
MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow", None))
self.toolBar.setWindowTitle(_translate("MainWindow", "toolBar", None))
def initCaseList(self):
tcPath = "D:\demo" # 定義樹形父節點路徑
names = locals()
treeTopNum = 1 # 定義樹形父節點個數
treeValue = 1
CaseArray = []
line = ''
list = os.listdir(tcPath) # 列出檔案夾下所有的目錄與檔案
for i in range(0, len(list)):
path = os.path.join(tcPath, list[i])
if os.path.isdir(path):
if line[-2:] == ' \t':
line = line[:-2] # 去除父節點最後的那個tab符号
line = line + list[i] + '\n' + ' ' + '\t'
treeValue += 1
# 遞歸檔案夾,找到case名稱,放在子節點,initial和release不能放,因為這裡沒有處理二級檔案夾,同名的不做處理。
# 如果需要做,那就要區分到測試套檔案夾名稱
for listView in os.walk(path):
if 'testcase' in listView[0]:
for listCase in listView[2]:
if ('initial.tcl' not in listCase) and ('release.tcl' not in listCase):
line = line + listCase + '\n' + ' ' + '\t'
# print line
self.model = TreeModel(u'%s' % line)
self.CaseList.setModel(self.model)
3、建立Main.py,代碼如下:
#!/usr/bin/python
# -*- coding: utf-8 -*-
import os
import PyQt4
from PyQt4 import QtGui
import sys
from GUI import Ui_MainWindow
#GUItmp***.ui轉換的py檔案名,也就相當于子產品。
#Ui_MainWindow為GUItmp界面的類,打開該py檔案即可看到
class MyWindow(QtGui.QMainWindow):
def __init__(self):
super(MyWindow, self).__init__()
self.ui = Ui_MainWindow() #這裡需要注意self.ui已經将Ui_MainWindow類執行個體 #化,是以繼承了該類的所有屬性,後面更改設定屬性都用self.ui“冠名”
self.ui.setupUi(self)
# =======================我是注釋========================
# 這個類的下面就可以編寫(def)自己的函數,如按鈕的功能等
# def。。。
# =======================注釋完畢========================
def main():
app = QtGui.QApplication(sys.argv)
w = MyWindow()
w.show()
sys.exit(app.exec_())
if __name__ == "__main__":
main()
4、運作Main.py即可。