PyQt是基于跨平台的图形界面C++开发工具Qt加Python包装的一个GPL软件(GPL是GNU General Public License的缩写,是GNU通用公共授权非正式的中文翻译),Qt基于Qt Designer提供了图形设计界面,通过绘制的图形界面使用PyUIC可以将图形界面转成Python代码文件(具体步骤请参考《第15.6节 PyQt5安装与配置》),这样图形界面设计和处理逻辑分离,可以快速实现应用。

本文解释的计算器由Qt Designer完成界面设计,并将鼠标点击事件与槽函数关联以响应界面输入,最后使用Python动态编译的eval函数实现表达式结果的计算,除了图形界面转换的代码外,其他处理代码只有36行,但计算器的功能还比较齐全。详细步骤如下:

一、设计计算器界面

在Qt Designer中设计计算器的图形界面,如下:

界面文件保存到Ui_Calculator.ui文件中。

二、定义按键与响应函数的关联

在Qt Designer中通过F4进入事件与槽函数的编辑界面,将按键与槽函数建立映射关系,以使得按键后调用对应槽函数进行响应,本次在主程序中设计了三个槽函数,分别为:

1、CalObjPressed响应所有数字、括号、计算符的鼠标点击;

2、ClearInput响应Clear按键的鼠标点击;

3、ExecuteCalculate:响应等号按键的鼠标点击。

三、将UI转换成Py代码

调用《第15.6节 PyQt5安装与配置》介绍的PyUIC,将UI图形界面代码转换成py代码(这部分不含在36行代码内)。如图:

转换后的文件为Ui_Calculator.py。

四、建立主程序calculator.py

在PyCharm中新建工程calculator,同时新建一个工程名同名的calculator.py作为应用主程序。在主程序中实现如下内容:

1、导入PyQt相关库和sys库

import sys

from PyQt5 import QtWidgets

from PyQt5.QtWidgets import QPushButton

2、导入Ui界面生成的py模块

from ui_Calculator import Ui_CaculatorWin

3、从Ui自动生成类派生出应用程序主窗口类w_Calculator并在构造函数中完成初始化

class w_Calculator(QtWidgets.QWidget, Ui_CaculatorWin):

def __init__(self):

super(w_Calculator, self).__init__()

self.setupUi(self)

self.expr = ''

self.resultfinished = False

注意:上面的构造函数前2行代码是标准代码,是所有Ui类派生类都要有的。后面初始化了两个实例变量,其中expr 保存输入表达式,resultfinished 表示表达式计算完成。

4、在w_Calculator实习三个槽函数代码

1>、CalObjPressed

该函数响应等号按键,当按下等号键时,对显示界面的表达式调用动态编译函数eval进行计算,代码如下:

def CalObjPressed(self):

if self.resultfinished:self.ClearInput()

pButton = self.sender()

char = pButton.text()

self.CalculatorDisplay.insertPlainText(char)

self.expr += char

2>、ClearInput(self)

该函数响应界面上的Clear按键,清除输入的表达式,代码如下:

def ClearInput(self):

self.CalculatorDisplay.clear()

self.expr = ''

self.resultfinished = False

3>ExecuteCalculate

响应等号按键进行表达式计算,代码如下:

def ExecuteCalculate(self):

self.CalculatorDisplay.append("=")

globalArea = {}

try: result = eval(self.expr, globalArea)

except Exception as e:

self.CalculatorDisplay.append(f"计算结果错误,错误原因:\n{e}")

else: self.CalculatorDisplay.append(str(result))

self.resultfinished = True

5、完成主程序的应用代码

if __name__ == '__main__':

app = QtWidgets.QApplication(sys.argv)

# mainwin = MediaPlayerWin()

# mainwin.show()

W = w_Calculator()

W.show()

sys.exit(app.exec_())

这样一个完整的计算器程序就完成了,真正需要自己完成的代码就36行。

下面是运行效果截图:

附件1、完整主程序代码

import sys

from PyQt5 import QtWidgets

from PyQt5.QtWidgets import QPushButton

from ui_Calculator import Ui_CaculatorWin

class w_Calculator(QtWidgets.QWidget, Ui_CaculatorWin):

def __init__(self):

super(w_Calculator, self).__init__()

self.setupUi(self)

self.expr = ''

self.resultfinished = False

def CalObjPressed(self):

if self.resultfinished:self.ClearInput()

pButton = self.sender()

char = pButton.text()

self.CalculatorDisplay.insertPlainText(char)

self.expr += char

def ExecuteCalculate(self):

self.CalculatorDisplay.append("=")

