python编写一个软件-软件代做:利用Python编写一个行业专用的小计算器

前言:本文讲述的是如何利用python编程制作一个适用于指定行业的计算器,方便计算结果,涵盖的知识点由Python编写GUI界面程序,利用爬虫采集实时的汇率数据,将Python文件打包成可以单独运行的exe文件。

首先,分析我们的需求,编写一个适用于指定行业的计算器,这里我们用到的计算公式很简单,就是淘宝提供的金石定价公式,如下图所示

微信图片_20200910151412_1599722089767.jpg淘宝定价计算器

这里可以看到这个计算公式还是蛮简单的,对于Python来说也就是一行代码的事,那么我们就开始着手写代码,首先搭建我们的页面布局,这里我们采用的是tkinter,这个框架在画GUI方面还是很简单方便的,首先给大家展示下我的最终布局,如下图所示

微信图片_20200910151425_1599722386758.jpg最终样式

其实也不是很好看,不过我已经尽我所能去美化了,其实功能很简单,就是几个输入框,两个按钮,点击计算按钮,获取输入框中的值,通过Python代码计算结果,最后将计算结果写入指定的输入框中,关于tkinter的组件介绍,可以自行百度,我这里就直接上代码了

class Application(tk.Tk):

def __init__(self):

super().__init__()

self.createUI()

def createUI(self):

self.ft = tf.Font(family='微软雅黑', size=18,weight=tf.BOLD)

self.ft1 = tf.Font(family='微软雅黑', size=12)

self.fm = tk.Frame(self)

self.label = tk.Label(self.fm,text="计算结果:",font=self.ft)

self.label.pack(side=tk.LEFT)

self.fm_new1 = tk.Frame(self.fm)

self.label0 = tk.Label(self.fm_new1,text="人民币:",font=self.ft1)

self.label0.pack(side=tk.LEFT)

self.entry0 = tk.Entry(self.fm_new1,font=self.ft1)

self.entry0.pack(side=tk.LEFT)

self.label11 = tk.Label(self.fm_new1,text="美元:",font=self.ft1)

self.label11.pack(side=tk.LEFT)

self.entry11 = tk.Entry(self.fm_new1,font=self.ft1)

self.entry11.pack(side=tk.LEFT)

self.fm_new1.pack(side=tk.TOP,padx=5, pady=10)

self.fm_new2 = tk.Frame(self.fm)

self.label12 = tk.Label(self.fm_new2,text="新加坡币:",font=self.ft1)

self.label12.pack(side=tk.LEFT)

self.entry12 = tk.Entry(self.fm_new2,font=self.ft1)

self.entry12.pack(side=tk.LEFT)

self.label13 = tk.Label(self.fm_new2,text="日元:",font=self.ft1)

self.label13.pack(side=tk.LEFT)

self.entry13 = tk.Entry(self.fm_new2,font=self.ft1)

self.entry13.pack(side=tk.LEFT)

self.fm_new2.pack(side=tk.TOP,padx=5, pady=10)

self.fm.pack(side=tk.TOP,padx=5, pady=10)

self.fm1 = tk.Frame(self)

self.label1 = tk.Label(self.fm1,text="金 重:",font=self.ft1)

self.label1.pack(side=tk.LEFT,padx=10, pady=10)

self.entry1 = tk.Entry(self.fm1,font=self.ft1)

self.entry1.pack(side=tk.LEFT,padx=5, pady=10)

self.label10 = tk.Label(self.fm1,text="浮动比率:",font=self.ft1)

self.label10.pack(side=tk.LEFT,padx=10, pady=10)

self.entry10 = tk.Entry(self.fm1,font=self.ft1)

self.entry10.pack(side=tk.LEFT,anchor=tk.W,padx=5, pady=10)

self.fm1.pack(side=tk.TOP,padx=5, pady=5)

self.fm2 = tk.Frame(self)

self.label2 = tk.Label(self.fm2,text="金 价:",font=self.ft1)

self.label2.pack(side=tk.LEFT,padx=10, pady=10)

self.entry2 = tk.Entry(self.fm2,font=self.ft1)

self.entry2.pack(side=tk.LEFT,padx=5, pady=10)

self.labe3 = tk.Label(self.fm2,text="14K/18K:",font=self.ft1)

self.labe3.pack(side=tk.LEFT,padx=10, pady=10)

self.entry3 = tk.Entry(self.fm2,font=self.ft1)

