IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 大数据 -> PyQt5:Qcombobox + QtreeView(二) -> 正文阅读

[大数据]PyQt5:Qcombobox + QtreeView(二)

Pyqt5:Qcombobox + QtreeView(一)icon-default.png?t=LA92https://blog.csdn.net/qq_24800941/article/details/121915554?spm=1001.2014.3001.5501????????在上一篇文章中,简单的说明了带复选框的Qcombobox+QtreeView的实现方式,接下来,我们需要利用sql查询数据库内容,把数据填充到QtreeView上,再实现点击父节点时,子节点复选框也会改变,具体效果如下图。

? ? ? ? (1)在这里,我使用的是Access数据库,数据结构是记录父节点的方式,如下图。ID是该节点的唯一身份证,这里用Access自增的方式,p_id即父节点的ID,数据类型是数字,part_name是该节点的具体内容信息。

? ? ? ? ?(2)sql查询语言,这里不详细展开,其中的get_conn是获取数据库连接的函数,请读者自行查找连接Access数据的写法。

        conn = get_conn()
        cur = conn.cursor()
        sql = "select * from XXX表"
        cur.execute(sql)
        data = cur.fetchall()
        # print(data)
        cur.close()
        conn.close()

? ? ? ? (3)设置查询的数据填充到QtreeView函数,如下。利用了deque的特性。默认树状结构的所有节点复选框是选中的。

    def importData(self, data, root=None):
        self.vars["listViewModel"].setRowCount(0)
        if root is None:
            root = QStandardItem()
            self.vars["listViewModel"].appendRow(root)
            root.setText("全选")
            root.setCheckable(True)
            root.setCheckState(Qt.Checked)
        seen = {}   # List of  QStandardItem
        values = deque(data)
        while values:
            value = values.popleft()
            if value[1] == 0:
                parent = root
            else:
                pid = value[1]
                if pid not in seen:
                    values.append(value)
                    continue
                parent = seen[pid]
            unique_id = value[0]
            child = QStandardItem()
            child.setText(value[2])
            child.setCheckable(True)
            child.setCheckState(Qt.Checked)
            parent.appendRow([
                child,
            ])
            seen[unique_id] = parent.child(parent.rowCount() - 1)

? ? ? ? (4)设置递归函数,让父节点勾选时,其所有子节点也能做出反应。如父节点为勾选中的状态,其所有子节点也应该为选中的状态,反之亦然。

    def QcomboTreebox_child_node(self, item):
        if item.hasChildren() == True:
            total_child_count = item.rowCount()
            for i in range(total_child_count):
                child_item = item.child(i)
                child_item.setCheckState(Qt.Checked if item.checkState() == Qt.Checked else Qt.Unchecked)
                self.QcomboTreebox_child_node(child_item)

? ? ? ? (5)当点击节点时,第(4)步才作出反应,点击节点的展开/折叠按钮不反应。

        if self.vars["expandOrCollape"]:
            pass
        else:
            current_standardItem.setCheckState(Qt.Unchecked if current_standardItem.checkState() == Qt.Checked else Qt.Checked)
            # 开始递归寻找子节点
            self.QcomboTreebox_child_node(current_standardItem)

完整测试代码:

from PyQt5.QtWidgets import QWidget, QComboBox, QLineEdit, QListView, QTreeView, QApplication
from PyQt5.QtGui import QStandardItemModel, QStandardItem, QMouseEvent
from PyQt5.Qt import Qt, QRect
from collections import deque
import sys


