PyQt Tree Widget,为动态移除添加复选框
PyQt Tree Widget, adding check boxes for dynamic removal
我正在尝试创建一个树形小部件,它基本上允许用户查看各种数据细分并可以选择删除某些项目。为了做到这一点,我想让复选框与每个顶级项目和每个 child 相关联,以便用户可以 select 哪些顶级项目(因此所有 children顶级项目)删除。或者具体删除哪个children。为了给你一个更好的主意,我创建了一个示例,其中 [x] 代表一个选中的复选框,[ ] 代表一个空复选框:
>Beverages Allowed in Stadium [ ]
Soda [ ]
Water [ ]
Tea [ ]
Spirits [X]
Ale [ ]
>Tickets [X]
Row A [X]
Row B [X]
Row C [X]
Lawn [X]
有什么关于如何实施的建议吗?我不知道这是否会影响难度,但我已经为复选框分配了一个单独的列。
QTreeWidgetItem
实际上有一个内置的复选框,您可以很容易地使用它。
例如:
item = QTreeWidgetItem(self.treeWidget)
item.setCheckState(0, QtCore.Qt.Unchecked)
除了 parent 元素上的 you provided, you can simplify your logic by using the ItemIsTristate
标志。
from PyQt4.QtCore import *
from PyQt4.QtGui import *
import sys
def main():
app = QApplication (sys.argv)
tree = QTreeWidget ()
headerItem = QTreeWidgetItem()
item = QTreeWidgetItem()
for i in xrange(3):
parent = QTreeWidgetItem(tree)
parent.setText(0, "Parent {}".format(i))
parent.setFlags(parent.flags() | Qt.ItemIsTristate | Qt.ItemIsUserCheckable)
for x in xrange(5):
child = QTreeWidgetItem(parent)
child.setFlags(child.flags() | Qt.ItemIsUserCheckable)
child.setText(0, "Child {}".format(x))
child.setCheckState(0, Qt.Unchecked)
tree.show()
sys.exit(app.exec_())
if __name__ == '__main__':
main()
最重要的三行代码是:
parent.setFlags(parent.flags() | Qt.ItemIsTristate | Qt.ItemIsUserCheckable)
此设置将 parent 元素设置为三态复选框。
child.setFlags(child.flags() | Qt.ItemIsUserCheckable)
child.setCheckState(0, Qt.Unchecked)
这些将 child 设置为可选,并将默认设置为未选中。如果 child 的复选框未指定状态,则复选框元素不会出现。
上面的代码构建了一棵非常简单的树。
但是,如果我选中 parent 元素上的复选框,所有 children 都会自动选中:
如果,我想取消选中单个child,则parent进入部分选中(Tri-State):
如果所有children都取消选择,则parent自动取消选择。如果取消选择parent,则所有children也会自动取消选择。
这不是您问题的答案,而是您拥有复选框后如何使用它们的答案。我使用了上面标记为正确的答案中的示例。它起作用了,但是当我试图找到如何知道哪些复选框被标记时,我遇到了很多问题。经过大量搜索,我找到了一个适合我的解决方案,因为我看到没有很多文档,所以我想为将来留下记录。顺便提一下,我使用了几种解决方案作为 invisibleRootItem 来找到父项的子项,但这没有用。
我最终使用带有标志 QtGui.QTreeWidgetItemIterator.Checked 的 class QTreeWidgetItemIterator 来检索标记的复选框的文本,这样我就可以继续工作了。
def vrfs_selected(self):
iterator = QtGui.QTreeWidgetItemIterator(self.tree, QtGui.QTreeWidgetItemIterator.Checked)
while iterator.value():
item = iterator.value()
print (item.text(0))
iterator += 1
link 到文档 http://ftp.ics.uci.edu/pub/centos0/ics-custom-build/BUILD/PyQt-x11-gpl-4.7.2/doc/html/qtreewidgetitemiterator.html and an example https://riverbankcomputing.com/pipermail/pyqt/2014-May/034315.html
我将@andy 的精彩示例移植到了 PyQt5:
from PyQt5 import QtWidgets
from PyQt5 import QtCore
from PyQt5 import QtGui
from PyQt5.Qt import Qt
import sys
def main():
app = QtWidgets.QApplication(sys.argv)
tree = QtWidgets.QTreeWidget()
headerItem = QtWidgets.QTreeWidgetItem()
item = QtWidgets.QTreeWidgetItem()
for i in range(3):
parent = QtWidgets.QTreeWidgetItem(tree)
parent.setText(0, "Parent {}".format(i))
parent.setFlags(parent.flags() | Qt.ItemIsTristate | Qt.ItemIsUserCheckable)
for x in range(5):
child = QtWidgets.QTreeWidgetItem(parent)
child.setFlags(child.flags() | Qt.ItemIsUserCheckable)
child.setText(0, "Child {}".format(x))
child.setCheckState(0, Qt.Unchecked)
tree.show()
sys.exit(app.exec_())
if __name__ == '__main__':
main()
我正在尝试创建一个树形小部件,它基本上允许用户查看各种数据细分并可以选择删除某些项目。为了做到这一点,我想让复选框与每个顶级项目和每个 child 相关联,以便用户可以 select 哪些顶级项目(因此所有 children顶级项目)删除。或者具体删除哪个children。为了给你一个更好的主意,我创建了一个示例,其中 [x] 代表一个选中的复选框,[ ] 代表一个空复选框:
>Beverages Allowed in Stadium [ ]
Soda [ ]
Water [ ]
Tea [ ]
Spirits [X]
Ale [ ]
>Tickets [X]
Row A [X]
Row B [X]
Row C [X]
Lawn [X]
有什么关于如何实施的建议吗?我不知道这是否会影响难度,但我已经为复选框分配了一个单独的列。
QTreeWidgetItem
实际上有一个内置的复选框,您可以很容易地使用它。
例如:
item = QTreeWidgetItem(self.treeWidget)
item.setCheckState(0, QtCore.Qt.Unchecked)
除了 parent 元素上的 ItemIsTristate
标志。
from PyQt4.QtCore import *
from PyQt4.QtGui import *
import sys
def main():
app = QApplication (sys.argv)
tree = QTreeWidget ()
headerItem = QTreeWidgetItem()
item = QTreeWidgetItem()
for i in xrange(3):
parent = QTreeWidgetItem(tree)
parent.setText(0, "Parent {}".format(i))
parent.setFlags(parent.flags() | Qt.ItemIsTristate | Qt.ItemIsUserCheckable)
for x in xrange(5):
child = QTreeWidgetItem(parent)
child.setFlags(child.flags() | Qt.ItemIsUserCheckable)
child.setText(0, "Child {}".format(x))
child.setCheckState(0, Qt.Unchecked)
tree.show()
sys.exit(app.exec_())
if __name__ == '__main__':
main()
最重要的三行代码是:
parent.setFlags(parent.flags() | Qt.ItemIsTristate | Qt.ItemIsUserCheckable)
此设置将 parent 元素设置为三态复选框。
child.setFlags(child.flags() | Qt.ItemIsUserCheckable)
child.setCheckState(0, Qt.Unchecked)
这些将 child 设置为可选,并将默认设置为未选中。如果 child 的复选框未指定状态,则复选框元素不会出现。
上面的代码构建了一棵非常简单的树。
但是,如果我选中 parent 元素上的复选框,所有 children 都会自动选中:
如果,我想取消选中单个child,则parent进入部分选中(Tri-State):
如果所有children都取消选择,则parent自动取消选择。如果取消选择parent,则所有children也会自动取消选择。
这不是您问题的答案,而是您拥有复选框后如何使用它们的答案。我使用了上面标记为正确的答案中的示例。它起作用了,但是当我试图找到如何知道哪些复选框被标记时,我遇到了很多问题。经过大量搜索,我找到了一个适合我的解决方案,因为我看到没有很多文档,所以我想为将来留下记录。顺便提一下,我使用了几种解决方案作为 invisibleRootItem 来找到父项的子项,但这没有用。
我最终使用带有标志 QtGui.QTreeWidgetItemIterator.Checked 的 class QTreeWidgetItemIterator 来检索标记的复选框的文本,这样我就可以继续工作了。
def vrfs_selected(self):
iterator = QtGui.QTreeWidgetItemIterator(self.tree, QtGui.QTreeWidgetItemIterator.Checked)
while iterator.value():
item = iterator.value()
print (item.text(0))
iterator += 1
link 到文档 http://ftp.ics.uci.edu/pub/centos0/ics-custom-build/BUILD/PyQt-x11-gpl-4.7.2/doc/html/qtreewidgetitemiterator.html and an example https://riverbankcomputing.com/pipermail/pyqt/2014-May/034315.html
我将@andy 的精彩示例移植到了 PyQt5:
from PyQt5 import QtWidgets
from PyQt5 import QtCore
from PyQt5 import QtGui
from PyQt5.Qt import Qt
import sys
def main():
app = QtWidgets.QApplication(sys.argv)
tree = QtWidgets.QTreeWidget()
headerItem = QtWidgets.QTreeWidgetItem()
item = QtWidgets.QTreeWidgetItem()
for i in range(3):
parent = QtWidgets.QTreeWidgetItem(tree)
parent.setText(0, "Parent {}".format(i))
parent.setFlags(parent.flags() | Qt.ItemIsTristate | Qt.ItemIsUserCheckable)
for x in range(5):
child = QtWidgets.QTreeWidgetItem(parent)
child.setFlags(child.flags() | Qt.ItemIsUserCheckable)
child.setText(0, "Child {}".format(x))
child.setCheckState(0, Qt.Unchecked)
tree.show()
sys.exit(app.exec_())
if __name__ == '__main__':
main()