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中控件数值验证的问题的更多相关文章

  1. 解决LinearLayout中控件不能居右对齐

    转载自:http://lgb168.blog.163.com/blog/static/49674438201172492935235/ 2011-08-24 21:35:25|  分类: Androi ...

  2. c#中解决winform中控件不能输入汉字的办法

    设置控件的ImeMode属性 如:    textBox.ImeMode = System.Windows.Forms.ImeMode.On; 其中枚举有如下值:

  3. [转]解决LinearLayout中控件不能居右对齐

    在LinearLayout布局时使用右对齐(android:layout_gravity="right")控件对齐方式不生效,需要设置 android:layout_weight= ...

  4. Atitit.dwr3 不能显示错误具体信息的解决方式,控件显示错误具体信息的解决方式 java .net php

    Atitit.dwr3 不能显示错误具体信息的解决方式,控件显示错误具体信息的解决方式 java .net php 1. Keyword/subtitle 1 2. 使用dwr3的异常convert处 ...

  5. form表单中控件较多,加载完成后切换页面都很慢的解决方法

    form表单中控件较多,加载完成后点击都很慢,为什么?我一页面中form表单里面上百个控件(如input.select.radio.checkbox等),还有一些js脚本,加载速度还可以,都能全部显示 ...

  6. 使用 Microsoft.UI.Xaml 解决 UWP 控件和对老版本 Windows 10 的兼容性问题

    原文 使用 Microsoft.UI.Xaml 解决 UWP 控件和对老版本 Windows 10 的兼容性问题 虽然微软宣称 Windows 10 将是最后一个 Windows 版本,但由于年代跨越 ...

  7. WSASocket()创建套接字不成功解决方法

    这几天我在写一个模仿windows自带的ping程序,可是套接字总是创建不成功,在网上找了一些资料最后总算把问题解决了,现在总结一下. 解决方法:以管理员运行VS就行了我的是vs2013,vs2010 ...

  8. JavaScript中的不同逻辑算法结合操作解决实际多重问题以及常用函数类型

    数组去重+快速排序 //老数组var arr1 = [1,2,2,3,8,6,6,4,5,5];//定义新数组var arr2 = [ ];内部可运用布尔型进行判断数组的唯一性 for(i=0;i&l ...

  9. tcp套接字粘包解决办法

    粘包只会出现在tcp,udp传输不会产生粘包现象.解决粘包的原理就是服务器预先向客户端发送客户端即将获取文件的大小. 第一版解决方案: 服务器: # Author : Kelvin # Date : ...

  10. django在启动时抛出Error: [WinError 10013] 以一种访问权限不允许的方式做了一个访问套接字的尝试 解决办法

    1.适用场景 在启动某个服务的时候,比如python中django启动的时候8000端口被占用,导致无法启动服务. 2.解决办法 通过命令行找出端口对应的PID进程 C:\Users\micha> ...

随机推荐

  1. NOIP2011普及组

    T2  统计单词数 也是一道经典题 字符串匹配 #include<iostream> #include<cstdio> #include<map> #include ...

  2. python开头

    python识别的正则模式 coding[:=]\s*([-\w.]+)#coding:utf8   ???不要用 #coding=utf-8#coding:utf-8# -*- coding: ut ...

  3. flask-script的简单使用

    1.Flask-Script介绍Flask-Script的作用是可以通过命令行的形式来操作Flask.Flask Script扩展提供向Flask插入外部脚本的功能,包括运行一个开发用的服务器,一个定 ...

  4. 用猿大师办公助手已经在Chrome网页中打开了Office Word,再用桌面Office打开其他Word打不开怎么办?

    我们发现用猿大师办公助手在Chrome网页中已经打开了Word文档,但是再用本地的Word打开其他文档,却直接显示在网页中了,本地打不开Word怎么办? 猿大师办公助手默认新打开文件是在内嵌网页off ...

  5. js实现切换页面清除定时器的函数

    背景: 我在切换页面的时候,发现切换回原来的页面,定时器会叠加而不会清除原来的定时器 解决方法: 1.定义全局变量,通过js遍历清除(不会用,但性能好) var pageTimer = {} ; // ...

  6. Mac 环境下 编译 spring 源码

    环境:macos idea jdk1.8 首先,在 spring.io的 git 地址 上下载下来源码后,执行里面的 gradlew命令,一般只要网络没有问题,都是可以成功的 然后,看显示的 Welc ...

  7. HGD2-LSP选择集专题-网络整理

    [Visual Lisp]图元选择集专题 图元选择集专题 ;;★★★01.选择集操作★★★ (setq ss (ssadd));;创建一个空选择集 (ssadd (car(entsel)) ss);; ...

  8. NTP同步时间

    什么是NTPNTP:Network Time Protocol(网络时间协议) ️ NTP 是用于同步网络中计算机时间的协议.它的用途是把计算机的时钟同步到世界协调时UTC. UTC:Universa ...

  9. (1)入门MasaFramework教程

    (1)入门MasaFramework教程 首先了解一下MasaFramework是什么 MasaFramework是一个基于.Net6.0的后端框架, 可以被用于开发Web应用程序.WPF项目.控制台 ...

  10. Javaweb学习笔记第八弹

    继续MyBatis学习 SQL语句警告提示问题 产生原因:IDEA和数据库没有建立连接,不识别表的信息 解决方式:在IDEA中配置MySQL数据库连接 在IDEA的Maven项目中,如果想要直接通过I ...