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