class QComboTreeBox(QComboBox):
    class MyTreeView(QTreeView):
        def __init__(self, parent: QWidget = None, vars=None):
            super().__init__(parent)
            self.vars = vars
            self.setExpandsOnDoubleClick(False)
            self.setHeaderHidden(True)

        def mousePressEvent(self, event):
            self.vars["lock"] = False
            currIndex = self.currentIndex()
            index = currIndex.sibling(currIndex.row(), 0).data()  # 获取同一行不同列的数据
            self.vars["currIndex"] = currIndex

            '''自己创建点击节点Node三角折叠/展开功能'''
            rect = self.visualRect(currIndex)
            expandOrCollape = QRect(rect.left() - 20, rect.top(), 20, rect.height())
            if expandOrCollape.contains(event.pos()):
                self.vars["expandOrCollape"] = True
                if self.isExpanded(currIndex):
                    self.setExpanded(currIndex, False)
                else:
                    self.setExpanded(currIndex, True)
            else:
                self.vars["expandOrCollape"] = False
            '''自己创建点击节点Node三角折叠/展开功能'''

            # super().mousePressEvent(event)   # super()会出现节点打不开的情况,所以才自己创建点击节点Node三角折叠/展开功能

        def mouseDoubleClickEvent(self, event):
            self.vars["lock"] = False
            super().mouseDoubleClickEvent(event)

    def __init__(self, parent=None):
        super().__init__(parent)
        self.vars = dict()
        self.vars["lock"] = True
        self.vars["lineEdit"] = QLineEdit(self)
        self.vars["lineEdit"].setReadOnly(True)
        self.vars["listView"] = self.MyTreeView(self, self.vars)
        self.vars["listViewModel"] = QStandardItemModel(self)
        self.setModel(self.vars["listViewModel"])
        self.setView(self.vars["listView"])
        self.setLineEdit(self.vars["lineEdit"])
        # self.MyTreeView(self, self.vars).setExpandsOnDoubleClick(False)
        self.view_settings()
        self.activated.connect(self.__show_selected)
        # self.add_item("(全选)")
        # self.add_item("其他")
        data = [(1, 0, 'A'), (2, 0, 'B'), (3, 0, 'C'), (4, 0, 'D'), (5, 0, 'E'), (6, 0, 'F'), (7, 0, 'G'), (8, 0, 'H'),
                (9, 1, 'J'), (10, 1, 'K'), (11, 1, 'L'), (
                    12, 1, 'Q'), (14, 2, 'E'), (15, 2, 'R'), (13, 2, 'W')]
        self.importData(data)

    # QtreeView展示视图的一些设置
    def view_settings(self):
        self.view().setMinimumWidth(150)
        self.view().setMinimumHeight(300)
        self.view().setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded)

    # 往QtreeView中添加数据
    def importData(self, data, root=None):
        self.vars["listViewModel"].setRowCount(0)
        if root is None:
            root = QStandardItem()
            self.vars["listViewModel"].appendRow(root)
            root.setText("全选")
            root.setCheckable(True)
            root.setCheckState(Qt.Checked)
        seen = {}  # List of  QStandardItem
        values = deque(data)
        while values:
            value = values.popleft()
            if value[1] == 0:
                parent = root
            else:
                pid = value[1]
                if pid not in seen:
                    values.append(value)
                    continue
                parent = seen[pid]
            unique_id = value[0]
            child = QStandardItem()
            child.setText(value[2])
            child.setCheckable(True)
            child.setCheckState(Qt.Checked)
            parent.appendRow([
                child,
            ])
            seen[unique_id] = parent.child(parent.rowCount() - 1)

    # # 根据文本添加子项
    # def add_item(self, text: "str"):
    #     self.topitem = QStandardItem()
    #     self.topitem.setText(text)
    #     self.topitem.setCheckable(True)
    #     self.topitem.setCheckState(Qt.Checked)
    #     self.vars["listViewModel"].appendRow(self.topitem)
    #
    # # 根据文本添加子项
    # def add_subitem(self, text: "str"):
    #     item = QStandardItem()
    #     item.setText(text)
    #     item.setCheckable(True)
    #     item.setCheckState(Qt.Checked)
    #     self.topitem.appendRow(item)

    def __show_selected(self, index):
        this = self.vars["currIndex"]
        model = self.vars["listViewModel"]
        current_standardItem = model.itemFromIndex(this)
        item = self.vars["listViewModel"].item(index)
        # print(item.hasChildren(),item.rowCount(),item.child(item.rowCount()-1).text())
        # print(this.data(), this.parent().data(), this.model().item(index), this.row())
        # print(this.model().itemFromIndex(this),model.itemFromIndex(this))
        # print(self.MyTreeView(self, self.vars).selectionModel())
        if self.vars["expandOrCollape"]:
            pass
            # print("Mouse_Clicked_On_ExpandOrCollape")
        else:
            current_standardItem.setCheckState(
                Qt.Unchecked if current_standardItem.checkState() == Qt.Checked else Qt.Checked)
            self.QcomboTreebox_child_node(current_standardItem)

        self.vars["lock"] = True

    # 递归寻找所有子节点,并改变其复选框状态
    def QcomboTreebox_child_node(self, item):
        if item.hasChildren() == True:
            total_child_count = item.rowCount()
            for i in range(total_child_count):
                child_item = item.child(i)
                child_item.setCheckState(Qt.Checked if item.checkState() == Qt.Checked else Qt.Unchecked)
                self.QcomboTreebox_child_node(child_item)

    # 递归寻找所有父节点,并展开
    def QcomboTreebox_parent_node(self, item):
        if item.parent() != None:
            pitem = item.parent()
            pitem.setExpanded(True)
            self.QcomboTreebox_parent_node(pitem)

    # def handleChanged(self, item, column):
    #     count = item.childCount()
    #     if item.checkState(column) == Qt.Checked:
    #         for index in range(count):
    #             item.child(index).setCheckState(0, Qt.Checked)
    #     if item.checkState(column) == Qt.Unchecked:
    #         for index in range(count):
    #             item.child(index).setCheckState(0, Qt.Unchecked)

    def hidePopup(self):
        if self.vars["lock"]:
            super().hidePopup()


def run():
    app = QApplication(sys.argv)
    win = QComboTreeBox()
    win.show()
    sys.exit(app.exec_())


if __name__ == '__main__':
    run()

  大数据 最新文章
实现Kafka至少消费一次
亚马逊云科技:还在苦于ETL?Zero ETL的时代
初探MapReduce
【SpringBoot框架篇】32.基于注解+redis实现
Elasticsearch:如何减少 Elasticsearch 集
Go redis操作
Redis面试题
专题五 Redis高并发场景
基于GBase8s和Calcite的多数据源查询
Redis——底层数据结构原理
上一篇文章      下一篇文章      查看所有文章
加:2021-12-16 17:44:46  更:2021-12-16 17:46:45 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 11:55:42-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码