【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_())
相关推荐
小陈的进阶之路1 小时前
Claude Code辅助测试:导入篇skills
python·自动化
whcyhhh2 小时前
头歌实践教学平台:大数据存储2023(六)
大数据·数据库·python
for_ever_love__3 小时前
python基础语法学习: 闭包
开发语言·python·学习·闭包
ly76893 小时前
Python 全面入门:从核心语法到工程实践
开发语言·python
Niuguangshuo4 小时前
DeepFilterNet 3:端侧实时全带降噪的开源标杆
python
第一程序员5 小时前
AI 辅助编程的 7 个误区:把模型当高级搜索引擎是对它的最大浪费
python·rust·github
Groundwork Explorer6 小时前
W5500 网卡编程初始化与使用指南
python·单片机
逸Y 仙X6 小时前
MCP(模型控制协议)完全指南:从核心概念到实战开发
python·大模型·llm·ai编程·mcp
WILLF7 小时前
前端视角:Python requests vs JS axios
前端·python
哒哒哒5285207 小时前
69. Python: 核心语法-面向对象基础-案例(教务系统)
python