globalArea = {}

try: result = eval(self.expr, globalArea)

except Exception as e:

self.CalculatorDisplay.append(f"计算结果错误,错误原因:\n{e}")

else: self.CalculatorDisplay.append(str(result))

self.resultfinished = True

def ClearInput(self):

self.CalculatorDisplay.clear()

self.expr = ''

self.resultfinished = False

if __name__ == '__main__':

app = QtWidgets.QApplication(sys.argv)

# mainwin = MediaPlayerWin()

# mainwin.show()

W = w_Calculator()

W.show()

sys.exit(app.exec_())

2、UI文件ui_Calculator.ui的内容

<?xml version="1.0" encoding="UTF-8"?>

CaculatorWin

0

0

339

314

计算器

C:/Users/jwp/资源/cal.jpgC:/Users/jwp/资源/cal.jpg

10

140

320

170

.

*

0

/

(

5

%

3

+

1

9

8

)

6

4

2

-

7

=

Clear

10

10

321

121

pushButton_Add

clicked()

CaculatorWin

CalObjPressed()

55

160

3

113

pushButton_Minus

clicked()

CaculatorWin

CalObjPressed()

115

159

3

139

pushButton_Multiply

clicked()

CaculatorWin

CalObjPressed()

204

156

336

128

pushButton_div

clicked()

CaculatorWin

CalObjPressed()

277

155

336

98

pushButton1

clicked()

CaculatorWin

CalObjPressed()

72

189

336

157

pushButton2

clicked()

CaculatorWin

CalObjPressed()

137

187

336

163

pushButton3

clicked()

CaculatorWin

CalObjPressed()

222

184

336

84

pushButton_dot

clicked()

CaculatorWin

CalObjPressed()

301

184

336

57

pushButton4

clicked()

CaculatorWin

CalObjPressed()

38

219

336

40

pushButton5

clicked()

CaculatorWin

CalObjPressed()

110

221

336

29

pushButton6

clicked()

CaculatorWin

CalObjPressed()

194

221

336

22

pushButton_mod

clicked()

CaculatorWin

CalObjPressed()

269

223

336

8

pushButton7

clicked()

CaculatorWin

CalObjPressed()

60

255

336

192

pushButton8

clicked()

CaculatorWin

CalObjPressed()

129

252

336

219

pushButton9

clicked()

CaculatorWin

CalObjPressed()

226

252

336

244

pushButton0

clicked()

CaculatorWin

CalObjPressed()

37

287

29

313

pushButton_leftbrackets

clicked()

CaculatorWin

CalObjPressed()

104

289

98

313

pushButton_rightbrackets

clicked()

CaculatorWin

CalObjPressed()

194

292

190

313

pushButton_Cal

clicked()

CaculatorWin

ExecuteCalculate()

279

288

277

313

pushButton_Clear

clicked()

CaculatorWin

ClearInput()

306

257

336

304

digitPressed()

digitPressed(digit)

CalObjPressed()

ExecuteCalculate()

ClearInput()

附件3、Ui转换的ui_Calculator.py文件内容

# -*- coding: utf-8 -*-

# Form implementation generated from reading ui file 'ui_Calculator.ui'

#

# Created by: PyQt5 UI code generator 5.13.0

#

# WARNING! All changes made in this file will be lost!

from PyQt5 import QtCore, QtGui, QtWidgets

class Ui_CaculatorWin(object):

def setupUi(self, CaculatorWin):

CaculatorWin.setObjectName("CaculatorWin")

CaculatorWin.resize(339, 314)

icon = QtGui.QIcon()

icon.addPixmap(QtGui.QPixmap("C:/Users/jwp/资源/cal.jpg"), QtGui.QIcon.Normal, QtGui.QIcon.Off)

CaculatorWin.setWindowIcon(icon)

self.gridLayoutWidget = QtWidgets.QWidget(CaculatorWin)

self.gridLayoutWidget.setGeometry(QtCore.QRect(10, 140, 320, 170))

self.gridLayoutWidget.setObjectName("gridLayoutWidget")

self.gridLayout_2 = QtWidgets.QGridLayout(self.gridLayoutWidget)

self.gridLayout_2.setContentsMargins(0, 0, 0, 0)

self.gridLayout_2.setObjectName("gridLayout_2")

self.pushButton_dot = QtWidgets.QPushButton(self.gridLayoutWidget)

self.pushButton_dot.setObjectName("pushButton_dot")

self.gridLayout_2.addWidget(self.pushButton_dot, 2, 3, 1, 1)

