【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_())
相关推荐
YJlio5 小时前
1.7 通过 Sysinternals Live 在线运行工具:不下载也能用的“云端工具箱”
c语言·网络·python·数码相机·ios·django·iphone
l1t6 小时前
在wsl的python 3.14.3容器中使用databend包
开发语言·数据库·python·databend
山塘小鱼儿7 小时前
本地Ollama+Agent+LangGraph+LangSmith运行
python·langchain·ollama·langgraph·langsimth
码说AI7 小时前
python快速绘制走势图对比曲线
开发语言·python
wait_luky7 小时前
python作业3
开发语言·python
Python大数据分析@9 小时前
tkinter可以做出多复杂的界面?
python·microsoft
大黄说说9 小时前
新手选语言不再纠结:Java、Python、Go、JavaScript 四大热门语言全景对比与学习路线建议
java·python·golang
小小张说故事9 小时前
SQLAlchemy 技术入门指南
后端·python
我是章汕呐10 小时前
拆解Libvio.link爬虫:从动态页面到反爬对抗的实战解析
爬虫·python