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

Kivy货币转换App结果格式化:千位分隔与保留两位小数

货币转换App结果格式化需求及解决方案

我开发了一款货币转换App,用户可输入本国货币金额,并选择从本国货币转换为外币。以下是App的完整代码:

from kivy.core.text import LabelBase
from kivymd.app import MDApp
from kivy.lang.builder import Builder
from kivy.core.window import Window
from kivymd.uix.floatlayout import MDFloatLayout
from kivy.uix.button import Button
from kivymd.uix.menu import MDDropdownMenu
from kivy.metrics import dp  
from decimal import *
from forex_python.converter import CurrencyRates

Window.size=(400, 500)

class DropdownButton(MDFloatLayout, Button):
    pass

class CurrencyConvertor(MDApp):
    
    try:
        c = CurrencyRates()
        rates = c.get_rates('USD')  
        print(rates)
    except:
        print('Connection Error!') 
  
##################################################
   
    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        self.screen = Builder.load_string(kv)
        
##################################################
#################### to items #################### 
        c = CurrencyRates()       
        to_items = [
            {
                "viewclass": "OneLineListItem",
                "text": f"{i}",
                "height": dp(56),
                "on_release": lambda x=f"{i}": self.set_to(x),
            # } for i in range(5)
             } for i in self.rates.keys()
        ]
        self.to_menu = MDDropdownMenu(
            caller=self.screen.ids.to_currency,
            items=to_items,
            position="auto",
            width_mult=4,
        )
        self.to_menu.bind()
        
 ################################################## 
 ################### from items ###################     
        c = CurrencyRates()
        from_items = [
            {
                "viewclass": "OneLineListItem",
                "text": f"{i}",
                "height": dp(56),
                "on_release": lambda x=f"{i}": self.set_from(x),
            } for i in self.rates.keys()
           # } for i in range(5)
        ]
        self.from_menu = MDDropdownMenu(
            caller=self.screen.ids.from_currency,
            items=from_items,
            position="auto",
            width_mult=4,
        )
        self.from_menu.bind()
        
##################################################
##################### set to ##################### 
    def set_to(self, text_item):
        if text_item != self.screen.ids.from_currency.text:
            self.screen.ids.to_currency.text = text_item
            self.to_menu.dismiss()
    
##################################################
#################### set from ####################
    def set_from(self, text_item):
        if text_item != self.screen.ids.to_currency.text:
            self.screen.ids.from_currency.text = text_item
            self.from_menu.dismiss()
            
##################################################
    def build(self):
        return self.screen
    
    
##################################################    
    def convert(self):
    
        c = CurrencyRates(force_decimal=True)
        amount = int(self.screen.ids.amount.text)
        from_currency = self.screen.ids.from_currency.text
        to_currency = self.screen.ids.to_currency.text
        converted_amount = c.convert(from_currency, to_currency, Decimal(amount))
        #print(converted_amount)
        self.root.ids.result.text = f"{amount} {from_currency} = {converted_amount} {to_currency}"
       