self.pushButton_Multiply = QtWidgets.QPushButton(self.gridLayoutWidget)

self.pushButton_Multiply.setObjectName("pushButton_Multiply")

self.gridLayout_2.addWidget(self.pushButton_Multiply, 0, 2, 1, 1)

self.pushButton0 = QtWidgets.QPushButton(self.gridLayoutWidget)

self.pushButton0.setObjectName("pushButton0")

self.gridLayout_2.addWidget(self.pushButton0, 6, 0, 1, 1)

self.pushButton_div = QtWidgets.QPushButton(self.gridLayoutWidget)

self.pushButton_div.setObjectName("pushButton_div")

self.gridLayout_2.addWidget(self.pushButton_div, 0, 3, 1, 1)

self.pushButton_leftbrackets = QtWidgets.QPushButton(self.gridLayoutWidget)

self.pushButton_leftbrackets.setObjectName("pushButton_leftbrackets")

self.gridLayout_2.addWidget(self.pushButton_leftbrackets, 6, 1, 1, 1)

self.pushButton5 = QtWidgets.QPushButton(self.gridLayoutWidget)

self.pushButton5.setObjectName("pushButton5")

self.gridLayout_2.addWidget(self.pushButton5, 3, 1, 1, 1)

self.pushButton_mod = QtWidgets.QPushButton(self.gridLayoutWidget)

self.pushButton_mod.setObjectName("pushButton_mod")

self.gridLayout_2.addWidget(self.pushButton_mod, 3, 3, 1, 1)

self.pushButton3 = QtWidgets.QPushButton(self.gridLayoutWidget)

self.pushButton3.setObjectName("pushButton3")

self.gridLayout_2.addWidget(self.pushButton3, 2, 2, 1, 1)

self.pushButton_Add = QtWidgets.QPushButton(self.gridLayoutWidget)

self.pushButton_Add.setObjectName("pushButton_Add")

self.gridLayout_2.addWidget(self.pushButton_Add, 0, 0, 1, 1)

self.pushButton1 = QtWidgets.QPushButton(self.gridLayoutWidget)

self.pushButton1.setObjectName("pushButton1")

self.gridLayout_2.addWidget(self.pushButton1, 2, 0, 1, 1)

self.pushButton9 = QtWidgets.QPushButton(self.gridLayoutWidget)

self.pushButton9.setObjectName("pushButton9")

self.gridLayout_2.addWidget(self.pushButton9, 4, 2, 1, 1)

self.pushButton8 = QtWidgets.QPushButton(self.gridLayoutWidget)

self.pushButton8.setObjectName("pushButton8")

self.gridLayout_2.addWidget(self.pushButton8, 4, 1, 1, 1)

self.pushButton_rightbrackets = QtWidgets.QPushButton(self.gridLayoutWidget)

self.pushButton_rightbrackets.setObjectName("pushButton_rightbrackets")

self.gridLayout_2.addWidget(self.pushButton_rightbrackets, 6, 2, 1, 1)

self.pushButton6 = QtWidgets.QPushButton(self.gridLayoutWidget)

self.pushButton6.setObjectName("pushButton6")

self.gridLayout_2.addWidget(self.pushButton6, 3, 2, 1, 1)

self.pushButton4 = QtWidgets.QPushButton(self.gridLayoutWidget)

self.pushButton4.setObjectName("pushButton4")

self.gridLayout_2.addWidget(self.pushButton4, 3, 0, 1, 1)

self.pushButton2 = QtWidgets.QPushButton(self.gridLayoutWidget)

self.pushButton2.setObjectName("pushButton2")

self.gridLayout_2.addWidget(self.pushButton2, 2, 1, 1, 1)

self.pushButton_Minus = QtWidgets.QPushButton(self.gridLayoutWidget)

self.pushButton_Minus.setObjectName("pushButton_Minus")

self.gridLayout_2.addWidget(self.pushButton_Minus, 0, 1, 1, 1)

self.pushButton7 = QtWidgets.QPushButton(self.gridLayoutWidget)

self.pushButton7.setObjectName("pushButton7")

self.gridLayout_2.addWidget(self.pushButton7, 4, 0, 1, 1)

self.pushButton_Cal = QtWidgets.QPushButton(self.gridLayoutWidget)

self.pushButton_Cal.setObjectName("pushButton_Cal")

self.gridLayout_2.addWidget(self.pushButton_Cal, 6, 3, 1, 1)

self.pushButton_Clear = QtWidgets.QPushButton(self.gridLayoutWidget)

self.pushButton_Clear.setObjectName("pushButton_Clear")

