小知识------QT Designer中TreeWidget、TableWidget等控件添加复选框+常用数据校验功能校验,以PySide6中实现数据校验工具为案例进行讲解

小知识------QT Designer中TreeWidget、TableWidget等控件添加复选框+常用数据校验功能校验,以PySide6中实现数据校验工具为案例进行讲解

概述

在进行数据分析或者数据挖掘、机器学习、深度学习之时,数据的正确性十分重要,因此在数据分析之前,进行数据正确性校验是十分必要的,基于此,本文实现了一款批量数据校验工具,可以完成:身份证校验、座机电话校验、手机号码校验、日期时间校验、邮箱校验、IP地址校验、邮编格式校验、MAC地址校验、非空校验、数字校验、域名校验、URL地址校验、统一社会信用代码校验、全国组织机构代码校验、特殊字符校验等多类校验功能。

本文代码实现基于Python + PySide6实现,主要应用到的控件是TreeWidget、TableWidget、CheckBox几类控件,通过本文的案例,读者除了可以了解到python是如何进行各类数据校验外,还能了解到TreeWidget+CheckBox如何实现多文件列表选择,TableWidget+CheckBox控件如何实现校验功能选择。

工具设计与实现

工具最终效果呈现

在这里插入图片描述

功能设计

工具主要包括以下功能点:

  • 点击打开,可以将选择文件夹中的所有xlsx文件全部列出,形成文件列表,并且可以点击复选框同时选中多个文件
  • 点击文件列表会将选中的excel文件显示到表格控件之中,同时会动态生成数据校验配置表
  • 在数据校验配置表中,勾选指定功能,便可以对选中的excel文件进行对应数据正确性校验
  • 保存校验设置,可以将多个文件的校验配置进行存储
  • 加载校验设置,可以将之前保存的校验设置加载

界面设计

界面设计见下图:
在这里插入图片描述
界面代码如下:

# -*- coding: utf-8 -*-

################################################################################
## Form generated from reading UI file 'dv_mainwindow.ui'
##
## Created by: Qt User Interface Compiler version 6.6.0
##
## WARNING! All changes made in this file will be lost when recompiling UI file!
################################################################################

from PySide6.QtCore import (QCoreApplication, QDate, QDateTime, QLocale,
    QMetaObject, QObject, QPoint, QRect,
    QSize, QTime, QUrl, Qt)
from PySide6.QtGui import (QAction, QBrush, QColor, QConicalGradient,
    QCursor, QFont, QFontDatabase, QGradient,
    QIcon, QImage, QKeySequence, QLinearGradient,
    QPainter, QPalette, QPixmap, QRadialGradient,
    QTransform)
from PySide6.QtWidgets import (QAbstractItemView, QApplication, QFrame, QGridLayout,
    QGroupBox, QHBoxLayout, QHeaderView, QLabel,
    QLineEdit, QMainWindow, QMenu, QMenuBar,
    QPushButton, QSizePolicy, QStatusBar, QTableView,
    QTableWidget, QTableWidgetItem, QTreeWidget, QTreeWidgetItem,
    QWidget)