kv = '''
#<KvLang>
MDFloatLayout:
    md_bg_color: 1,1,1,1
    MDLabel:
        text: 'Currency Convertor'
        pos_hint: {'center_x': .5, 'center_y': .9}
        halign: 'center'
        font_name: 'media/poppins-bold'
        front_size: '32sp'
    MDFloatLayout:
        size_hint: .85,.2
        pos_hint: {'center_x': 0.5,'center_y': 0.7}
        MDLabel:
            text: "Enter Amount"
            pos_hint: {'center_x': 0.5, 'center_y': 0.85}
            font_name: 'media/poppins-medium'
            font_size: '18sp'
        MDFloatLayout:
            size_hint_y: .5
            pos_hint: {'center_x': .5, 'center_y':.38}
            canvas.before:
                Color:
                    rgb: 210/255, 210/255, 210/255, 1
                Line:
                    width: 1.2
                    rounded_rectangle:self.x, self.y, self.width, self.height, 6, 6, 6, 6, 100
            TextInput:
                id: amount
                text: ''
                size_hint: 1, None
                pos_hint: {'center_x': .5, 'center_y': .5}
                height: self.minimum_height
                font_name: 'media/poppins-medium'        
                font_size: '18sp'
                hint_text_color: 170/255, 170/255, 170/255, 1
                background_color: 1, 1, 1, 0
                padding: 13
                cursor_color: 0,0,0,1
                multiline: False
                
    MDFloatLayout:
        size_hint: .85, .2
        pos_hint: {'center_x': .5, 'center_y': .46}
        MDFloatLayout:
            pos_hint: {'center_x': .6, 'center_y': .5} 
            MDLabel:
                text: "From"
                pos_hint: {'center_x': 0.5, 'center_y': 0.85}
                font_name: 'media/poppins-medium'
                font_size: '18sp'
                
            DropdownButton:                
                id: from_currency
                text: 'EUR'
                size_hint: .25, .5
                pos_hint: {'center_x': .125, 'center_y':.38}
                background_color: 0, 0, 0, 0
                color: 0, 0, 0, 1 
                font_size: '20sp'
                font_name: 'media/poppins-medium'
                on_release: app.from_menu.open()
                # on_release: print('Hello')
                canvas.before:
                    Color:
                        rgb: 210/255, 210/255, 210/255, 1
                    Line:
                        width: 1.2
                        rounded_rectangle:self.x, self.y, self.width, self.height, 6, 6, 6, 6, 100
        Image:
            source: 'media/arrow.png'
            size_hint: .35, .35
            pos_hint: {'center_x': .5, 'center_y': .38} 
            
        MDFloatLayout:
            pos_hint: {'center_x':1.15, 'center_y': .5} 
            MDLabel:
                text: "To"
                pos_hint: {'center_x': 0.5, 'center_y': 0.85}
                font_name: 'media/poppins-medium'
                font_size: '18sp'
                
            DropdownButton:                
                id: to_currency
                text: 'USD'
                size_hint: .25, .5
                pos_hint: {'center_x': .125, 'center_y':.38}
                background_color: 0,0,0,0
                color: 0,0,0,1
                font_name: 'media/poppins-medium'
                font_size: '20sp'
                on_release: app.to_menu.open()
                canvas.before:
                    Color:
                        rgb: 210/255, 210/255, 210/255, 1
                    Line:
                        width: 1.2
                        rounded_rectangle:self.x, self.y, self.width, self.height, 6, 6, 6, 6, 100
                        
    MDLabel:
        id: result
        text: ''
        pos_hint: {'center_x': .5, 'center_y': .3}
        halign: 'center'
        font_name: 'media/poppins-medium'
        font_size: '18sp'
        
    Button: 
        text: 'Get Exchange Rate'
        font_name: 'media/poppins-medium'
        size_hint: .85, .12
        font_size: '18sp'
        pos_hint: {'center_x': .5, 'center_y': .15}
        background_color: 1,1,1,0
        color: 1,1,1,1
        # on_release: print('result')
        on_release: app.convert()
        canvas.before:
            Color: 
                rgb: 71/255, 104/255, 237/255, 1
            RoundedRectangle:
                size: self.size
                pos: self.pos
                radius: [6]
#<KvLang>
'''

CurrencyConvertor().run()
LabelBase.register(name="Poppins", fn_regular="media/Poppins-Regular.ttf")     

当前App转换结果示例:输入10000 USD转换为EUR时,显示为 10000 EUR = 10131.0000 USD。现需对结果做以下格式化优化:

  • 为原始金额和转换后的金额添加千位分隔符(每千位用逗号分隔)
  • 转换后的金额保留两位小数

实现方案

只需修改convert方法中的结果格式化代码,利用Python的字符串格式化语法即可完成需求:

def convert(self):
    c = CurrencyRates(force_decimal=True)
    amount = int(self.screen.ids.amount.text)
    from_currency = self.screen.ids.from_currency.text
    to_currency = self.screen.ids.to_currency.text
    converted_amount = c.convert(from_currency, to_currency, Decimal(amount))
    
    # 格式化原始金额:添加千位分隔符
    formatted_amount = "{:,}".format(amount)
    # 格式化转换后金额:保留两位小数 + 千位分隔符
    formatted_converted = "{:,.2f}".format(converted_amount)
    
    self.root.ids.result.text = f"{formatted_amount} {from_currency} = {formatted_converted} {to_currency}"

说明

  • "{:,}":Python格式化语法中,逗号用于添加千位分隔符,适用于整数和浮点数/Decimal类型
  • "{:,.2f}":结合了千位分隔符和保留两位小数的格式,.2f指定保留两位小数,逗号负责分隔千位
  • 转换后的converted_amount是Decimal类型,直接用上述格式字符串处理即可,无需额外转换类型

优化后,之前的示例结果会显示为:10,000 EUR = 10,131.00 USD,符合易读性要求。

内容的提问来源于stack exchange,提问作者Loh Boon How

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.21 22:39:20