self.gridLayout_2.addWidget(self.pushButton_Clear, 4, 3, 1, 1)

self.CalculatorDisplay = QtWidgets.QTextBrowser(CaculatorWin)

self.CalculatorDisplay.setGeometry(QtCore.QRect(10, 10, 321, 121))

self.CalculatorDisplay.setObjectName("CalculatorDisplay")

self.retranslateUi(CaculatorWin)

self.pushButton_Add.clicked.connect(CaculatorWin.CalObjPressed)

self.pushButton_Minus.clicked.connect(CaculatorWin.CalObjPressed)

self.pushButton_Multiply.clicked.connect(CaculatorWin.CalObjPressed)

self.pushButton_div.clicked.connect(CaculatorWin.CalObjPressed)

self.pushButton1.clicked.connect(CaculatorWin.CalObjPressed)

self.pushButton2.clicked.connect(CaculatorWin.CalObjPressed)

self.pushButton3.clicked.connect(CaculatorWin.CalObjPressed)

self.pushButton_dot.clicked.connect(CaculatorWin.CalObjPressed)

self.pushButton4.clicked.connect(CaculatorWin.CalObjPressed)

self.pushButton5.clicked.connect(CaculatorWin.CalObjPressed)

self.pushButton6.clicked.connect(CaculatorWin.CalObjPressed)

self.pushButton_mod.clicked.connect(CaculatorWin.CalObjPressed)

self.pushButton7.clicked.connect(CaculatorWin.CalObjPressed)

self.pushButton8.clicked.connect(CaculatorWin.CalObjPressed)

self.pushButton9.clicked.connect(CaculatorWin.CalObjPressed)

self.pushButton0.clicked.connect(CaculatorWin.CalObjPressed)

self.pushButton_leftbrackets.clicked.connect(CaculatorWin.CalObjPressed)

self.pushButton_rightbrackets.clicked.connect(CaculatorWin.CalObjPressed)

self.pushButton_Cal.clicked.connect(CaculatorWin.ExecuteCalculate)

self.pushButton_Clear.clicked.connect(CaculatorWin.ClearInput)

QtCore.QMetaObject.connectSlotsByName(CaculatorWin)

def retranslateUi(self, CaculatorWin):

_translate = QtCore.QCoreApplication.translate

CaculatorWin.setWindowTitle(_translate("CaculatorWin", "计算器"))

self.pushButton_dot.setText(_translate("CaculatorWin", "."))

self.pushButton_Multiply.setText(_translate("CaculatorWin", "*"))

self.pushButton0.setText(_translate("CaculatorWin", "0"))

self.pushButton_div.setText(_translate("CaculatorWin", "/"))

self.pushButton_leftbrackets.setText(_translate("CaculatorWin", "("))

self.pushButton5.setText(_translate("CaculatorWin", "5"))

self.pushButton_mod.setText(_translate("CaculatorWin", "%"))

self.pushButton3.setText(_translate("CaculatorWin", "3"))

self.pushButton_Add.setText(_translate("CaculatorWin", "+"))

self.pushButton1.setText(_translate("CaculatorWin", "1"))

self.pushButton9.setText(_translate("CaculatorWin", "9"))

self.pushButton8.setText(_translate("CaculatorWin", "8"))

self.pushButton_rightbrackets.setText(_translate("CaculatorWin", ")"))

self.pushButton6.setText(_translate("CaculatorWin", "6"))

self.pushButton4.setText(_translate("CaculatorWin", "4"))

self.pushButton2.setText(_translate("CaculatorWin", "2"))

self.pushButton_Minus.setText(_translate("CaculatorWin", "-"))

self.pushButton7.setText(_translate("CaculatorWin", "7"))

self.pushButton_Cal.setText(_translate("CaculatorWin", "="))

self.pushButton_Clear.setText(_translate("CaculatorWin", "Clear"))

