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

一个简单的示例记录利用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》

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,254评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,875评论 3 387
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,682评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,896评论 1 285
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,015评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,152评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,208评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,962评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,388评论 1 304
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,700评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,867评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,551评论 4 335
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,186评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,901评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,142评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,689评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,757评论 2 351

推荐阅读更多精彩内容