pyqt5 带有复选框的QTreeWidget
案例截图:
代码:
import sys
from PyQt5.QtWidgets import QApplication, QMainWindow, QTreeWidget, QTreeWidgetItem, QVBoxLayout, QWidget, QPushButton
from PyQt5.QtCore import Qt
class TreeWidget(QTreeWidget):
def __init__(self, parent=None):
super().__init__(parent)
self.setHeaderLabels(["点选选项:"])
self.setAnimated(True)
self.setSelectionMode(QTreeWidget.MultiSelection)
self.itemChanged.connect(self.handle_item_changed)
def add_item_with_checkbox(self, parent, text, checked=False):
"""添加带有复选框的项"""
item = QTreeWidgetItem(parent, [text])
item.setCheckState(0, Qt.Checked if checked else Qt.Unchecked)
return item
def select_all_nodes(self):
"""递归地选择所有的节点"""
self.selectAll()
def deselect_all_nodes(self):
"""递归地取消选择所有的节点"""
self.clearSelection()
def toggle_select_all_nodes(self):
"""递归地切换所有节点的选择状态"""
if self.selectedItems():
self.deselect_all_nodes()
else:
self.select_all_nodes()
def get_selected_items(self):
"""获取所有被选中的项"""
selected_items = []
for item in self.selectedItems():
selected_items.append(item.text(0))
return selected_items
def recursive_traversal(self, item, callback):
"""递归地遍历所有的节点"""
callback(item)
for i in range(item.childCount()):
child = item.child(i)
self.recursive_traversal(child, callback)
def handle_item_changed(self, item, column):
"""处理复选框状态改变时的行为"""
if column == 0:
if item.parent() is None: # 如果是根节点
if item.checkState(column) == Qt.Checked:
self.select_children(item)
else:
self.deselect_children(item)
else: # 如果是子节点
if item.checkState(column) == Qt.Checked:
item.setSelected(True)
else:
item.setSelected(False)
def select_children(self, item):
"""递归地选择所有子节点"""
item.setSelected(True)
for i in range(item.childCount()):
child = item.child(i)
child.setCheckState(0, Qt.Checked)
self.select_children(child)
def deselect_children(self, item):
"""递归地取消选择所有子节点"""
item.setSelected(False)
for i in range(item.childCount()):
child = item.child(i)
child.setCheckState(0, Qt.Unchecked)
self.deselect_children(child)
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
self.setWindowTitle("Tree Widget Example with Checkboxes")
central_widget = QWidget()
layout = QVBoxLayout()
central_widget.setLayout(layout)
self.setCentralWidget(central_widget)
# 创建 QTreeWidget
self.tree_widget = TreeWidget()
layout.addWidget(self.tree_widget)
# 添加一些根节点
root1 = self.tree_widget.add_item_with_checkbox(self.tree_widget, "全选")
data = [
['c1','节点1',True],
['c2', '节点2',True],
['c3', '节点3',True],
['c4', '节点4',True],
['c5', '节点5',True],
]
# 为每个根节点添加子节点
for i in range(len(data)):
data[i][0] = self.tree_widget.add_item_with_checkbox(root1, data[i][1], data[i][2])
# 添加按钮
button_layout = QVBoxLayout()
layout.addLayout(button_layout)
select_all_button = QPushButton("Select All")
select_all_button.clicked.connect(self.tree_widget.select_all_nodes)
button_layout.addWidget(select_all_button)
deselect_all_button = QPushButton("Deselect All")
deselect_all_button.clicked.connect(self.tree_widget.deselect_all_nodes)
button_layout.addWidget(deselect_all_button)
toggle_select_button = QPushButton("Toggle Select All")
toggle_select_button.clicked.connect(self.tree_widget.toggle_select_all_nodes)
button_layout.addWidget(toggle_select_button)
show_selection_button = QPushButton("Show Selection")
show_selection_button.clicked.connect(self.show_selected_items)
button_layout.addWidget(show_selection_button)
def show_selected_items(self):
selected_items = self.tree_widget.get_selected_items()
print("Selected Items:", selected_items)
def main():
app = QApplication(sys.argv)
window = MainWindow()
window.show()
sys.exit(app.exec_())
if __name__ == '__main__':
main()