一个简单的示例记录利用pyqt实现带界面的小工具的过程。
掌握PyQt基本的使用,可以便于制作团队内部效率小工具
-
pycharm pyqt环境配置
参考以下文章安装配置开发工作环境,安装pyqt5 以及 pyqt5-tools 以及 配置pycharm中外部工具 QtDesigner(用于绘图) 和 UIC工具(将绘图ui文件转换成源码文件)
https://blog.csdn.net/zjm12343/article/details/79707275
-
一个简单实例 - calc 24
-
简介
calc 24 是一个小时候玩的扑克游戏,任意抽出四张牌,利用基本运算加减乘除计算出24。
计算24基本实现过程:
- 从输入的四张牌值中穷举出所有的牌值集合,穷举出所有的运算符集合
- 根据两种集合计算每一种情况下的结果,确认是否能得到24
- 若存在24,最终输出计算出24时的运算步骤;否则输出 不能计算出24
-
UI界面
启动Qt Designer 绘制基本界面如下,包括基本的主窗口,一个标签,四个输入,一个按钮,一个输出利用UIC 将绘制保存的ui文件转换成python文件,注意转换出来的文件是一个含有所有界面子元素的ui元类(没有mainwindow,依赖于外部传入的mainwindow),并不能直接写main函数初始化加载该类使用
-
-
使用生成的ui类
class Calc24(QtWidgets.QMainWindow): def __init__(self): super().__init__() self.ui = Ui_MainWindow() self.ui.setupUi(self) self.ui.retranslateUi(self) self.ui.pushButton.clicked.connect(self.StartCalc) self.show() if __name__ == "__main__": app = QtWidgets.QApplication(sys.argv) mainWindow = Calc24() mainWindow.show() sys.exit(app.exec_())
UI绘制时,利用的时MainWindow来容纳界面元素,所以此处采用QMainWindow作为基类(类似的还有其他形式,如QDialog)
将生成的Ui_Mainwindow作为类的成员,并基于该类,调用Ui_Mainwindow的方法进行页面元素绘制显示
QT 信号槽绑定,按钮处理逻辑绑定为运算24过程
最终main函数中启动QApplication,加载该类
-
源码
-
ui文件生成的calc24.py
# -*- coding: utf-8 -*- # Form implementation generated from reading ui file 'calc24.ui' # # Created by: PyQt5 UI code generator 5.13.2 # # WARNING! All changes made in this file will be lost! from PyQt5 import QtCore, QtGui, QtWidgets class Ui_MainWindow(object): def setupUi(self, MainWindow): MainWindow.setObjectName("Calc 24") MainWindow.resize(420, 320) self.centralwidget = QtWidgets.QWidget(MainWindow) self.centralwidget.setObjectName("centralwidget") self.label = QtWidgets.QLabel(self.centralwidget) self.label.setEnabled(False) self.label.setGeometry(QtCore.QRect(30, 20, 321, 31)) self.label.setObjectName("label") self.lineEdit = QtWidgets.QLineEdit(self.centralwidget) self.lineEdit.setGeometry(QtCore.QRect(30, 60, 51, 51)) self.lineEdit.setObjectName("lineEdit") self.lineEdit_2 = QtWidgets.QLineEdit(self.centralwidget) self.lineEdit_2.setGeometry(QtCore.QRect(100, 60, 51, 51)) self.lineEdit_2.setObjectName("lineEdit_2") self.lineEdit_3 = QtWidgets.QLineEdit(self.centralwidget) self.lineEdit_3.setGeometry(QtCore.QRect(170, 60, 51, 51)) self.lineEdit_3.setObjectName("lineEdit_3") self.lineEdit_4 = QtWidgets.QLineEdit(self.centralwidget) self.lineEdit_4.setGeometry(QtCore.QRect(240, 60, 51, 51)) self.lineEdit_4.setObjectName("lineEdit_4") self.lineEdit_5 = QtWidgets.QLineEdit(self.centralwidget) self.lineEdit_5.setGeometry(QtCore.QRect(30, 230, 300, 41)) self.lineEdit_5.setObjectName("lineEdit_5") self.lineEdit_5.setReadOnly(True) self.pushButton = QtWidgets.QPushButton(self.centralwidget) self.pushButton.setGeometry(QtCore.QRect(30, 140, 101, 61)) self.pushButton.setObjectName("pushButton") MainWindow.setCentralWidget(self.centralwidget) self.retranslateUi(MainWindow) QtCore.QMetaObject.connectSlotsByName(MainWindow) def retranslateUi(self, MainWindow): _translate = QtCore.QCoreApplication.translate MainWindow.setWindowTitle(_translate("MainWindow", "Calc 24")) self.label.setText(_translate("MainWindow", "<html><head/><body><p><span style=\" font-size:14pt;\">输入4张扑克牌值,计算24</span></p></body></html>")) self.pushButton.setText(_translate("MainWindow", "Calc 24"))
-
mainwindow 以及 calc24 逻辑 处理实现文件 calc24proc.py
import copy import sys from calc24 import * def operate(a, b, op): ret = 0 if op == "+": ret = a + b elif op == "-": ret = a - b elif op == "*": ret = a * b elif op == "/" and b != 0 and a % b == 0: ret = a / b return ret def calc24(poks): operators = ["+", "-", "*", "/"] operations = set() for i in operators: for j in operators: for k in operators: operations.add((i, j, k)) pokset = set() for a in poks: b_poks = copy.deepcopy(list(poks)) b_poks.remove(a) for b in b_poks: c_poks = copy.deepcopy(b_poks) c_poks.remove(b) for c in c_poks: d_poks = copy.deepcopy(c_poks) d_poks.remove(c) for d in d_poks: pokset.add((int(a), int(b), int(c), int(d))) for poklist in pokset: for oplist in operations: ret = operate(poklist[0], poklist[1], oplist[0]) if ret == 0: continue else: ret = operate(ret, poklist[2], oplist[1]) if ret == 0: continue else: ret = operate(ret, poklist[3], oplist[2]) if ret != 24: continue else: return "%d %s %d %s %d %s %d" % ( poklist[0], oplist[0], poklist[1], oplist[1], poklist[2], oplist[2], poklist[3]) return "无法计算出24" class Calc24(QtWidgets.QMainWindow): def __init__(self): super().__init__() self.ui = Ui_MainWindow() self.ui.setupUi(self) self.ui.retranslateUi(self) self.ui.pushButton.clicked.connect(self.StartCalc) self.show() def StartCalc(self): pok1 = self.ui.lineEdit.text() pok2 = self.ui.lineEdit_2.text() pok3 = self.ui.lineEdit_3.text() pok4 = self.ui.lineEdit_4.text() poks = (pok1, pok2, pok3, pok4) self.ui.lineEdit.setEnabled(False) self.ui.lineEdit_2.setEnabled(False) self.ui.lineEdit_3.setEnabled(False) self.ui.lineEdit_4.setEnabled(False) if '' in poks: self.ui.lineEdit_5.setText("请输入4张扑克牌值") else: retText = calc24(poks) self.ui.lineEdit_5.setText(retText) self.ui.lineEdit.setEnabled(True) self.ui.lineEdit_2.setEnabled(True) self.ui.lineEdit_3.setEnabled(True) self.ui.lineEdit_4.setEnabled(True) if __name__ == "__main__": app = QtWidgets.QApplication(sys.argv) mainWindow = Calc24() mainWindow.show() sys.exit(app.exec_())
-
-
其他
-
最终的界面显示结果很可能不与在Qt Designer中绘制时那样齐整一直,需自行调整界面中元素布局位置
self.label.setGeometry(QtCore.QRect(30, 20, 321, 31))
元素在界面中几何位置QRect中四个参数含义 前面两个表示元素左上角平面坐标,后面两个表示横向长和纵向宽
参考书籍 《Rapid GUI programming with Python and Qt the definitive guide to PyQt programmig》
-