利用Python编写一个行业专用的小计算器 |
您所在的位置:网站首页 › 怎么制作简单的编程软件 › 利用Python编写一个行业专用的小计算器 |
前言:本文讲述的是如何利用python编程制作一个适用于指定行业的计算器,方便计算结果,涵盖的知识点由Python编写GUI界面程序,利用爬虫采集实时的汇率数据,将Python文件打包成可以单独运行的exe文件。 首先,分析我们的需求,编写一个适用于指定行业的计算器,这里我们用到的计算公式很简单,就是淘宝提供的金石定价公式,如下图所示 淘宝定价计算器
这里可以看到这个计算公式还是蛮简单的,对于Python来说也就是一行代码的事,那么我们就开始着手写代码,首先搭建我们的页面布局,这里我们采用的是tkinter,这个框架在画GUI方面还是很简单方便的,首先给大家展示下我的最终布局,如下图所示 最终样式 其实也不是很好看,不过我已经尽我所能去美化了,其实功能很简单,就是几个输入框,两个按钮,点击计算按钮,获取输入框中的值,通过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()至此基本完成了,不过完成的软件是这样的,如下所示 初始版本 可以看到比较明显的差异在计算结果那块,因为后面和客户沟通了,他需要其他币种的计算结果,所以后面就增加了几种结果,这里就用到了爬虫技术去采集实时的汇率,这里直接奉上了代码,直接解析的接口数据,所以很简单 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代码基本完成了,这里奉上完整的代码 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文件,至此,本文结束。 最终样式 本文首发于https://www.bizhibihui.com/ |
今日新闻 |
推荐新闻 |
CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3 |