PyQt6中重写QIntValidator的fixup()方法无效问题求助
PyQt6中QIntValidator子类fixup()方法不执行的解决办法
问题分析
你已成功将自定义IntValidator子类应用到QLineEdit派生类,但重写的fixup()方法未触发(如print语句无输出);原生QIntValidator的数字验证功能正常,但自定义修复逻辑失效。
核心原因
PyQt6中fixup()的触发有严格条件:
- 仅当输入文本验证状态为Invalid(如输入值超出1-255范围、空字符串需手动标记为Invalid),且控件失去焦点(或主动调用
QLineEdit.fixup())时,fixup()才会被调用。 - 你的
fixup()写法有误:Python字符串为不可变类型,直接赋值input = "123"无法修改原输入内容,需通过PyQt提供的字符串操作方法修改。
正确实现方案
1. 修正IntValidator的fixup()方法
需通过replace()方法修改传入的字符串对象,同时明确触发条件:
from PyQt6.QtGui import QIntValidator from PyQt6.QtCore import QValidator class IntValidator(QIntValidator): def validate(self, input_str, pos): # 调用父类验证逻辑 state, input_str, pos = super().validate(input_str, pos) # 将空字符串标记为Invalid,触发fixup if not input_str.strip(): return QValidator.State.Invalid, input_str, pos return state, input_str, pos def fixup(self, input_str): print("自定义fixup执行") # 将非法/空输入替换为最小值1 input_str.replace(0, len(input_str), str(self.bottom()))
2. 验证触发逻辑
满足以下场景时,fixup()会自动执行:
- 输入
0(小于最小值1)后,点击窗口其他区域让控件失焦 - 输入
256(大于最大值255)后失焦 - 输入空字符串后失焦(已通过重写
validate()标记为Invalid)
3. 修正后的完整代码示例
IntValidator.py
from PyQt6.QtGui import QIntValidator from PyQt6.QtCore import QValidator class IntValidator(QIntValidator): def validate(self, input_str, pos): state, input_str, pos = super().validate(input_str, pos) if not input_str.strip(): return QValidator.State.Invalid, input_str, pos return state, input_str, pos def fixup(self, input_str): print("自定义fixup执行") input_str.replace(0, len(input_str), str(self.bottom()))
StepsInput.py
from IntValidator import IntValidator from LabeledInputInput import LabeledInputInput class StepsInput(LabeledInputInput): def set_validator(self) -> None: validator = IntValidator(1, 255) self.setValidator(validator)
LabeledInputInput.py
from PyQt6.QtWidgets import QLineEdit from PyQt6.QtCore import Qt, QRegularExpression from PyQt6.QtGui import QRegularExpressionValidator from PasteToMenu import PasteToMenu class LabeledInputInput(QLineEdit): context_menu: PasteToMenu def __init__(self): super().__init__() self.context_menu = PasteToMenu() self.__set_appearance() self.set_validator() def contextMenuEvent(self, event): self.context_menu.exec(event.globalPos()) def __set_appearance(self) -> None: self.setFixedSize(50, 20) self.setAlignment(Qt.AlignmentFlag.AlignCenter) self.setStyleSheet(self.__generate_style_sheet()) def __generate_style_sheet(self) -> str: return ''' LabeledInputInput { background-color: #EEEEEE; border: 2px solid #FFD369; color: #393E46; font-size: 10pt; font-weight: bold; } ''' def set_validator(self) -> None: pattern = '[0-9]+' regex = QRegularExpression(pattern) validator = QRegularExpressionValidator(regex) self.setValidator(validator)
关键注意事项
- 触发时机:仅验证状态为Invalid时,控件失焦才会调用
fixup();Acceptable或Intermediate状态不会触发。 - 字符串修改:必须使用
input_str.replace()修改内容,直接赋值无法改变原输入。 - 参数命名:避免用
input作为参数名,防止与Python内置input()函数冲突。
内容的提问来源于stack exchange,提问作者john
相关产品推荐
相关产品推荐

