You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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_())

代码说明

  1. 自定义输入框:通过eventFilter拦截非法按键和光标移动,确保前缀/后缀文本不被修改;重写textChanged方法维护固定文本结构,提取有效数字并发射信号。
  2. 实时转换:主界面监听输入框的valueChanged信号,实时计算汇率并更新结果标签。
  3. 扩展性:可通过修改prefix和suffix参数调整固定文本内容,适配不同货币格式。

内容的提问来源于stack exchange,提问作者user21956032

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.20 20:10:34