PySide:文件夹的 TreeView 小部件
PySide: TreeView widget for folders
我想使用 PySide for Autodesk Maya 创建一个 TreeView 小部件,它可以显示目录的内容,如下例所示:
我确实找到了一个使用 tkinter 的简单 python 脚本示例:
Tkinter: Treeview widget。但我想使用 Pyside,这样我就可以 运行 在 Autodesk Maya 中使用它
我确实创建了一个可以显示简单 TreeView 小部件的脚本:
这是我的代码:
try:
from PySide2.QtCore import *
from PySide2.QtGui import *
from PySide2.QtWidgets import *
from PySide2 import __version__
from shiboken2 import wrapInstance
import collections
import maya.OpenMayaUI as OpenMayaUI
except ImportError:
from PySide.QtCore import *
from PySide.QtGui import *
from PySide import __version__
from shiboken import wrapInstance
import collections
import maya.OpenMayaUI as OpenMayaUI
treepop = collections.defaultdict(list)
treepop[""]=['layer_1',
'layer_2',
'layer_3',
'layer_4',
'layer_5',
'layer_6',
'layer_12']
treepop["layer_2"] = ['layer_7',
'layer_9',
'layer_11']
treepop["layer_3"] = ['layer_7']
treepop["layer_8"] = ['layer_10']
treepop["layer_10"] = ['layer_13']
def mayaToQT(name):
# Maya -> QWidget
ptr = OpenMayaUI.MQtUtil.findControl(name)
if ptr is None: ptr = OpenMayaUI.MQtUtil.findLayout(name)
if ptr is None: ptr = OpenMayaUI.MQtUtil.findMenuItem(name)
if ptr is not None: return wrapInstance(long(ptr),
QWidget)
cmds.window()
layout = cmds.columnLayout(rowSpacing=10, columnWidth=250)
qwidget= mayaToQT(layout)
qlayout = qwidget.children()[0]
treeview = QTreeWidget()
treeview.setSelectionMode(QAbstractItemView.ExtendedSelection)
treeview.setColumnCount(1)
treeview.setAlternatingRowColors(True)
treeview.clear()
qlayout.addWidget(treeview)
items = []
for k in treepop[""]:
root_item = QTreeWidgetItem()
root_item.setText(0,k)
print(k)
if k in treepop:
for v in treepop[k]:
child_item = QTreeWidgetItem()
child_item.setText(0,v)
root_item.addChild(child_item)
items.append(root_item)
treeview.addTopLevelItems(items)
cmds.showWindow()
def getSelected():
items = treeview.selectedItems()
for i in items:
print(i.text(0))
谁能帮帮我!
编辑:
在大家的帮助下我确实解决了问题,谢谢大家:
try:
from PySide2.QtCore import *
from PySide2.QtGui import *
from PySide2.QtWidgets import *
from PySide2 import __version__
from shiboken2 import wrapInstance
import collections
import maya.OpenMayaUI as OpenMayaUI
import os
except ImportError:
from PySide.QtCore import *
from PySide.QtGui import *
from PySide import __version__
from shiboken import wrapInstance
import collections
import maya.OpenMayaUI as OpenMayaUI
import os
class MyTree(QTreeWidget):
def __init__(self, parent=None):
QTreeWidget.__init__(self, parent)
self.startDir = "C:/users/user/desktop/myFolder"
self.setHeaderLabels([self.startDir])
self.setColumnWidth(0,400)
self.setContentsMargins(0, 0, 0, 0)
self.header().setDefaultSectionSize(300)
self.header().setStretchLastSection(False)
self.header().setResizeMode(0, QHeaderView.ResizeToContents)
self.header().setResizeMode(0, QHeaderView.Stretch)
self.setSelectionMode(QAbstractItemView.ExtendedSelection)
self.setColumnCount(1)
self.setAlternatingRowColors(True)
self.fillTree()
self.show()
def fillTree(self):
def iterate(currentDir, currentItem):
for f in os.listdir(currentDir):
path = os.path.join(currentDir, f)
if os.path.isdir(path):
dirItem = QTreeWidgetItem(currentItem)
dirItem.setText(0, f)
iterate(path, dirItem)
iterate(self.startDir, self)
def mayaToQT(name):
# Maya -> QWidget
ptr = OpenMayaUI.MQtUtil.findControl(name)
if ptr is None: ptr = OpenMayaUI.MQtUtil.findLayout(name)
if ptr is None: ptr = OpenMayaUI.MQtUtil.findMenuItem(name)
if ptr is not None: return wrapInstance(long(ptr),QWidget)
cmds.window(w=600, h=300)
layout = cmds.columnLayout(rowSpacing=60, columnWidth=400, w=600, h=600)
qwidget= mayaToQT(layout)
qlayout = qwidget.children()[0]
treeview = MyTree()
qlayout.addWidget(treeview)
cmds.showWindow()
但是谁能帮忙设置 QTreeView 小部件的高度和宽度?
您正在混合使用 Maya 和 Qt 小部件,这有什么原因吗?如果父项是 none,QtWidgets 会自动创建一个 window。一个很好的做法是子类化一个小部件,它使您能够将所有必要的数据保存在一个地方,如下所示:
class MyTree(QtWidgets.QTreeWidget):
def __init__(self, parent=None):
super(MyTree, self).__init__(parent)
self.fillTree()
def fillTree(self):
self.clear()
for i in range(10):
item = QtWidgets.QTreeWidgetItem(self)
item.setText(0, str(i))
如果你在init方法中的self.fillTree()之后添加self.show()或者从maya中调用它,你就可以自动显示它:
mt = MyTree()
mt.show()
应该出现 window。这个 window 不会总是在 Maya window 之上。如果需要,请导入 mayaMixin 并从 mixin 继承:
import maya.app.general.mayaMixin as MayaMixin
class MyTree(MayaMixin.MayaQWidgetBaseMixin, QtWidgets.QTreeWidget):
.....
接下来您可以开始用正确的数据填充树并添加子项。可以通过使用当前项作为父项来简单地添加子项:
item = QtWidgets.QTreeWidgetItem(self)
item.setText(0, "parent")
subItem = QtWidgets.QTreeWidgetItem(item)
subItem.setText(0, "child")
您需要整理数据!在你最后的评论中,你告诉我你不知道你的数据是什么,当你拥有它时,你可以循环遍历它并使用 'while' 或 'for' 将 child 添加到树中
my_data_folders = {'parent1': {'Lips':['A', 'B', 'C']}}
下面这部分是你要添加的循环 children :
items = []
for k in treepop:
# this is "parent1"
root_item = QTreeWidgetItem()
root_item.setText(0,k)
if treepop[k]:
# if there is children to "parent1", add Lips children to parent1
for v in treepop[k]:
child_item = QTreeWidgetItem()
child_item.setText(0,v)
root_item.addChild(child_item)
if treepop[k][v]:
for sub in treepop[k][v]:
sub_item = QTreeWidgetItem()
sub_item.setText(0, sub)
child_item.addChild(sub_item)
items.append(root_item)
treeview.addTopLevelItems(items)
一切皆有可能,最复杂的事情是组织数据
请注意,如果您正在尝试制作资源管理器,则 Qt 中有 QDirModel 的东西:
https://doc.qt.io/qtforpython/PySide2/QtWidgets/QDirModel.html
model = QtWidgets.QDirModel()
model.setReadOnly(True);
model.setSorting(QtCore.QDir.DirsFirst|QtCore.QDir.IgnoreCase|QtCore.QDir.Name)
model.setFilter(QtCore.QDir.Dirs)
treeView.setModel(model)
QDirModel 很棒。万一你想要另一个解决方案,你可以试试这个:
class MyTree(QtWidgets.QTreeWidget):
def __init__(self, parent=None):
super(MyTree, self).__init__(parent=parent)
self.startDir = "C:/daten/backup"
self.fillTree()
self.show()
def fillTree(self):
def iterate(currentDir, currentItem):
for f in os.listdir(currentDir):
path = os.path.join(currentDir, f)
if os.path.isdir(path):
dirItem = QtWidgets.QTreeWidgetItem(currentItem)
dirItem.setText(0, f)
iterate(path, dirItem)
else:
fileItem = QtWidgets.QTreeWidgetItem(currentItem)
fileItem.setText(0, f)
iterate(self.startDir, self)
它只是遍历起始目录,直到不再找到任何目录。
我想使用 PySide for Autodesk Maya 创建一个 TreeView 小部件,它可以显示目录的内容,如下例所示:
我确实找到了一个使用 tkinter 的简单 python 脚本示例: Tkinter: Treeview widget。但我想使用 Pyside,这样我就可以 运行 在 Autodesk Maya 中使用它
我确实创建了一个可以显示简单 TreeView 小部件的脚本:
这是我的代码:
try:
from PySide2.QtCore import *
from PySide2.QtGui import *
from PySide2.QtWidgets import *
from PySide2 import __version__
from shiboken2 import wrapInstance
import collections
import maya.OpenMayaUI as OpenMayaUI
except ImportError:
from PySide.QtCore import *
from PySide.QtGui import *
from PySide import __version__
from shiboken import wrapInstance
import collections
import maya.OpenMayaUI as OpenMayaUI
treepop = collections.defaultdict(list)
treepop[""]=['layer_1',
'layer_2',
'layer_3',
'layer_4',
'layer_5',
'layer_6',
'layer_12']
treepop["layer_2"] = ['layer_7',
'layer_9',
'layer_11']
treepop["layer_3"] = ['layer_7']
treepop["layer_8"] = ['layer_10']
treepop["layer_10"] = ['layer_13']
def mayaToQT(name):
# Maya -> QWidget
ptr = OpenMayaUI.MQtUtil.findControl(name)
if ptr is None: ptr = OpenMayaUI.MQtUtil.findLayout(name)
if ptr is None: ptr = OpenMayaUI.MQtUtil.findMenuItem(name)
if ptr is not None: return wrapInstance(long(ptr),
QWidget)
cmds.window()
layout = cmds.columnLayout(rowSpacing=10, columnWidth=250)
qwidget= mayaToQT(layout)
qlayout = qwidget.children()[0]
treeview = QTreeWidget()
treeview.setSelectionMode(QAbstractItemView.ExtendedSelection)
treeview.setColumnCount(1)
treeview.setAlternatingRowColors(True)
treeview.clear()
qlayout.addWidget(treeview)
items = []
for k in treepop[""]:
root_item = QTreeWidgetItem()
root_item.setText(0,k)
print(k)
if k in treepop:
for v in treepop[k]:
child_item = QTreeWidgetItem()
child_item.setText(0,v)
root_item.addChild(child_item)
items.append(root_item)
treeview.addTopLevelItems(items)
cmds.showWindow()
def getSelected():
items = treeview.selectedItems()
for i in items:
print(i.text(0))
谁能帮帮我!
编辑: 在大家的帮助下我确实解决了问题,谢谢大家:
try:
from PySide2.QtCore import *
from PySide2.QtGui import *
from PySide2.QtWidgets import *
from PySide2 import __version__
from shiboken2 import wrapInstance
import collections
import maya.OpenMayaUI as OpenMayaUI
import os
except ImportError:
from PySide.QtCore import *
from PySide.QtGui import *
from PySide import __version__
from shiboken import wrapInstance
import collections
import maya.OpenMayaUI as OpenMayaUI
import os
class MyTree(QTreeWidget):
def __init__(self, parent=None):
QTreeWidget.__init__(self, parent)
self.startDir = "C:/users/user/desktop/myFolder"
self.setHeaderLabels([self.startDir])
self.setColumnWidth(0,400)
self.setContentsMargins(0, 0, 0, 0)
self.header().setDefaultSectionSize(300)
self.header().setStretchLastSection(False)
self.header().setResizeMode(0, QHeaderView.ResizeToContents)
self.header().setResizeMode(0, QHeaderView.Stretch)
self.setSelectionMode(QAbstractItemView.ExtendedSelection)
self.setColumnCount(1)
self.setAlternatingRowColors(True)
self.fillTree()
self.show()
def fillTree(self):
def iterate(currentDir, currentItem):
for f in os.listdir(currentDir):
path = os.path.join(currentDir, f)
if os.path.isdir(path):
dirItem = QTreeWidgetItem(currentItem)
dirItem.setText(0, f)
iterate(path, dirItem)
iterate(self.startDir, self)
def mayaToQT(name):
# Maya -> QWidget
ptr = OpenMayaUI.MQtUtil.findControl(name)
if ptr is None: ptr = OpenMayaUI.MQtUtil.findLayout(name)
if ptr is None: ptr = OpenMayaUI.MQtUtil.findMenuItem(name)
if ptr is not None: return wrapInstance(long(ptr),QWidget)
cmds.window(w=600, h=300)
layout = cmds.columnLayout(rowSpacing=60, columnWidth=400, w=600, h=600)
qwidget= mayaToQT(layout)
qlayout = qwidget.children()[0]
treeview = MyTree()
qlayout.addWidget(treeview)
cmds.showWindow()
但是谁能帮忙设置 QTreeView 小部件的高度和宽度?
您正在混合使用 Maya 和 Qt 小部件,这有什么原因吗?如果父项是 none,QtWidgets 会自动创建一个 window。一个很好的做法是子类化一个小部件,它使您能够将所有必要的数据保存在一个地方,如下所示:
class MyTree(QtWidgets.QTreeWidget):
def __init__(self, parent=None):
super(MyTree, self).__init__(parent)
self.fillTree()
def fillTree(self):
self.clear()
for i in range(10):
item = QtWidgets.QTreeWidgetItem(self)
item.setText(0, str(i))
如果你在init方法中的self.fillTree()之后添加self.show()或者从maya中调用它,你就可以自动显示它:
mt = MyTree()
mt.show()
应该出现 window。这个 window 不会总是在 Maya window 之上。如果需要,请导入 mayaMixin 并从 mixin 继承:
import maya.app.general.mayaMixin as MayaMixin
class MyTree(MayaMixin.MayaQWidgetBaseMixin, QtWidgets.QTreeWidget):
.....
接下来您可以开始用正确的数据填充树并添加子项。可以通过使用当前项作为父项来简单地添加子项:
item = QtWidgets.QTreeWidgetItem(self)
item.setText(0, "parent")
subItem = QtWidgets.QTreeWidgetItem(item)
subItem.setText(0, "child")
您需要整理数据!在你最后的评论中,你告诉我你不知道你的数据是什么,当你拥有它时,你可以循环遍历它并使用 'while' 或 'for' 将 child 添加到树中
my_data_folders = {'parent1': {'Lips':['A', 'B', 'C']}}
下面这部分是你要添加的循环 children :
items = []
for k in treepop:
# this is "parent1"
root_item = QTreeWidgetItem()
root_item.setText(0,k)
if treepop[k]:
# if there is children to "parent1", add Lips children to parent1
for v in treepop[k]:
child_item = QTreeWidgetItem()
child_item.setText(0,v)
root_item.addChild(child_item)
if treepop[k][v]:
for sub in treepop[k][v]:
sub_item = QTreeWidgetItem()
sub_item.setText(0, sub)
child_item.addChild(sub_item)
items.append(root_item)
treeview.addTopLevelItems(items)
一切皆有可能,最复杂的事情是组织数据
请注意,如果您正在尝试制作资源管理器,则 Qt 中有 QDirModel 的东西:
model = QtWidgets.QDirModel()
model.setReadOnly(True);
model.setSorting(QtCore.QDir.DirsFirst|QtCore.QDir.IgnoreCase|QtCore.QDir.Name)
model.setFilter(QtCore.QDir.Dirs)
treeView.setModel(model)
QDirModel 很棒。万一你想要另一个解决方案,你可以试试这个:
class MyTree(QtWidgets.QTreeWidget):
def __init__(self, parent=None):
super(MyTree, self).__init__(parent=parent)
self.startDir = "C:/daten/backup"
self.fillTree()
self.show()
def fillTree(self):
def iterate(currentDir, currentItem):
for f in os.listdir(currentDir):
path = os.path.join(currentDir, f)
if os.path.isdir(path):
dirItem = QtWidgets.QTreeWidgetItem(currentItem)
dirItem.setText(0, f)
iterate(path, dirItem)
else:
fileItem = QtWidgets.QTreeWidgetItem(currentItem)
fileItem.setText(0, f)
iterate(self.startDir, self)
它只是遍历起始目录,直到不再找到任何目录。