class Ui_dv_MainWindow(object):
    def setupUi(self, dv_MainWindow):
        if not dv_MainWindow.objectName():
            dv_MainWindow.setObjectName(u"dv_MainWindow")
        dv_MainWindow.resize(1280, 760)
        sizePolicy = QSizePolicy(QSizePolicy.Preferred, QSizePolicy.Preferred)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(dv_MainWindow.sizePolicy().hasHeightForWidth())
        dv_MainWindow.setSizePolicy(sizePolicy)
        self.actionopendir = QAction(dv_MainWindow)
        self.actionopendir.setObjectName(u"actionopendir")
        self.action_config = QAction(dv_MainWindow)
        self.action_config.setObjectName(u"action_config")
        self.centralwidget = QWidget(dv_MainWindow)
        self.centralwidget.setObjectName(u"centralwidget")
        self.groupBox = QGroupBox(self.centralwidget)
        self.groupBox.setObjectName(u"groupBox")
        self.groupBox.setGeometry(QRect(9, 9, 431, 701))
        self.gridLayout_2 = QGridLayout(self.groupBox)
        self.gridLayout_2.setObjectName(u"gridLayout_2")
        self.searchEdit = QLineEdit(self.groupBox)
        self.searchEdit.setObjectName(u"searchEdit")

        self.gridLayout_2.addWidget(self.searchEdit, 0, 0, 1, 1)

        self.pushButton = QPushButton(self.groupBox)
        self.pushButton.setObjectName(u"pushButton")

        self.gridLayout_2.addWidget(self.pushButton, 0, 1, 1, 1)

        self.treeWidget = QTreeWidget(self.groupBox)
        self.treeWidget.setObjectName(u"treeWidget")
        self.treeWidget.setFrameShape(QFrame.WinPanel)
        self.treeWidget.setLineWidth(0)
        self.treeWidget.setSelectionMode(QAbstractItemView.SingleSelection)
        self.treeWidget.setSelectionBehavior(QAbstractItemView.SelectItems)

        self.gridLayout_2.addWidget(self.treeWidget, 1, 0, 1, 2)

        self.groupBox_2 = QGroupBox(self.groupBox)
        self.groupBox_2.setObjectName(u"groupBox_2")
        self.gridLayout = QGridLayout(self.groupBox_2)
        self.gridLayout.setObjectName(u"gridLayout")
        self.lineEdit_StartCol = QLineEdit(self.groupBox_2)
        self.lineEdit_StartCol.setObjectName(u"lineEdit_StartCol")

        self.gridLayout.addWidget(self.lineEdit_StartCol, 1, 1, 1, 1)

        self.label = QLabel(self.groupBox_2)
        self.label.setObjectName(u"label")

        self.gridLayout.addWidget(self.label, 0, 0, 1, 1)

        self.label_5 = QLabel(self.groupBox_2)
        self.label_5.setObjectName(u"label_5")

        self.gridLayout.addWidget(self.label_5, 1, 2, 1, 1)

        self.label_4 = QLabel(self.groupBox_2)
        self.label_4.setObjectName(u"label_4")

        self.gridLayout.addWidget(self.label_4, 0, 2, 1, 1)

        self.lineEdit_EndCol = QLineEdit(self.groupBox_2)
        self.lineEdit_EndCol.setObjectName(u"lineEdit_EndCol")

        self.gridLayout.addWidget(self.lineEdit_EndCol, 1, 3, 1, 1)

        self.pushButton_load_dv = QPushButton(self.groupBox_2)
        self.pushButton_load_dv.setObjectName(u"pushButton_load_dv")

        self.gridLayout.addWidget(self.pushButton_load_dv, 4, 2, 1, 2)

        self.pushButton_save_config = QPushButton(self.groupBox_2)
        self.pushButton_save_config.setObjectName(u"pushButton_save_config")

        self.gridLayout.addWidget(self.pushButton_save_config, 3, 0, 1, 4)

        self.lineEdit_StartRow = QLineEdit(self.groupBox_2)
        self.lineEdit_StartRow.setObjectName(u"lineEdit_StartRow")

        self.gridLayout.addWidget(self.lineEdit_StartRow, 0, 1, 1, 1)

        self.lineEdit_dv_save_dir = QLineEdit(self.groupBox_2)
        self.lineEdit_dv_save_dir.setObjectName(u"lineEdit_dv_save_dir")

        self.gridLayout.addWidget(self.lineEdit_dv_save_dir, 2, 0, 1, 4)

        self.label_2 = QLabel(self.groupBox_2)
        self.label_2.setObjectName(u"label_2")

        self.gridLayout.addWidget(self.label_2, 1, 0, 1, 1)

        self.lineEdit_EndRow = QLineEdit(self.groupBox_2)
        self.lineEdit_EndRow.setObjectName(u"lineEdit_EndRow")

        self.gridLayout.addWidget(self.lineEdit_EndRow, 0, 3, 1, 1)

        self.pushButton_save_dv = QPushButton(self.groupBox_2)
        self.pushButton_save_dv.setObjectName(u"pushButton_save_dv")

        self.gridLayout.addWidget(self.pushButton_save_dv, 4, 0, 1, 2)


        self.gridLayout_2.addWidget(self.groupBox_2, 2, 0, 1, 2)

        self.tableView_view = QTableView(self.centralwidget)
        self.tableView_view.setObjectName(u"tableView_view")
        self.tableView_view.setGeometry(QRect(448, 9, 821, 331))
        sizePolicy.setHeightForWidth(self.tableView_view.sizePolicy().hasHeightForWidth())
        self.tableView_view.setSizePolicy(sizePolicy)
        self.tableView_view.setFrameShape(QFrame.Box)
        self.tableView_view.setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded)
        self.tableView_view.setHorizontalScrollBarPolicy(Qt.ScrollBarAsNeeded)
        self.tableView_view.setSelectionMode(QAbstractItemView.SingleSelection)
        self.groupBox_3 = QGroupBox(self.centralwidget)
        self.groupBox_3.setObjectName(u"groupBox_3")
        self.groupBox_3.setGeometry(QRect(450, 670, 821, 41))
        self.horizontalLayout = QHBoxLayout(self.groupBox_3)
        self.horizontalLayout.setObjectName(u"horizontalLayout")
        self.pushButton_start = QPushButton(self.groupBox_3)
        self.pushButton_start.setObjectName(u"pushButton_start")

        self.horizontalLayout.addWidget(self.pushButton_start)

        self.groupBox_4 = QGroupBox(self.centralwidget)
        self.groupBox_4.setObjectName(u"groupBox_4")
        self.groupBox_4.setGeometry(QRect(450, 350, 821, 311))
        self.tableWidget_dv_config = QTableWidget(self.groupBox_4)
        self.tableWidget_dv_config.setObjectName(u"tableWidget_dv_config")
        self.tableWidget_dv_config.setGeometry(QRect(10, 20, 797, 281))
        self.tableWidget_dv_config.setFrameShape(QFrame.Box)
        dv_MainWindow.setCentralWidget(self.centralwidget)
        self.menubar = QMenuBar(dv_MainWindow)
        self.menubar.setObjectName(u"menubar")
        self.menubar.setGeometry(QRect(0, 0, 1280, 22))
        self.menu = QMenu(self.menubar)
        self.menu.setObjectName(u"menu")
        self.menu_2 = QMenu(self.menubar)
        self.menu_2.setObjectName(u"menu_2")
        dv_MainWindow.setMenuBar(self.menubar)
        self.statusbar = QStatusBar(dv_MainWindow)
        self.statusbar.setObjectName(u"statusbar")
        dv_MainWindow.setStatusBar(self.statusbar)

        self.menubar.addAction(self.menu.menuAction())
        self.menubar.addAction(self.menu_2.menuAction())
        self.menu.addAction(self.actionopendir)
        self.menu_2.addAction(self.action_config)

        self.retranslateUi(dv_MainWindow)

        QMetaObject.connectSlotsByName(dv_MainWindow)
    # setupUi

    def retranslateUi(self, dv_MainWindow):
        dv_MainWindow.setWindowTitle(QCoreApplication.translate("dv_MainWindow", u"\u8868\u683c\u6570\u636e\u6821\u9a8c\u5de5\u5177", None))
        self.actionopendir.setText(QCoreApplication.translate("dv_MainWindow", u"\u9009\u62e9\u6587\u4ef6\u5939", None))
