我在PySide中为Maya(3D软件)构建了一个工具,该工具可以自动版本并将文件保存在目录中。将QTreeView/QAbstractItemModel与QTreeWidget比较
我花了几天的时间试图将我的初始QTreeWidget代码转换为模型/视图模式与QTreeView和QAbstractItemModel以获得工具提示和其他功能,但我发现它比预期更难。当我正在学习一种新的编码语言/技术时,我喜欢找到两个脚本来做同样的事情 - 一个使用新技术,一个使用旧技术。这样我可以比较和分解新代码的功能。
我的一大障碍是,我无法找到一个QTreeView示例,它执行我的QTreeWidget示例。此外,大多数示例都手动填充QTreeView,这对我也无能为力。如果有人可以修改QTreeView代码,那么它将会很棒,因此它可以完成我的QTreeWidget代码。对QTreeView的最佳实践的评论也会很棒!
目前我QTreeWidget代码...
1)获取源字符串列表,并列出它们在第一列
2)在第二个每串并把它得到的日期柱
QTreeView则代码:
from PySide import QtCore, QtGui
from shiboken import wrapInstance
import maya.OpenMayaUI as mui
import sys, os
def get_parent():
ptr = mui.MQtUtil.mainWindow()
return wrapInstance(long(ptr), QtGui.QWidget)
################################################################################
class MyTree(QtGui.QMainWindow):
def __init__(self, parent=get_parent()):
super(MyTree, self).__init__(parent)
data = MyData.init()
frame = QtGui.QFrame();
frame.setLayout(QtGui.QHBoxLayout());
treeViewModel = TreeViewModel(data)
treeView = Widget_TreeView(treeViewModel)
frame.layout().addWidget(treeView);
self.setCentralWidget(frame)
################################################################################
class MyData():
def __init__(self, txt, parent=None):
self.txt = txt
self.tooltip = None
self.parent = parent
self.child = []
self.icon = []
self.index = None
self.widget = None
#---------------------------------------------------------------------------
# test initialization
@staticmethod
def init():
root = MyData("root")
root.tooltip = "root tooltip"
for i in range(0, 2):
child1 = MyData("child %i" % (i), root)
child1.tooltip = "child1 tooltip"
root.child.append(child1)
for x in range(0, 2):
child2 = MyData("child %i %i" % (i, x), child1)
child2.tooltip = "child2 tooltip"
child1.child.append(child2)
return root
# my failed attempt at adding my own data.
'''
path = "C:\Program Files"
contents = os.listdir(path)
data_list = []
for item in contents:
_data = MyData(item)
_data.tooltip = "_data tooltip"
data_list.append(_data)
return data_list # [0] adding this adds the first item to the UI,
# but i need every item from the directory
'''
################################################################################
class TreeViewModel(QtCore.QAbstractItemModel):
#---------------------------------------------------------------------------
def __init__(self, tree):
super(TreeViewModel, self).__init__()
self.__tree = tree
self.__view = None
#---------------------------------------------------------------------------
def flags(self, index):
flag = QtCore.Qt.ItemIsEnabled
if index.isValid():
flag |= QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsUserCheckable
return flag
#---------------------------------------------------------------------------
def index(self, row, column, parent=QtCore.QModelIndex()):
node = QtCore.QModelIndex()
if parent.isValid():
nodeS = parent.internalPointer()
nodeX = nodeS.child[row]
node = self.__createIndex(row, column, nodeX)
else:
node = self.__createIndex(row, column, self.__tree)
return node
#---------------------------------------------------------------------------
def parent(self, index):
return QtCore.QModelIndex()
#---------------------------------------------------------------------------
def rowCount(self, index=QtCore.QModelIndex()):
count = 1
node = index.internalPointer()
if node is not None:
count = len(node.child)
return count
#---------------------------------------------------------------------------
def columnCount(self, index=QtCore.QModelIndex()):
return 2
#---------------------------------------------------------------------------
def data(self, index, role=QtCore.Qt.DisplayRole):
data = None
return data
#---------------------------------------------------------------------------
def setView(self, view):
self.__view = view
#---------------------------------------------------------------------------
def __createIndex(self, row, column, node):
if node.index == None:
index = self.createIndex(row, column, node)
node.index = index
if node.widget is None:
node.widget = Widget_Tooltip(node)
self.__view.setIndexWidget(index, node.widget)
return node.index
################################################################################
class Widget_TreeView(QtGui.QTreeView):
#---------------------------------------------------------------------------
def __init__(self, model, parent=None):
super(Widget_TreeView, self).__init__(parent)
self.setModel(model)
#self.setIndentation(0)
model.setView(self)
root = model.index(0,0)
################################################################################
class Widget_Tooltip(QtGui.QWidget):
#---------------------------------------------------------------------------
def __init__(self, node):
super(Widget_Tooltip, self).__init__()
# Vars
self.node = node
self.txt = None
# Commands
self.create_tooltip(self.node)
############################################
def create_tooltip(self, node):
layout = QtGui.QHBoxLayout()
self.txt = QtGui.QLabel(node.txt)
self.txt.setToolTip("Text tooltip %s %s" % (node.txt, node.tooltip))
layout.addWidget(self.txt, 1)
self.setLayout(layout)
################################################################################
if __name__ == '__main__':
try:
form_ui.close()
form_ui.deleteLater()
except:
pass
form_ui = MyTree()
form_ui.show()
try:
form_ui.show()
except:
form_ui.close()
form_ui.deleteLater()
QTreeWidget代码:
import sys, os, time
from PySide import QtCore, QtGui
from shiboken import wrapInstance
import maya.OpenMayaUI as mui
def get_parent():
ptr = mui.MQtUtil.mainWindow()
return wrapInstance(long(ptr), QtGui.QWidget)
class Main_Window(QtGui.QDialog):
def __init__(self, parent = get_parent()):
super(Main_Window, self).__init__(parent)
# Commands
self.create_gui()
self.create_layout()
self.get_contents(None)
def create_gui(self):
self.tw_file_list = File_List(self)
self.parent = self.tw_file_list.invisibleRootItem()
def create_layout(self):
self.layout = QtGui.QHBoxLayout(self)
self.layout.addWidget(self.tw_file_list)
self.setLayout(self.layout)
def get_contents(self, path):
self.tw_file_list.clear()
path = "C:\Program Files"
contents = os.listdir(path)
for item in contents:
print item
parent = self.tw_file_list.invisibleRootItem()
date = self.get_date(item, path)
self.add_item(item, date, parent)
def add_item(self, name, date, parent):
item = QtGui.QTreeWidgetItem(parent)
item.setText(0, name)
item.setText(1, date)
item.setFlags(QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsUserCheckable | QtCore.Qt.ItemIsEnabled)
return item
def get_date(self, item, path):
path = "C:\Program Files"
file = str(path + "/" + item)
date = time.localtime(os.path.getmtime(file))
clean_date = "{0}_{1}_{2} {3}:{4}".format(date[0], date[1], date[2], date[3], str(date[4]).zfill(2))
return clean_date
############################################
class File_List(QtGui.QTreeWidget):
''' Create the file filters '''
def __init__(self, parent=get_parent()):
super(File_List, self).__init__(parent)
# Setup UI
self.setColumnCount(2)
self.setHeaderLabels(["name","date"])
self.parent = self.invisibleRootItem()
############################################
if __name__ == "__main__":
# Workaround hack for a PySide bug within maya
try:
main_ui.close()
main_ui.deleteLater()
except:
pass
# Show stuff
main_ui = Main_Window()
main_ui.show()
try:
main_ui.show()
except:
main_ui.close()
main_ui.deleteLater()
太好了,谢谢你这么多,tmoreau!所以在这种情况下,使用QStandardItemModel而不是QAbstractItemModel有什么优势?另外,说QTreeWidget这样的便利类的行为类似QStandardItemModel,但QStandardItemModel要求视图才能看到数据,这是否过于简单化? –
来自'QTreeWidget'的文档:“不需要Model/View框架灵活性的开发人员可以很容易地使用这个类来创建简单的分层列表,一种更加灵活的方法是将QTreeView与标准项目模型相结合。允许将数据的存储从其表示中分离出来。“ – Mel