在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)
一樣可以使用這個邏輯進行處理,只要前期構建好,代碼復用完全不是問題,
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/550186.html
標籤:Python
上一篇:python行程池中的回呼函式