2015-07-01 47 views
1

我在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() 

回答

3

这是你QTreeWidget例如,简化:

import sys 
from PySide import QtCore, QtGui 
class File_List(QtGui.QTreeWidget): 
    def __init__(self, parent=None): 
     super(File_List, self).__init__(parent) 
     self.setColumnCount(2) 
     self.setHeaderLabels(["name","date"]) 
     self.get_contents() 

    def get_contents(self): 
     self.clear() 
     contents = ["path1","path2"] 
     for path in contents: 
      date = self.get_date(path) 
      self.add_item(path,date) 

    def add_item(self, name, date): 
     item = QtGui.QTreeWidgetItem(self) 
     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, path): 
     return "a date" 

if __name__ == "__main__": 
    app = QtGui.QApplication(sys.argv) 
    win= File_List() 
    win.show() 
    sys.exit(app.exec_()) 

这里还有一个QTreeViewQStandardItemModel同样的事情(+如何添加子):

import sys 
from PySide import QtCore, QtGui 

class MyModel(QtGui.QStandardItemModel): 
    def __init__(self, parent=None): 
     super(MyModel, self).__init__(parent) 
     self.get_contents() 

    def get_contents(self): 
     self.clear() 
     contents=["path1","path2"] 
     for path in contents: 
      date = self.get_date(path) 
      self.add_item(path,date) 

    def add_item(self,name,date): 
     item1 = QtGui.QStandardItem(name) 
     item2 = QtGui.QStandardItem(date) 
     self.appendRow([item1, item2]) 
     #to append child items 
     childItem=QtGui.QStandardItem("child") 
     item1.appendRow(childItem) 

    def get_date(self, path): 
     return "a date" 


if __name__ == "__main__": 
    app = QtGui.QApplication(sys.argv) 
    model=MyModel() 
    treeView=QtGui.QTreeView() 
    treeView.setModel(model) 
    model.setHorizontalHeaderLabels(["name","date"]) 
    treeView.show() 
    sys.exit(app.exec_()) 
+0

太好了,谢谢你这么多,tmoreau!所以在这种情况下,使用QStandardItemModel而不是QAbstractItemModel有什么优势?另外,说QTreeWidget这样的便利类的行为类似QStandardItemModel,但QStandardItemModel要求视图才能看到数据,这是否过于简单化? –

+0

来自'QTreeWidget'的文档:“不需要Model/View框架灵活性的开发人员可以很容易地使用这个类来创建简单的分层列表,一种更加灵活的方法是将QTreeView与标准项目模型相结合。允许将数据的存储从其表示中分离出来。“ – Mel