self.entry3.pack(side=tk.LEFT,padx=5, pady=10)

self.fm2.pack(side=tk.TOP,padx=5, pady=5)

self.fm3 = tk.Frame(self)

self.label4 = tk.Label(self.fm3,text="主石重:",font=self.ft1)

self.label4.pack(side=tk.LEFT,padx=10, pady=10)

self.entry4 = tk.Entry(self.fm3,font=self.ft1)

self.entry4.pack(side=tk.LEFT,padx=5, pady=10)

self.label5 = tk.Label(self.fm3,text="价 格:",font=self.ft1)

self.label5.pack(side=tk.LEFT,padx=10, pady=10)

self.entry5 = tk.Entry(self.fm3,font=self.ft1)

self.entry5.pack(side=tk.LEFT,padx=5, pady=10)

self.fm3.pack(side=tk.TOP,padx=5, pady=5)

self.fm4 = tk.Frame(self)

self.label6 = tk.Label(self.fm4,text="副石重:",font=self.ft1)

self.label6.pack(side=tk.LEFT,padx=10, pady=10)

self.entry6 = tk.Entry(self.fm4,font=self.ft1)

self.entry6.pack(side=tk.LEFT,padx=5, pady=10)

self.labe7 = tk.Label(self.fm4,text="价 格:",font=self.ft1)

self.labe7.pack(side=tk.LEFT,padx=10, pady=10)

self.entry7 = tk.Entry(self.fm4,font=self.ft1)

self.entry7.pack(side=tk.LEFT,padx=5, pady=10)

self.fm4.pack(side=tk.TOP,padx=5, pady=5)

self.fm5 = tk.Frame(self)

self.label8 = tk.Label(self.fm5,text="工费:",font=self.ft1)

self.label8.pack(side=tk.LEFT,padx=10, pady=10)

self.entry8 = tk.Entry(self.fm5,font=self.ft1)

self.entry8.pack(side=tk.LEFT,padx=5, pady=10)

self.labe9 = tk.Label(self.fm5,text="设计费:",font=self.ft1)

self.labe9.pack(side=tk.LEFT,padx=5, pady=10)

self.entry9 = tk.Entry(self.fm5,font=self.ft1)

self.entry9.pack(side=tk.LEFT,padx=10, pady=10)

self.fm5.pack(side=tk.TOP,padx=5, pady=5)

self.fm6 = tk.Frame(self)

self.selectButton = tk.Button(self.fm6, text="重置", command=self.selectFile,font=self.ft1)

self.selectButton.pack(side=tk.LEFT,padx=10, pady=10)

self.startButton = tk.Button(self.fm6, text="计算", command=lambda :self.thread_it(self.startAction),font=self.ft1)

self.startButton.pack(side=tk.LEFT,padx=10, pady=10)

self.fm6.pack(side=tk.TOP,padx=5, pady=5)

self.title("我的计算器")

#窗口大小

width ,height= 600, 500

#窗口居中显示

self.geometry('%dx%d+%d+%d' % (width,height,(self.winfo_screenwidth() - width ) / 2, (self.winfo_screenheight() - height) / 2))

#窗口最大值

self.maxsize(600, 500)

#窗口最小值

self.minsize(300,200)

self.entry0.insert('end',0)

self.entry1.insert('end',0)

self.entry2.insert('end',0)

self.entry3.insert('end',0)

self.entry4.insert('end',0)

self.entry5.insert('end',0)

self.entry6.insert('end',0)

self.entry7.insert('end',0)

self.entry8.insert('end',150)

self.entry9.insert('end',50)

self.entry10.insert('end',1.25)

self.entry11.insert('end',0)

self.entry12.insert('end',0)

self.entry13.insert('end',0)

说实话这段代码写的很随意,变量命名很随意,因为很多都是重复的东西,这里大致讲一下,首先是创建定义一个类继承自tkinter,这就相当于整个对象就是一个窗体了,之后就在这个窗体中进行布局,这里我们采用的是pack布局,说白了就是浮动布局,就是按照一行或者一列依次排列组件,这里就是利用Frame组件生成了几行的布局,然后在每个Frame里排列我们的标签和输入框,其中包含的一些细节就是组件的字体,组件之间的间距之类,完成了布局这一步之后,我们需要给按钮绑定事件,就是点击按钮触发什么操作,这里我们有两个按钮。

