PyQt5-组件控件-setValidator验证过滤器控件基本使用(三)

博客给出了实现组件控件的代码,介绍了两种实现方法,供读者参考使用。

样式一
样式二
直接上代码:

import re
import sys
from PyQt5 import QtCore, QtGui
from PyQt5.QtWidgets import QApplication, QLineEdit
from PyQt5.QtWidgets import QWidget, QHBoxLayout, QPushButton, QMessageBox


class NumericTextBox(QLineEdit):
    def __init__(self, *args):
        super(NumericTextBox, self).__init__()
        __regExp = QtCore.QRegExp('^(?!0)\d{1,6}\.\d{1,2}$')
        self.setValidator(QtGui.QRegExpValidator(__regExp, self))
        self.textChanged.connect(self.onValueChanged)

    def setPositiveAndNegativeInterval(self):
        regExp = QtCore.QRegExp('^(\-?)\d{1,6}\.\d{1,2}$')
        self.setValidator(QtGui.QRegExpValidator(regExp, self))

    def onValueChanged(self):
        pass
        # try:
        #     text = self.text()
        #     if text.__len__() > 1 or text[-1] != ".":
        #         self.setText(str((float(text))))
        # except Exception:
        #     print(Exception)

    def getIntValue(self):
        return int(self.text())

    def getFloatValue(self):
        return float(self.text())



class testNumericTextBox(QWidget):
    def __init__(self):
        super(testNumericTextBox, self).__init__()
        self.initUI()

    def initUI(self):
        self.box = QHBoxLayout()
        # 创建文本框
        regExp1 = QtCore.QRegExp('^\d{1,6}\.\d{1,2}$')
        self.text1 = QLineEdit()
        # 表单布局添加名称及控件
        self.box.addWidget(self.text1)
        self.btn = QPushButton("确认")
        self.box.addWidget(self.btn)

        # 设置文本框的默认浮现文本
        self.text1.setPlaceholderText("可输入范围0-10000")
        # 设置校验
        self.text1.setValidator(QtGui.QRegExpValidator(regExp1, self))
        self.setLayout(self.box)
        self.btn.clicked.connect(self.setUsefulRange)

    def setUsefulRange(self):
        text = self.text1.text()
        if text == '':
            print("数值为空")
            QMessageBox.information(self, "提示信息", "数值为空")
        else:
            if re.match('.+\.$', text) or re.match('^0\d0$', text):
                print("格式不正确:{}".format(text))
                # isClearButtonEnabled()
                QMessageBox.information(self, "提示信息", "格式不正确:{}".format(text))
            elif float(text) <= 100000:
                print("数值确认:{}".format(text))
                # isClearButtonEnabled()
                QMessageBox.information(self, "提示信息", "数值确认:{}".format(text))
            else:
                print("数值超出范围0-100000:{}".format(text))
                # isClearButtonEnabled()
                QMessageBox.information(self, "提示信息", "数值超出范围0-100000:{}".format(text))
                # raise Exception("Only input positive number")


if __name__ == '__main__':
    app = QApplication(sys.argv)
    win = testNumericTextBox()
    win.show()
    sys.exit(app.exec_())

两种方法实现,可自行参考使用