#if QT_CONFIG(tooltip)
        self.actionopendir.setToolTip(QCoreApplication.translate("dv_MainWindow", u"<html><head/><body><p>\u9009\u62e9\u5f85\u8fdb\u884c\u6570\u636e\u6821\u9a8c\u6587\u4ef6\u6240\u5728\u6587\u4ef6\u5939</p></body></html>", None))
#endif // QT_CONFIG(tooltip)
        self.action_config.setText(QCoreApplication.translate("dv_MainWindow", u"\u6821\u9a8c\u9879\u76ee\u914d\u7f6e", None))
        self.groupBox.setTitle("")
        self.pushButton.setText(QCoreApplication.translate("dv_MainWindow", u"\u6536\u7d22", None))
        ___qtreewidgetitem = self.treeWidget.headerItem()
        ___qtreewidgetitem.setText(0, QCoreApplication.translate("dv_MainWindow", u"\u8bf7\u9009\u62e9\u6587\u4ef6\u5939", None));
        self.groupBox_2.setTitle(QCoreApplication.translate("dv_MainWindow", u"\u57fa\u7840\u914d\u7f6e", None))
        self.lineEdit_StartCol.setText(QCoreApplication.translate("dv_MainWindow", u"0", None))
        self.label.setText(QCoreApplication.translate("dv_MainWindow", u"\u6570\u636e\u8d77\u59cb\u884c", None))
        self.label_5.setText(QCoreApplication.translate("dv_MainWindow", u"\u6570\u636e\u7ed3\u5c3e\u5217", None))
        self.label_4.setText(QCoreApplication.translate("dv_MainWindow", u"\u6570\u636e\u7ed3\u5c3e\u884c", None))
        self.lineEdit_EndCol.setText(QCoreApplication.translate("dv_MainWindow", u"0", None))
        self.pushButton_load_dv.setText(QCoreApplication.translate("dv_MainWindow", u"\u52a0\u8f7d\u6821\u9a8c\u8bbe\u7f6e", None))
        self.pushButton_save_config.setText(QCoreApplication.translate("dv_MainWindow", u"\u6821\u9a8c\u62a5\u544a\u5b58\u50a8\u5730\u5740\u9009\u62e9", None))
        self.lineEdit_StartRow.setText(QCoreApplication.translate("dv_MainWindow", u"0", None))
        self.lineEdit_dv_save_dir.setText(QCoreApplication.translate("dv_MainWindow", u"./config_output", None))
        self.label_2.setText(QCoreApplication.translate("dv_MainWindow", u"\u6570\u636e\u8d77\u59cb\u5217", None))
        self.lineEdit_EndRow.setText(QCoreApplication.translate("dv_MainWindow", u"0", None))
        self.pushButton_save_dv.setText(QCoreApplication.translate("dv_MainWindow", u"\u4fdd\u5b58\u6821\u9a8c\u8bbe\u7f6e", None))
        self.groupBox_3.setTitle("")
        self.pushButton_start.setText(QCoreApplication.translate("dv_MainWindow", u"\u5f00\u59cb\u6821\u9a8c", None))
        self.groupBox_4.setTitle(QCoreApplication.translate("dv_MainWindow", u"\u6570\u636e\u6821\u9a8c\u914d\u7f6e", None))
        self.menu.setTitle(QCoreApplication.translate("dv_MainWindow", u"\u6253\u5f00", None))
        self.menu_2.setTitle(QCoreApplication.translate("dv_MainWindow", u"\u8bbe\u7f6e", None))
    # retranslateUi