其中重置按钮是为了清除输入的错误数据,绑定的事件就用command=self.selectFile这行代码来指定,这样就可以绑定到selectFile这个函数上,这个函数的代码如下所示

def selectFile(self):

self.entry1.delete(0, "end")

self.entry4.delete(0, "end")

self.entry6.delete(0, "end")

self.entry1.insert('end',0)

self.entry4.insert('end',0)

self.entry6.insert('end',0)

然后计算按钮是为了执行计算操作,这里我们采用了线程的方式进行绑定,也就是异步执行,不会卡住,避免因计算量过大导致程序假死的现象,绑定的方式是command=lambda :self.thread_it(self.startAction)

绑定的函数如下所示

def startAction(self):

A = self.entry1.get()

print(A)

B = self.entry2.get()

print(B)

C = self.entry3.get()

print(C)

D = self.entry4.get()

print(D)

E = self.entry5.get()

print(E)

F = self.entry6.get()

print(F)

G = self.entry7.get()

print(G)

H = self.entry8.get()

print(H)

I = self.entry9.get()

print(I)

J = self.entry10.get()

print(J)

result = ((float(A)*float(B)*float(C))+(float(D)*float(E))+(float(F)*float(G))+(float(H)+float(I)))*float(J)

USDCNY,SGDCNY,JPYCNY = self.getRate()

USDCNY_result = result/USDCNY

SGDCNY_result = result/SGDCNY

JPYCNY_result = USDCNY_result*JPYCNY

self.entry0.delete(0, "end")

self.entry0.insert('end',str(round(result, 2)))

self.entry11.delete(0, "end")

self.entry11.insert('end',str(round(USDCNY_result, 2)))

self.entry12.delete(0, "end")

self.entry12.insert('end',str(round(SGDCNY_result, 2)))

self.entry13.delete(0, "end")

self.entry13.insert('end',str(round(JPYCNY_result, 2)))

@staticmethod

def thread_it(func, *args):

t = threading.Thread(target=func, args=args)

t.setDaemon(True)

t.start()

至此基本完成了,不过完成的软件是这样的,如下所示

微信图片_20200910151432_1599724134937.jpg初始版本

可以看到比较明显的差异在计算结果那块,因为后面和客户沟通了,他需要其他币种的计算结果,所以后面就增加了几种结果,这里就用到了爬虫技术去采集实时的汇率,这里直接奉上了代码,直接解析的接口数据,所以很简单

def getRate(self):

url = "http://webforex.hermes.hexun.com/forex/quotelist?code=FOREXUSDCNY,FOREXSGDCNY,FOREXUSDJPY&column=Code,Price"

req = urllib.request.Request(url)

f = urllib.request.urlopen(req)

html = f.read().decode("utf-8")

print(html)

s = re.findall("{.*}",str(html))[0]

sjson = json.loads(s)

USDCNY = sjson["Data"][0][0][1]/10000

print(USDCNY)

SGDCNY = sjson["Data"][0][1][1]/10000

print(SGDCNY)

JPYCNY = sjson["Data"][0][2][1]/10000

print(JPYCNY)

return USDCNY,SGDCNY,JPYCNY

至此,Python代码基本完成了,这里奉上完整的代码

微信图片_20200910151425_1599724700620.jpg

import tkinter as tk

from tkinter import filedialog

from tkinter import messagebox

import threading

import tkinter.font as tf

import re

import json

import urllib.request

class Application(tk.Tk):

def __init__(self):

super().__init__()

self.createUI()

def createUI(self):

self.ft = tf.Font(family='微软雅黑', size=18,weight=tf.BOLD)

self.ft1 = tf.Font(family='微软雅黑', size=12)

self.fm = tk.Frame(self)

self.label = tk.Label(self.fm,text="计算结果:",font=self.ft)

self.label.pack(side=tk.LEFT)

self.fm_new1 = tk.Frame(self.fm)

self.label0 = tk.Label(self.fm_new1,text="人民币:",font=self.ft1)

self.label0.pack(side=tk.LEFT)

self.entry0 = tk.Entry(self.fm_new1,font=self.ft1)

self.entry0.pack(side=tk.LEFT)

self.label11 = tk.Label(self.fm_new1,text="美元:",font=self.ft1)

self.label11.pack(side=tk.LEFT)

self.entry11 = tk.Entry(self.fm_new1,font=self.ft1)

self.entry11.pack(side=tk.LEFT)

self.fm_new1.pack(side=tk.TOP,padx=5, pady=10)