python 动态编译代码_使用PyQt(Python+Qt)+动态编译36行代码实现的计算器相关推荐

  1. python黑色和浅黑色的代码_黑色格式化程序-忽略特定的多行代码 - python

    我想忽略black python formatter的特定多行代码.特别是,它用于np.array或格式化时难看的矩阵构造.以下是示例. np.array( [ [1, 0, 0, 0], [0, - ...

  2. 机器学习 文本分类 代码_无需担心机器学习-如何在少于10行代码中对文本进行分类

    机器学习 文本分类 代码 This article builds upon my previous two articles where I share some tips on how to get ...

  3. python -不敢表白,不好意思说出来,没关系,7行代码完成自动打印文字

    python -不敢表白,不好意思说出来,没关系,7行代码搞定自动打印文字 ​ 一.实现效果 我们先来看实现之后的效果: 二.代码实现 我们需要调用到控制台输出文字,于是需要引用到sys模块. imp ...

  4. python是脚本语言不需要编译器编译执行_都有Python了,还要什么编译器!

    编译的目的是将源码转化为机器可识别的可执行程序,在早期,每次编译都需要重新构建所有东西,后来人们意识到可以让编译器自动完成一些工作,从而提升编译效率. 但"编译器不过是用于代码生成的软机器, ...

  5. 网页爬虫python代码_《用python写网络爬虫》完整版+源码

    原标题:<用python写网络爬虫>完整版+源码 <用python写网络爬虫>完整版+附书源码 本书讲解了如何使用Python来编写网络爬虫程序,内容包括网络爬虫简介,从页面中 ...

  6. element ui 批量删除之后动态更新列表_气象编程 | Python高效批量绘图方法

    添加新云天气象主编微信或QQ:130188121,及时获取或发布气象升学.就业.会议.征稿及学术动态等信息!在数值预报后处理中经常需要批量出图,而基于matplotlib的图形渲染速度较慢,而提高出图 ...

  7. python绘制pr曲线图_如何利用Python制作可以动的动态图表。

    来源:机器之心 原文链接:https://towardsdatascience.com/learn-how-to-create-animated-graphs-in-python-fce780421a ...

  8. python打开文件切片_收藏 | 从Python安装到语法基础,小白都能懂的爬虫教程!(附代码)...

    来源:大数据 作者:罗攀 蒋仟 本文约5000字,建议阅读20分钟. 本文立足基础,讲解Python和PyCharm的安装,及Python最简单的语法基础和爬虫技术中所需的Python语法. 本文涉及 ...

  9. 一段有趣的python代码_你知道 Python 这五个有趣的彩蛋吗?

    当一门编程语言是开源的时候,往往会有产生一些搞笑和有趣的东西.通常,这意味着社区的贡献者会为该语言添加一些有趣和特别的彩蛋以及隐藏的特性(当然前提是不会增加在生产环境中使用的风险). Python 就 ...

最新文章

  1. 如果你没用过maven的install,你应该了解一下!maven中的install功能及用法。
  2. 为类定义后构造函数的最小示例,使用 boost::signals2::deconstruct 作为它的工厂函数
  3. 太可怕!儿童智能手表竟成偷窥器,315重锤个人隐私泄露
  4. 最安全的金笛JDMail邮件系统的安全防范技术介绍--2
  5. mysql命令行操作语句_MySQL常用命令行操作语句
  6. spring源码:扫描bean的原理
  7. SQL删除字段重复内容且保留唯一一条数据
  8. 拍乐云基于AV1的实时视频系统技术实践 | 2021 LiveVideoStackCon 演讲回顾
  9. elasticsearch(es)的安装-macOs
  10. raid5用户mbr还是gpt_对硬盘进行分区时,GPT和MBR有什么区别?
  11. android发现u盘自动安装apk,安卓自动识别U盘中APK文件并进行安装操作
  12. 电脑设备打印机驱动安装失败如何解决
  13. ppt将画好的箭头改为直线
  14. 【机器学习笔记】【随机森林】【回归器】【填充缺失值】
  15. Unity + SteamVR + VIVE Pro进行动作捕捉
  16. 基于GMapping的栅格地图的构建
  17. 转帖:BTree,B-Tree,B+Tree,B*Tree都是什么
  18. 【atoi函数的介绍以及模拟实现】
  19. 企业邮局在koomail里的设置方法
  20. 使用esp8266 wifi芯片和DFRduino开发板(Arduino也可以),向自己的服务器发送请求(尽可能详细的说明)

热门文章

  1. 分享一例脚本发版和tomcat重启脚本
  2. Docx4j 添加页码
  3. 高斯判别分析 Gaussian Discriminant Analysis
  4. Delphi 中的颜色常量及效果图
  5. java- ASM 字节码操控框架
  6. Web 服务编程,REST 与 SOAP
  7. ---Pcie基本概念普及(扫盲篇--巨适合新手)
  8. python array赋值_从踩坑学Python内部原理(5):执行时机的差异
  9. 【python教程入门学习】Python实现自动玩贪吃蛇程序
  10. 电脑练习打字软件_KeyBlaze Free Typing Tutor(打字练习软件)最新版下载_KeyBlaze Free Typing Tutor(打字练习软件)最新版本下载v4.02官方版...