【PYQT】QLineEdit控件的信号与槽

目录

[1. 文本内容变化相关](#1. 文本内容变化相关)

[2. 焦点与状态相关](#2. 焦点与状态相关)

[3. 输入限制相关](#3. 输入限制相关)

槽函数(Slots)示例

常用槽函数(内置)

补充:鼠标点击控件空余地方,确认输入内容,光标消失


QLineEdit 提供了丰富的信号来响应文本编辑的各种操作,以下是最常用的信号,按使用场景分类:

1. 文本内容变化相关

信号 触发时机 说明
textChanged(str text) 文本内容任何修改时(包括代码修改) 最常用,文本一改变就触发,参数是最新的文本内容
textEdited(str text) 仅用户手动编辑文本时触发 代码调用setText()不会触发,适合区分用户操作和程序操作

2. 焦点与状态相关

信号 触发时机 说明
editingFinished() 编辑完成时(失去焦点 / 按 Enter 键) 常用于确认用户输入,无参数
returnPressed() 按下Enter/Return键时 适合实现 "回车确认" 功能
selectionChanged() 选中的文本范围变化时 监控文本选中状态
cursorPositionChanged(int oldPos, int newPos) 光标位置变化时 参数为旧位置和新位置

3. 输入限制相关

信号 触发时机 说明
inputRejected() 输入被验证器(Validator)拒绝时 配合 QValidator 使用,监控非法输入

槽函数(Slots)示例

python 复制代码
import sys
from PyQt5.QtWidgets import (QApplication, QWidget, QVBoxLayout, 
                             QLineEdit, QLabel, QTextEdit)


class LineEditSignalDemo(QWidget):
    def __init__(self):
        super().__init__()
        self.init_ui()
        
    def init_ui(self):
        self.setWindowTitle('QLineEdit 信号槽示例')
        self.setGeometry(100, 100, 500, 400)
        
        # 创建布局
        layout = QVBoxLayout()
        
        # 创建QLineEdit
        self.line_edit = QLineEdit()
        self.line_edit.setPlaceholderText('请输入文本,体验各种信号触发...')
        layout.addWidget(self.line_edit)
        
        # 创建日志显示框
        self.log_text = QTextEdit()
        self.log_text.setReadOnly(True)
        layout.addWidget(self.log_text)
        
        self.setLayout(layout)
        
        # 绑定信号与槽
        self.bind_signals()
        
    def bind_signals(self):
        """绑定所有演示的信号"""
        # 1. 文本变化(任何修改)
        self.line_edit.textChanged.connect(self.on_text_changed)
        
        # 2. 文本编辑(仅用户手动修改)
        self.line_edit.textEdited.connect(self.on_text_edited)
        
        # 3. 编辑完成(失去焦点/回车)
        self.line_edit.editingFinished.connect(self.on_editing_finished)
        
        # 4. 按下回车键
        self.line_edit.returnPressed.connect(self.on_return_pressed)
        
        # 5. 选中文本变化
        self.line_edit.selectionChanged.connect(self.on_selection_changed)
        
        # 6. 光标位置变化
        self.line_edit.cursorPositionChanged.connect(self.on_cursor_changed)
        
    def log(self, msg):
        """日志输出辅助函数"""
        self.log_text.append(msg)
        
    # ------------------- 槽函数定义 -------------------
    def on_text_changed(self, text):
        """文本变化槽函数"""
        self.log(f'[textChanged] 文本变为:{text}')
        
    def on_text_edited(self, text):
        """文本编辑槽函数"""
        self.log(f'[textEdited] 用户编辑文本为:{text}')
        
    def on_editing_finished(self):
        """编辑完成槽函数"""
        self.log(f'[editingFinished] 编辑完成,当前文本:{self.line_edit.text()}')
        
    def on_return_pressed(self):
        """回车按下槽函数"""
        self.log(f'[returnPressed] 按下回车,当前文本:{self.line_edit.text()}')
        
    def on_selection_changed(self):
        """选中文本变化槽函数"""
        selected = self.line_edit.selectedText()
        self.log(f'[selectionChanged] 选中的文本:{selected if selected else "无"}')
        
    def on_cursor_changed(self, old_pos, new_pos):
        """光标位置变化槽函数"""
        self.log(f'[cursorPositionChanged] 光标从{old_pos}移到{new_pos}')


if __name__ == '__main__':
    app = QApplication(sys.argv)
    window = LineEditSignalDemo()
    window.show()
    
    # 测试:用代码修改文本,对比textChanged和textEdited的区别
    # 延迟2秒后用代码修改文本,观察日志
    from PyQt5.QtCore import QTimer
    QTimer.singleShot(2000, lambda: window.line_edit.setText('代码设置的文本'))
    
    sys.exit(app.exec_())

常用槽函数(内置)

除了自定义槽函数,QLineEdit 也有内置的实用槽函数可直接使用:

内置槽函数 功能
clear() 清空文本框内容
setText(str text) 设置文本框内容
selectAll() 选中所有文本
deselect() 取消文本选中
setFocus() 让文本框获得焦点

补充:鼠标点击控件空余地方,确认输入内容,光标消失

  • 重写窗口的mousePressEvent事件,监听鼠标点击事件
  • 在点击事件中判断点击位置是否在 QLineEdit 之外(空余区域)
  • 如果是空余区域,让 QLineEdit 失去焦点,并触发输入内容的确认逻辑
python 复制代码
import sys
from PyQt5.QtWidgets import (QApplication, QWidget, QVBoxLayout, 
                             QLineEdit, QLabel, QMessageBox)
from PyQt5.QtGui import QIntValidator
from PyQt5.QtCore import Qt


class IntRangeLineEdit(QWidget):
    def __init__(self):
        super().__init__()
        self.init_ui()
        
    def init_ui(self):
        # 设置窗口属性
        self.setWindowTitle('整数输入限制(150-1500)')
        self.setGeometry(100, 100, 400, 200)
        
        # 创建布局
        layout = QVBoxLayout()
        # 设置布局边距和间距,留出空余区域
        layout.setContentsMargins(50, 50, 50, 50)
        layout.setSpacing(20)
        
        # 添加提示标签
        label = QLabel('请输入150-1500之间的整数:')
        layout.addWidget(label)
        
        # 创建QLineEdit并设置验证器
        self.int_edit = QLineEdit()
        self.int_edit.setPlaceholderText('例如:200、1000、1500')
        
        # 1. 设置整数验证器,限定范围150-1500
        self.validator = QIntValidator(150, 1500, self.int_edit)
        self.int_edit.setValidator(self.validator)
        
        # 2. 绑定编辑完成信号,做最终验证
        self.int_edit.editingFinished.connect(self.validate_input)
        
        layout.addWidget(self.int_edit)
        self.setLayout(layout)
        
    def validate_input(self):
        """编辑完成后验证输入的合法性"""
        # 获取输入文本
        text = self.int_edit.text().strip()
        
        # 处理空输入
        if not text:
            QMessageBox.warning(self, '提示', '输入不能为空,请输入150-1500之间的整数!')
            self.int_edit.clear()
            return
        
        # 转换为整数并验证范围(双重保险)
        try:
            value = int(text)
            if 150 <= value <= 1500:
                QMessageBox.information(self, '确认成功', f'已确认输入值:{value}')
            else:
                QMessageBox.critical(self, '错误', f'输入值{value}超出范围!请输入150-1500之间的整数')
                self.int_edit.setText('150')
        except ValueError:
            QMessageBox.critical(self, '错误', '输入无效!只能输入整数')
            self.int_edit.clear()
    
    def mousePressEvent(self, event):
        """重写鼠标点击事件"""
        # 判断点击的位置是否在QLineEdit控件之外
        if not self.int_edit.geometry().contains(event.pos()):
            # 让QLineEdit失去焦点(光标消失)
            self.int_edit.clearFocus()
            # 如果QLineEdit有内容,触发验证确认逻辑
            if self.int_edit.text().strip():
                self.validate_input()
        # 调用父类的鼠标事件,保证其他功能正常
        super().mousePressEvent(event)


if __name__ == '__main__':
    app = QApplication(sys.argv)
    window = IntRangeLineEdit()
    window.show()
    sys.exit(app.exec_())
相关推荐
兵慌码乱7 小时前
基于Python+PyQt5+SQLite的药房管理系统实现:事务一致性与界面解耦全流程解析
python·sqlite·信号与槽·pyqt5·数据库设计·桌面应用开发·事务处理
金銀銅鐵9 小时前
[Python] 体验用欧几里得算法计算最大公约数的过程
python·数学
FreakStudio13 小时前
W55MH32L-EVB 上手测评:硬件 TCP/IP 加持的以太网单片机,MicroPython 零门槛开发
python·单片机·嵌入式·大学生·面向对象·并行计算·电子diy·电子计算机
用户03321266636714 小时前
使用 Python 从零创建 Word 文档
python
Csvn18 小时前
Python 两大经典坑点 —— 可变默认参数 & 闭包延迟绑定
后端·python
曲幽20 小时前
别再用网页翻译看源码了!你的私人翻译神器LibreTranslate,部署避坑指南来了
python·docker·web·pot·translate·libretranslate·arogstranslate
用户5569188175321 小时前
#从脚本到独立程序:Python + Playwright 批量抓取的完整踩坑记录
python·自动化运维
兵慌码乱1 天前
基于 MediaPipe 与 PySide2 的手势交互音乐控制系统实现:轻量化视觉交互全流程解析
python·opencv·计算机视觉·人机交互·手势识别·mediapipe·pyside2
luckdewei2 天前
FastAPI 资产管理系统实战:复杂 ORM 关联、Alembic 迁移与 N+1 查询优化
python