self.fm_new2 = tk.Frame(self.fm)

self.label12 = tk.Label(self.fm_new2,text="新加坡币:",font=self.ft1)

self.label12.pack(side=tk.LEFT)

self.entry12 = tk.Entry(self.fm_new2,font=self.ft1)

self.entry12.pack(side=tk.LEFT)

self.label13 = tk.Label(self.fm_new2,text="日元:",font=self.ft1)

self.label13.pack(side=tk.LEFT)

self.entry13 = tk.Entry(self.fm_new2,font=self.ft1)

self.entry13.pack(side=tk.LEFT)

self.fm_new2.pack(side=tk.TOP,padx=5, pady=10)

self.fm.pack(side=tk.TOP,padx=5, pady=10)

self.fm1 = tk.Frame(self)

self.label1 = tk.Label(self.fm1,text="金 重:",font=self.ft1)

self.label1.pack(side=tk.LEFT,padx=10, pady=10)

self.entry1 = tk.Entry(self.fm1,font=self.ft1)

self.entry1.pack(side=tk.LEFT,padx=5, pady=10)

self.label10 = tk.Label(self.fm1,text="浮动比率:",font=self.ft1)

self.label10.pack(side=tk.LEFT,padx=10, pady=10)

self.entry10 = tk.Entry(self.fm1,font=self.ft1)

self.entry10.pack(side=tk.LEFT,anchor=tk.W,padx=5, pady=10)

self.fm1.pack(side=tk.TOP,padx=5, pady=5)

self.fm2 = tk.Frame(self)

self.label2 = tk.Label(self.fm2,text="金 价:",font=self.ft1)

self.label2.pack(side=tk.LEFT,padx=10, pady=10)

self.entry2 = tk.Entry(self.fm2,font=self.ft1)

self.entry2.pack(side=tk.LEFT,padx=5, pady=10)

self.labe3 = tk.Label(self.fm2,text="14K/18K:",font=self.ft1)

self.labe3.pack(side=tk.LEFT,padx=10, pady=10)

self.entry3 = tk.Entry(self.fm2,font=self.ft1)

self.entry3.pack(side=tk.LEFT,padx=5, pady=10)

self.fm2.pack(side=tk.TOP,padx=5, pady=5)

self.fm3 = tk.Frame(self)

self.label4 = tk.Label(self.fm3,text="主石重:",font=self.ft1)

self.label4.pack(side=tk.LEFT,padx=10, pady=10)

self.entry4 = tk.Entry(self.fm3,font=self.ft1)

self.entry4.pack(side=tk.LEFT,padx=5, pady=10)

self.label5 = tk.Label(self.fm3,text="价 格:",font=self.ft1)

self.label5.pack(side=tk.LEFT,padx=10, pady=10)

self.entry5 = tk.Entry(self.fm3,font=self.ft1)

self.entry5.pack(side=tk.LEFT,padx=5, pady=10)

self.fm3.pack(side=tk.TOP,padx=5, pady=5)

self.fm4 = tk.Frame(self)

self.label6 = tk.Label(self.fm4,text="副石重:",font=self.ft1)

self.label6.pack(side=tk.LEFT,padx=10, pady=10)

self.entry6 = tk.Entry(self.fm4,font=self.ft1)

self.entry6.pack(side=tk.LEFT,padx=5, pady=10)

self.labe7 = tk.Label(self.fm4,text="价 格:",font=self.ft1)

self.labe7.pack(side=tk.LEFT,padx=10, pady=10)

self.entry7 = tk.Entry(self.fm4,font=self.ft1)

self.entry7.pack(side=tk.LEFT,padx=5, pady=10)

self.fm4.pack(side=tk.TOP,padx=5, pady=5)

self.fm5 = tk.Frame(self)

self.label8 = tk.Label(self.fm5,text="工费:",font=self.ft1)

self.label8.pack(side=tk.LEFT,padx=10, pady=10)

self.entry8 = tk.Entry(self.fm5,font=self.ft1)

self.entry8.pack(side=tk.LEFT,padx=5, pady=10)

self.labe9 = tk.Label(self.fm5,text="设计费:",font=self.ft1)

self.labe9.pack(side=tk.LEFT,padx=5, pady=10)

self.entry9 = tk.Entry(self.fm5,font=self.ft1)

self.entry9.pack(side=tk.LEFT,padx=10, pady=10)

self.fm5.pack(side=tk.TOP,padx=5, pady=5)