<think>好的,用户现在的问题是关于如何在PyQt5动态生成的UI中为QLineEdit组件绑定事件。之前他们已经问过如何获取动态生成的QLineEdit的值,现在他们想进一步了解事件绑定的具体方法。我需要结合之前的回答和新的问题来提供详细的解决方案。 首先,回顾之前的回答,用户已经知道需要用列表或字典来存储动态生成的控件,并且使用了textChanged信号进行实时监听。现在的问题是关于事件绑定,可能包括其他类型的事件,比如回车键按下、焦点变化或者自定义验证。 接下来,我需要考虑用户可能的实际需求。动态生成的QLineEdit可能需要不同的事件处理,例如输入验证、实时搜索、自动跳转等。用户可能需要具体的例子来理解如何绑定这些事件。 需要分步骤说明,可能包括核心方法、事件绑定方式、示例代码和注意事项。核心方法可能包括使用信号与槽机制、lambda表达式传递参数、对象存储等。事件类型可能包括textChanged、editingFinished、returnPressed、focusIn/Out等。 然后,要提供一个完整的示例代码,展示如何动态生成QLineEdit并绑定不同的事件,比如实时输入响应、回车键提交、焦点变化处理等。同时,需要解释代码中的关键点,比如为什么使用lambda来传递参数,如何避免信号绑定的常见问题,比如最后一个控件覆盖的问题。 还要考虑用户可能遇到的问题,比如如何传递额外的参数,如何在事件处理函数中区分不同的控件,以及内存管理的问题,比如控件销毁时如何处理。 此外,用户提供的引用[1]提到QWidget是基类,所有控件继承自它,可以接收输入事件。这可能涉及到更底层的事件处理,比如重写event方法,但通常信号与槽已经足够,所以可能不需要深入这部分,除非用户有特殊需求。 最后,需要总结关键点,并生成相关问题,帮助用户进一步探索,比如输入验证、动态删除控件、滚动区域实现等,这些相关问题可以引导用户深入学习。</think>在PyQt5动态UI中为QLineEdit组件绑定事件,可以通过信号与槽机制实现。以下是具体实现方法和关键步骤: ### 一、核心绑定方法 1. **动态对象存储** 使用容器保存动态生成的QLineEdit对象 ```python self.dynamic_edits = [] # 存储动态创建的输入框 ``` 2. **信号绑定方式** ```python new_edit = QLineEdit() new_edit.textChanged.connect(handler) # 绑定输入变化事件 new_edit.returnPressed.connect(submit) # 绑定回车键事件 ``` ### 二、常用事件类型 | 事件信号 | 触发条件 | 典型应用场景 | |----------------------|------------------------------|--------------------------| | `textChanged(str)` | 文本内容发生任何变化时触发 | 实时输入校验/搜索建议 | | `editingFinished()` | 结束编辑(焦点移出)时触发 | 表单字段验证 | | `returnPressed()` | 按下回车键时触发 | 快速提交单字段数据 | | `selectionChanged()` | 文本选择范围变化时触发 | 特殊文本操作功能 | ### 、完整实现示例 ```python from PyQt5.QtWidgets import QApplication, QWidget, QVBoxLayout, QPushButton, QLineEdit class DynamicEventDemo(QWidget): def __init__(self): super().__init__() self.dynamic_edits = [] self.init_ui() def init_ui(self): layout = QVBoxLayout() # 动态添加控件按钮 btn_add = QPushButton('新建输入框') btn_add.clicked.connect(self.create_edit) layout.addWidget(btn_add) # 示例功能按钮 btn_clear = QPushButton('清空所有') btn_clear.clicked.connect(self.clear_all) layout.addWidget(btn_clear) self.setLayout(layout) self.setWindowTitle('动态事件绑定示例') self.show() def create_edit(self): new_edit = QLineEdit() new_edit.setPlaceholderText(f'输入框 {len(self.dynamic_edits)+1}') # 绑定多个事件 new_edit.textChanged.connect( lambda text, obj=new_edit: self.on_text_change(obj, text) ) new_edit.returnPressed.connect( lambda: self.on_enter_press(new_edit) ) new_edit.editingFinished.connect( lambda: self.validate_input(new_edit) ) self.dynamic_edits.append(new_edit) self.layout().addWidget(new_edit) def on_text_change(self, edit_obj, text): print(f'[{edit_obj.objectName()}] 实时输入:', text) # 此处可添加实时校验逻辑 def on_enter_press(self, edit_obj): print(f'[{edit_obj.objectName()}] 提交值:', edit_obj.text()) # 触发数据提交操作 def validate_input(self, edit_obj): if not edit_obj.text().isalnum(): edit_obj.setStyleSheet("background: #ffe6e6;") print("输入包含非法字符!") else: edit_obj.setStyleSheet("") def clear_all(self): for edit in self.dynamic_edits: edit.clear() if __name__ == '__main__': app = QApplication([]) ex = DynamicEventDemo() app.exec_() ``` ### 四、关键实现细节 1. **Lambda参数传递** 使用`lambda`表达式传递当前控件引用,解决信号默认只传递基本参数的问题: ```python # 正确写法:显式传递对象引用 new_edit.textChanged.connect(lambda text, obj=new_edit: handler(obj, text)) # 错误写法:会导致所有信号都指向最后创建的控件 new_edit.textChanged.connect(lambda: handler(new_edit)) ``` 2. **动态样式控制** 通过`setStyleSheet()`实现即时反馈: ```python def validate_input(self, edit_obj): if len(edit_obj.text()) > 10: edit_obj.setStyleSheet("border: 2px solid red;") else: edit_obj.setStyleSheet("") ``` 3. **事件处理优化** - 使用`QTimer.singleShot`延迟处理高频触发事件(如实时搜索)[^3] - 对大量动态控件使用事件过滤器提高性能: ```python new_edit.installEventFilter(self) def eventFilter(self, obj, event): if event.type() == QtCore.QEvent.FocusIn: print(f"{obj.objectName()} 获得焦点") return super().eventFilter(obj, event) ``` ### 五、扩展应用场景 1. **输入验证** ```python new_edit.setValidator(QIntValidator(0, 100)) # 限制数字输入 ``` 2. **自动补全** ```python completer = QCompleter(["北京", "上海", "广州"]) new_edit.setCompleter(completer) ``` 3. **快捷键绑定** ```python new_edit.addAction(QIcon("search.png"), QLineEdit.TrailingPosition ).triggered.connect(search_handler) ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

宥钧

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

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

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

打赏作者

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

抵扣说明:

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

余额充值