TreeWidget+CheckBox实现文件列表

TreeWidget+CheckBox实现文件列表+复选框如何实现?由于TreeWidget实际上是由多个TreeWidgetItem构成,所以新增复选框,应该考虑在TreeWidgetItem上进行设置,此处设置较为简单,因为TreeWidgetItem本身自带setCheckState设置,所以我们只需要对其进行设置后,便可以在TreeWidget上显示复选框了,这个功能,我们在打开按钮功能中实现。具体代码如下:

# 打开文件夹
    def open_dirs(self):
        self._open_dirs = QFileDialog.getExistingDirectory(None, '选取文件夹', '')
        self._open_dirs_list.append(self._open_dirs)
        # self._model = QFileSystemModel()

        # 清空treeWidget的数据
        self.treeWidget.clear()

        # QTreeWidgets列数和列名设置
        self.treeWidget.setColumnCount(1)
        self.treeWidget.setHeaderLabels(['文件名'])
        # root节点设置
        self._root = QTreeWidgetItem(self.treeWidget)
        self._root.setText(0, self._open_dirs)
        self._root.setCheckState(0, Qt.Unchecked)

        # 获取文件列表
        self._file_path_list = self.get_file_path(self._open_dirs)
        # 遍历文件名,添加到列表之中
        self._item_list = []
        for file in self._file_path_list:
            file_name = os.path.split(file)[1]
            child = QTreeWidgetItem(self._root)
            child.setText(0, file_name)
            child.setCheckState(0, Qt.Unchecked)
            self._item_list.append(child)