self.fm6 = tk.Frame(self)

self.selectButton = tk.Button(self.fm6, text="重置", command=self.selectFile,font=self.ft1)

self.selectButton.pack(side=tk.LEFT,padx=10, pady=10)

self.startButton = tk.Button(self.fm6, text="计算", command=lambda :self.thread_it(self.startAction),font=self.ft1)

self.startButton.pack(side=tk.LEFT,padx=10, pady=10)

self.fm6.pack(side=tk.TOP,padx=5, pady=5)

self.title("我的计算器")

#窗口大小

width ,height= 600, 500

#窗口居中显示

self.geometry('%dx%d+%d+%d' % (width,height,(self.winfo_screenwidth() - width ) / 2, (self.winfo_screenheight() - height) / 2))

#窗口最大值

self.maxsize(600, 500)

#窗口最小值

self.minsize(300,200)

self.entry0.insert('end',0)

self.entry1.insert('end',0)

self.entry2.insert('end',0)

self.entry3.insert('end',0)

self.entry4.insert('end',0)

self.entry5.insert('end',0)

self.entry6.insert('end',0)

self.entry7.insert('end',0)

self.entry8.insert('end',150)

self.entry9.insert('end',50)

self.entry10.insert('end',1.25)

self.entry11.insert('end',0)

self.entry12.insert('end',0)

self.entry13.insert('end',0)

def selectFile(self):

self.entry1.delete(0, "end")

self.entry4.delete(0, "end")

self.entry6.delete(0, "end")

self.entry1.insert('end',0)

self.entry4.insert('end',0)

self.entry6.insert('end',0)

def startAction(self):

A = self.entry1.get()

print(A)

B = self.entry2.get()

print(B)

C = self.entry3.get()

print(C)

D = self.entry4.get()

print(D)

E = self.entry5.get()

print(E)

F = self.entry6.get()

print(F)

G = self.entry7.get()

print(G)

H = self.entry8.get()

print(H)

I = self.entry9.get()

print(I)

J = self.entry10.get()

print(J)

result = ((float(A)*float(B)*float(C))+(float(D)*float(E))+(float(F)*float(G))+(float(H)+float(I)))*float(J)

USDCNY,SGDCNY,JPYCNY = self.getRate()

USDCNY_result = result/USDCNY

SGDCNY_result = result/SGDCNY

JPYCNY_result = USDCNY_result*JPYCNY

self.entry0.delete(0, "end")

self.entry0.insert('end',str(round(result, 2)))

self.entry11.delete(0, "end")

self.entry11.insert('end',str(round(USDCNY_result, 2)))

self.entry12.delete(0, "end")

self.entry12.insert('end',str(round(SGDCNY_result, 2)))

self.entry13.delete(0, "end")

self.entry13.insert('end',str(round(JPYCNY_result, 2)))

@staticmethod

def thread_it(func, *args):

t = threading.Thread(target=func, args=args)

t.setDaemon(True)

t.start()

def getRate(self):

url = "http://webforex.hermes.hexun.com/forex/quotelist?code=FOREXUSDCNY,FOREXSGDCNY,FOREXUSDJPY&column=Code,Price"

req = urllib.request.Request(url)

f = urllib.request.urlopen(req)

html = f.read().decode("utf-8")

print(html)

s = re.findall("{.*}",str(html))[0]

sjson = json.loads(s)

USDCNY = sjson["Data"][0][0][1]/10000

print(USDCNY)

SGDCNY = sjson["Data"][0][1][1]/10000

print(SGDCNY)

JPYCNY = sjson["Data"][0][2][1]/10000

print(JPYCNY)

return USDCNY,SGDCNY,JPYCNY

app = Application()

app.mainloop()

# root.mainloop()

但是到这一步,还差一点点,因为我们的目的是生成一个exe软件,可以给没有安装Python环境的人使用,所以我们要用到Python的软件打包工具,这里我们使用的是pyinstaller,使用起来也很方便,直接用命令行进入python文件所在的文件夹,执行pyinstaller -F app.py --noconsole 即可,这里的app.py指代的是你们需要打包的python文件名,--noconsole是指打包成的exe文件运行时不显示控制台黑窗口。执行完成即可在同级目录下的dist文件中找到你们打包好的exe文件,至此,本文结束。

微信图片_20200910151425_1599722386758.jpg最终样式

本文首发于https://www.bizhibihui.com/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值