PyQt5开发货币转换器:实现输入框仅指定数值可编辑
PyQt5实现部分可编辑的货币转换器输入框
需求可行性
完全可行,通过自定义QLineEdit子类并结合事件过滤、文本监听即可实现仅数字区域可编辑、其余文本固定的效果,同时支持实时更新转换结果。
实现思路
核心逻辑:
- 固定输入框的前缀/后缀文本(比如" USD"),仅开放中间数字区域供编辑
- 通过事件过滤限制光标移动、按键输入,防止用户修改固定文本
- 监听数字部分的变化,实时计算并更新转换后的数值
完整代码实现
自定义部分可编辑的输入框
from PyQt5.QtWidgets import QLineEdit, QWidget, QVBoxLayout, QApplication, QLabel from PyQt5.QtCore import Qt, QEvent, pyqtSignal class PartialEditableLineEdit(QLineEdit): valueChanged = pyqtSignal(float) # 数值变化时发射的信号 def __init__(self, prefix="", suffix="", parent=None): super().__init__(parent) self.prefix = prefix self.suffix = suffix # 初始化默认文本 self.setText(f"{prefix}1{suffix}") # 默认光标定位到数字区域 self.setCursorPosition(len(prefix)) # 安装事件过滤器,控制输入和光标 self.installEventFilter(self) def eventFilter(self, obj, event): if obj != self: return super().eventFilter(obj, event) # 处理按键事件 if event.type() == QEvent.KeyPress: key = event.key() # 允许的按键:数字、退格、删除、左右箭头(仅在数字区域内移动) allowed_keys = [Qt.Key_0, Qt.Key_1, Qt.Key_2, Qt.Key_3, Qt.Key_4, Qt.Key_5, Qt.Key_6, Qt.Key_7, Qt.Key_8, Qt.Key_9, Qt.Key_Backspace, Qt.Key_Delete, Qt.Key_Left, Qt.Key_Right] if key not in allowed_keys: return True # 拦截不允许的按键 cursor_pos = self.cursorPosition() # 限制光标不能移到前缀前或后缀后 if key == Qt.Key_Left and cursor_pos <= len(self.prefix): return True if key == Qt.Key_Right and cursor_pos >= len(self.text()) - len(self.suffix): return True # 禁止删除前缀或后缀 if key in [Qt.Key_Backspace, Qt.Key_Delete]: selected = self.selectedText() if selected: if self.prefix in selected or self.suffix in selected: return True else: if key == Qt.Key_Backspace and cursor_pos <= len(self.prefix): return True if key == Qt.Key_Delete and cursor_pos >= len(self.text()) - len(self.suffix): return True # 聚焦时光标自动定位到数字区域 elif event.type() == QEvent.FocusIn: self.setCursorPosition(len(self.prefix)) return super().eventFilter(obj, event) def textChanged(self, text): # 确保前缀和后缀始终存在,防止被意外修改 if not text.startswith(self.prefix): text = self.prefix + text.lstrip() if not text.endswith(self.suffix): text = text.rstrip() + self.suffix # 提取中间的数字部分 num_part = text[len(self.prefix):-len(self.suffix)].strip() # 处理空输入,默认设为1 if not num_part or not num_part.replace(".", "").isdigit(): num_part = "1" # 更新文本,避免递归触发textChanged new_text = f"{self.prefix}{num_part}{self.suffix}" if new_text != self.text(): self.blockSignals(True) self.setText(new_text) self.blockSignals(False) # 光标定位到数字末尾 self.setCursorPosition(len(self.prefix) + len(num_part)) # 发射数值变化信号 try: self.valueChanged.emit(float(num_part)) except ValueError: pass
货币转换器主界面
class CurrencyConverter(QWidget): def __init__(self): super().__init__() self.init_ui() def init_ui(self): layout = QVBoxLayout() # 创建输入框:数字可编辑,后缀" USD"固定 self.input_edit = PartialEditableLineEdit(suffix=" USD") # 转换结果标签 self.result_label = QLabel("= 0.92 EUR") layout.addWidget(self.input_edit) layout.addWidget(self.result_label) self.setLayout(layout) # 绑定数值变化信号到更新函数 self.input_edit.valueChanged.connect(self.update_conversion) self.setWindowTitle("Currency Converter") self.resize(300, 100) self.show() def update_conversion(self, usd_value): # 这里替换为实际汇率逻辑 usd_to_eur = 0.92 eur_value = usd_value * usd_to_eur self.result_label.setText(f"= {eur_value:.2f} EUR") if __name__ == "__main__": import sys app = QApplication(sys.argv) converter = CurrencyConverter() sys.exit(app.exec_())
代码说明
- 自定义输入框:通过
eventFilter拦截非法按键和光标移动,确保前缀/后缀文本不被修改;重写textChanged方法维护固定文本结构,提取有效数字并发射信号。 - 实时转换:主界面监听输入框的
valueChanged信号,实时计算汇率并更新结果标签。 - 扩展性:可通过修改
prefix和suffix参数调整固定文本内容,适配不同货币格式。
内容的提问来源于stack exchange,提问作者user21956032
相关产品推荐
相关产品推荐

