QTreeView/Widget - PySide2 - чекбоксы и фильтры
Всем добра!
Ситуация страшная, ибо кроме TKinter не имел дел с GUI вообще, а тут понадобился Qt...
Итак, имеется наследованный QTreeWidget, где я переопределил функцию двойного клика и настроил загрузку дерева из файла:
class MyTreeView(QTreeWidget):
""" custom treeview class -> reinitialized mouseDoubleClickEvent function """
def mouseDoubleClickEvent(self, event):
if event.button() == QtCore.Qt.MouseButton.RightButton:
index = self.selectedIndexes()[0]
text = index.data(Qt.DisplayRole)
print(text)
else:
super(MyTreeView, self).mouseDoubleClickEvent(event)
def get_contents(self):
self.clear()
with open("tree.list", "r") as fobj:
tree_row = fobj.readlines()
for content in tree_row:
parent = self.invisibleRootItem()
for word in content.split("\t"):
for i in range(parent.childCount()):
item = parent.child(i)
if item.text(0) == word.strip():
temp_var = item
break
else:
temp_var = QTreeWidgetItem([word.strip()])
parent.addChild(temp_var)
parent = temp_var
И вроде бы всё работает, но мне нужно прикрутить ко всему дереву чекбоксы (объекты без родителя должны быть без них вообще, а остальные имели tristade/checked/unchecked) и добавить некий QLineEdit, при вводе в который текста оно бы фильтровало содержимое моего treewidget: например, при вводе в searchbox "B" дерево выглядело бы так: A B.
Я так понял, что нужно использовать другие модели, но не могу найти никаких примеров на python. Какая модель мне нужна? Почему именно она? Если использовать модель, то нужно использовать QTreeView, а если так, то половина функций, что я использую - пропадёт. Как их реализовать по подобию из QTreeWidget (например, получение списка всех отмеченных галочкой обьектов)?
По поводу чекбоксов: я пытался добавить флаги на обьект temp_var, они становятся кликабельными, но никак не связаны между собой (при отметке дочернего обьекта, родитель не переходит в tristate и наоборот, при отметке родителя дети не отмечаются). Куда и что надо добавить?
По поводу фильтра: я добавил self.searchbox.textChanged.connect(self.search), но абсолютно не понимаю как прикрутить к этому дерево, чтобы оно скрывало ненужные мне связи. Это должны мыть методы модели? Я пытался перейти на модель QStandartItemModel, но описанные вопросы никуда не делись. Как должна быть реализована функция поиска-фильтра?
Спасибо за понимание!
Мой код:
from PySide2.QtCore import (QCoreApplication, QDate, QDateTime, QMetaObject,
QObject, QPoint, QRect, QSize, QTime, QUrl, Qt)
from PySide2.QtGui import (QBrush, QColor, QConicalGradient, QCursor, QFont,
QFontDatabase, QIcon, QKeySequence, QLinearGradient, QPalette, QPainter,
QPixmap, QRadialGradient)
from PySide2.QtWidgets import *
import sys
class MyTreeWidget(QTreeWidget):
def mouseDoubleClickEvent(self, event):
if event.button() == Qt.MouseButton.RightButton:
index = self.selectedIndexes()[0]
text = index.data(Qt.DisplayRole)
print(text)
else:
super(MyTreeWidget, self).mouseDoubleClickEvent(event)
def get_contents(self):
self.clear()
with open("tree.list", "r") as fobj:
tree_row = fobj.readlines()
for content in tree_row:
parent = self.invisibleRootItem()
for word in content.split("\t"):
for i in range(parent.childCount()):
item = parent.child(i)
if item.text(0) == word.strip():
temp_var = item
break
else:
temp_var = QTreeWidgetItem([word.strip()])
parent.addChild(temp_var)
parent = temp_var
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
if not MainWindow.objectName():
MainWindow.setObjectName(u"MainWindow")
MainWindow.resize(659, 600)
self.centralwidget = QWidget(MainWindow)
self.centralwidget.setObjectName(u"centralwidget")
self.verticalLayout = QVBoxLayout(self.centralwidget)
self.verticalLayout.setObjectName(u"verticalLayout")
self.treeWidget = MyTreeWidget(self.centralwidget)
__qtreewidgetitem = QTreeWidgetItem()
__qtreewidgetitem.setText(0, u"1");
self.treeWidget.setHeaderItem(__qtreewidgetitem)
self.treeWidget.setObjectName(u"treeWidget")
self.treeWidget.setAnimated(True)
self.treeWidget.setHeaderHidden(True)
self.verticalLayout.addWidget(self.treeWidget)
self.searchbox = QLineEdit(self.centralwidget)
self.searchbox.setObjectName(u"searchbox")
self.verticalLayout.addWidget(self.searchbox)
MainWindow.setCentralWidget(self.centralwidget)
QMetaObject.connectSlotsByName(MainWindow)
class MainApp(QMainWindow, Ui_MainWindow):
def __init__(self):
super().__init__()
self.setupUi(self)
self.treeWidget.get_contents()
self.searchbox.textChanged.connect(self.search)
self.show()
def search(self, text):
print("Text now:", text)
if __name__ == "__main__":
app = QApplication(sys.argv)
root = MainApp()
sys.exit(app.exec_())
tree.list
Root 1 Item 1_1 Item 1_1_1
Root 1 Item 1_1 Item 1_1_2
Root 1 Item 1_1 Item 1_1_3
Root 1 Item 1_1 Item 1_1_4
Root 1 Item 1_1 Item 1_1_4 Item 1_1_4_1
Root 1 Item 1_2
Root 1 Item 1_3 Item 1_3_1
Root 1 Item 1_4 Item 1_4_1 Item_1_4_1_1
Root 1 Item 1_4 Item 1_4_1 Item_1_4_1_2
Root 2 Item 2_1 Item 2_1_1
Root 2 Item 2_1 Item 2_1_2
Root 2 Item 2_1 Item 2_1_3
Root 2 Item 2_1 Item 2_1_4
Root 2 Item 2_2
Root 2 Item 2_3 Item 2_3_1
Root 2 Item 2_3 Item 2_3_2
Root 2 Item 2_3 Item 2_3_3
Root 3 Item 3_1 Item 3_1_1