gpt4 book ai didi

香,一套逻辑轻松且智能解决PyQt中控件数值验证的问题

转载 作者:我是一只小鸟 更新时间:2023-04-15 22:31:41 38 4
gpt4 key购买 nike

在 PyQt 开发中,时常需要对控件的值进行校验,如需要校验 QCheckBox 是否被选中, QLabel 是否校验值是否为空等等。在复杂的业务场景下,这类控件如果数量很多,逐个校验就显得麻烦,需要一一获得控件名称,再调用对应的方法来判断是否被选中、是否为空等。而且开发过程中如果多控件做了增减,还需要增减校验的逻辑,那会要了老命.

此篇文章,推荐使用 __dict__ 属性 + 字典映射来快速校验控件值,并且无视后面控件的增减,无需调整代码.

__dict__ 是什么?

做 python 开发的,或多或少都接触过该属性,它是 类 独有的一个特性,用来保存 类 的一些属性,关于这个属性的相关文章,网上一抓一大把,此处不作赘述,需要说明的是, 类实例 也有自己的 __dict__ 属性,而且和 类 的 __dict 不同,``类实例 的 dict 只保存了通过 self.xxx`所声明的属性和方法.

校验逻辑演示

接下来的演示中,仅使用 QCheckBox (为了省事),同时要保持这些控件的名称要具备同样的特征,下面的截图中,所有的控件名称都以 checkbox 结尾.

1、使用 .ui 文件生成 .py 文件 。

2、简单写个入口程序 。

继承刚才生成的 .py 文件,在这里可以实现自己的方法,在自定义类中,先打印 __dict__ ,看看有哪些值.

                
                  {
  'centralwidget': <PyQt6.QtWidgets.QWidget object at 0x00000231DD4E9D30>, 
  'gridLayout': <PyQt6.QtWidgets.QGridLayout object at 0x00000231DD4E9DC0>, 
  'c_checkbox': <PyQt6.QtWidgets.QCheckBox object at 0x00000231DD4E9E50>, 
  'd_checkbox': <PyQt6.QtWidgets.QCheckBox object at 0x00000231DD4E9EE0>, 
  'a_checkbox': <PyQt6.QtWidgets.QCheckBox object at 0x00000231DD4E9F70>, 
  'b_checkbox': <PyQt6.QtWidgets.QCheckBox object at 0x00000231DD9A3040>, 
  'f_checkbox': <PyQt6.QtWidgets.QCheckBox object at 0x00000231DD9A30D0>, 
  'e_checkbox': <PyQt6.QtWidgets.QCheckBox object at 0x00000231DD9A3160>, 
  'menubar': <PyQt6.QtWidgets.QMenuBar object at 0x00000231DD9A31F0>, 
  'statusbar': <PyQt6.QtWidgets.QStatusBar object at 0x00000231DD9A3280>
}

                
              

可以看到,它是一个字典,它包含了界面上所有的控件的名称和实例对象,这里就体现出了控件名称命名时遵守统一特征的好处了,即能望文生义,也方便处理.

3、提取所有 QCheckBox 的控件名称,构建一个校验的通用逻辑 。

                
                  import sys
from PyQt6.QtWidgets import QMainWindow, QApplication, QCheckBox
from ui_main import Ui_MainWindow

class MainWindow(Ui_MainWindow, QMainWindow):
    def __init__(self):
        super().__init__()
        super().setupUi(self)
        self.show()
        self.checkboxs()

    
    def checkboxs(self):
        # print(self.__dict__)

        # 增加这个字典映射是为了可以自动处理更多类型的控件值校验
        widget_mapping = {
            'QCheckBox': QCheckBox.isChecked
        }
        
        # 获取所有QCheckBox的控件名称
        boxs = [
            item for item in self.__dict__ \
                if item.endswith('_checkbox')
        ]

        # 用来保存未被勾选的控件
        un_checked = []

        for item in boxs:
            widget_instance = self.__dict__.get(item)
            widget_method = widget_mapping.get(
                self.__dict__.get(item).__class__.__name__
            )
            # 如果该QCheckBox处于未选中,则被添加到列表中
            if not widget_method(widget_instance):
                un_checked.append(item)

        print(un_checked)


if __name__ == '__main__':
    app = QApplication(sys.argv)
    window = MainWindow()
    sys.exit(app.exec())

                
              

4、逻辑分析 。

(1) 在代码 。

                
                  boxs = [
            item for item in self.__dict__ \
                if item.endswith('_checkbox')
        ]

                
              

中,通过 __dict__ 提取了所有以 _checkbox 结尾的控件名称,注意,这只是字符串而已,并非控件本身.

(2)构建一个通用的控件名称和控件方法的字典映射 。

                
                  # 增加这个字典映射是为了可以自动处理更多类型的控件值校验
        widget_mapping = {
            'QCheckBox': QCheckBox.isChecked
        }

                
              

这么做的目的是为了让这个逻辑更具通用性,让这个逻辑兼容其他控件,简单来说,可以通过控件的名称(boxs列表)找到该控件对应的方法,因为每个控件获取值所用的方法不尽相同.

(3)遍历 boxs 列表,逐个去 widget_mapping 找对应的方法,假如这里要较多种控件的话,字典映射的优势就体现出来了。 widget_method 就是该控件获取值所要用的方法了, QCheckBox 控件,就用 isChecked 方法来获取控件是否被选中.

(4)调用所找到的方法 widget_method 。这里之所以要把控件实例 widget_instance 传入方法中,是因为控件方法 isChecked 是单独调用的,它默认要传入 self参数 即实例本身.

运行代码看看效果 。

可以看到6个选项均为选中,打印结果符合该事实.

在 qt desinger 中默认勾选两个,再试试效果 。

有4个未选中,打印结果符合事实.

总结

上面的仅为演示代码,只是演示处理此类问题的逻辑,刚构建逻辑时会显得很绕,但是构建起来后就很好用了,如果再渐增控件,只要遵守控件名称命名规范,那么所增加的控件校验也无需增加校验代码,减少控件也一样.

延申用法

如果一个界面中有很多控件需要填写数值或清空数值,如:

  • 提交表单后,控件数值初始化
  • 校验不通过,需要在控件中做信息提示(诸如placeholder)

一样可以使用这个逻辑进行处理,只要前期构建好,代码复用完全不是问题.

最后此篇关于香,一套逻辑轻松且智能解决PyQt中控件数值验证的问题的文章就讲到这里了,如果你想了解更多关于香,一套逻辑轻松且智能解决PyQt中控件数值验证的问题的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。

38 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com