TableWidget+CheckBox实现动态数据校验配置表

TableWidget+CheckBox如何实现动态数据校验配置表呢?思路和上文结束类似,TableWidget其每个单元格也是由QTableWidgetItem构成的,而QTableWidgetItem控件是可以通过setCheckState设置选中状态的。该功能在构造数据校验配置表函数中实现,具体代码如下:

# 构造数据校验配置表
    def construct_config_dv(self):
        # 存储数据校验配置表
        self._df_dv = pd.DataFrame(columns=config.df_dv_col)

        columns = self.df.columns.tolist()
        first_row = self.df.iloc[0]
        
        # 遍历构造校验配置表
        for i, col in enumerate (columns):
            self._df_dv.loc[i, '列编号'] = columns[i]
            self._df_dv.loc[i, '第一列内容'] = first_row[i]

        self.tableWidget_dv_config.clear()

        # 获取表格行数与列数
        rows = self._df_dv.shape[0]
        cols = self._df_dv.shape[1]

        # 给tableWidget设置行表头
        self.tableWidget_dv_config.setColumnCount(cols)
        self.tableWidget_dv_config.setRowCount(rows)
        self.tableWidget_dv_config.setHorizontalHeaderLabels(config.df_dv_col)

        # 遍历数据校验配置表,加载到tableWidget中
        for i in range(rows):
            rows_values = self._df_dv.iloc[[i]]
            rows_values_array = np.array(rows_values)
            rows_values_list = rows_values_array.tolist()[0]
            for j in range(cols):
                items_list = str(rows_values_list[j])
                if (items_list == 'nan') and (j != 1):
                    newItem = QTableWidgetItem('是否校验')
                else:
                    newItem = QTableWidgetItem(items_list)

                if j not in [0, 1]:
                    newItem.setCheckState(Qt.Unchecked)
                newItem.setTextAlignment(Qt.AlignHCenter | Qt.AlignVCenter)
                self.tableWidget_dv_config.setItem(i, j, newItem)

工具完整代码下载

在本案例中,还实现了诸多其他功能,想要深入学习的同学可以下载源码进行研究,源码下载地址如下:

工具完整代码下载连接,点击下载

  • 17
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
Qt是一款跨平台的图形用户界面开发框架,提供了丰富的GUI控件功能以及跨平台的能力。PyQtPySide是在Qt基础上开发Python绑定库,使得我们可以使用Python语言来编写Qt应用程序。 PyQtPySide提供了和Qt类似的功能和API,使得我们可以方便地在Python使用Qt的各种特性,如窗口管理、布局管理器、事件处理和信号槽机制等。它们支持Qt的所有模块,因此可以利用Qt的强大功能开发出高度可定制的应用程序。 Custom Widgets是指自定义的用户界面部件,可以根据需求自己进行开发或者对现有的控件进行定制。在PyQtPySide,我们可以使用Qt功能来创建自定义的控件,通过继承已有的控件类来添加新的功能或者修改控件的外观和行为。这样可以满足特定需求并增加应用程序的交互性和美观性。 开发自定义的控件需要理解Qt的事件和绘图机制,掌握Qt提供的绘图功能控件定制的技术。我们可以使用Qt的绘图API来绘制自定义的界面元素,并且可以通过事件和信号槽来实现控件的交互性。在PyQtPySide,可以利用Python的特性和语法来更加方便地进行控件开发和定制。 总之,Qt、PyQtPySide的结合可以帮助我们快速开发跨平台的应用程序,并且可以通过自定义控件来满足特定需求。这些工具和技术的使用可以大大提高应用程序的开发效率和灵活性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

脑洞笔记

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值