美文网首页
PyQt使用简单Demo过程示例记录

PyQt使用简单Demo过程示例记录

作者: 打出了枫采 | 来源:发表于2020-03-24 20:11 被阅读0次

    一个简单的示例记录利用pyqt实现带界面的小工具的过程。
    掌握PyQt基本的使用,可以便于制作团队内部效率小工具

    • pycharm pyqt环境配置

      参考以下文章安装配置开发工作环境,安装pyqt5 以及 pyqt5-tools 以及 配置pycharm中外部工具 QtDesigner(用于绘图) 和 UIC工具(将绘图ui文件转换成源码文件)
      https://blog.csdn.net/zjm12343/article/details/79707275
    • 一个简单实例 - calc 24

      1. 简介

        calc 24 是一个小时候玩的扑克游戏,任意抽出四张牌,利用基本运算加减乘除计算出24。

        计算24基本实现过程:

        • 从输入的四张牌值中穷举出所有的牌值集合,穷举出所有的运算符集合
        • 根据两种集合计算每一种情况下的结果,确认是否能得到24
        • 若存在24,最终输出计算出24时的运算步骤;否则输出 不能计算出24
      2. UI界面
        启动Qt Designer 绘制基本界面如下,包括基本的主窗口,一个标签,四个输入,一个按钮,一个输出 image.png

        利用UIC 将绘制保存的ui文件转换成python文件,注意转换出来的文件是一个含有所有界面子元素的ui元类(没有mainwindow,依赖于外部传入的mainwindow),并不能直接写main函数初始化加载该类使用

        image.png
    1. 使用生成的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,加载该类

    2. 源码
      • 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_())
        
        
    最终运行结果示例: image.png
    1. 其他
      • 最终的界面显示结果很可能不与在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》

    相关文章

      网友评论

          本文标题:PyQt使用简单Demo过程示例记录

          本文链接:https://www.haomeiwen.com/subject/ueuayhtx.html