PyQt5简单应用--小试牛刀

最近考虑换工作,面了一家居然是用pyqt5来做桌面应用开发的公司,QT通常都是C++去做的,用python对于一个做python全栈开发的我,这毋庸置疑是一个挑战,毕竟没有接触过QT,面了几次了,还要给我两天时间学习一下pyqt,在这里我就把我这两天的学习成果总结一下。

PyQt5 简介

本教程的目的是带领你入门PyQt5。教程内所有代码都在Linux上测试通过。PyQt4 教程是PyQt4的教程,PyQt4是一个Python(同时支持2和3)版的Qt库。

关于 PyQt5

PyQt5 是Digia的一套Qt5应用框架与python的结合,同时支持2.x和3.x。本教程使用的是3.x。Qt库由Riverbank Computing开发,是最强大的GUI库之一 ,官方网站:www.riverbankcomputing.co.uk/news。

PyQt5是由一系列Python模块组成。超过620个类,6000函数和方法。能在诸如Unix、Windows和Mac OS等主流操作系统上运行。PyQt5有两种证书,GPL和商业证书。

PyQt5类分为很多模块,主要模块有:

  • QtCore 包含了核心的非GUI的功能。主要和时间、文件与文件夹、各种数据、流、URLs、mime类文件、进程与线程一起使用。
  • QtGui 包含了窗口系统、事件处理、2D图像、基本绘画、字体和文字类。
  • QtWidgets
  • QtMultimedia
  • QtBluetooth
  • QtNetwork
  • QtPositioning
  • Enginio
  • QtWebSockets
  • QtWebKit
  • QtWebKitWidgets
  • QtXml
  • QtSvg
  • QtSql
  • QtTest

QtWidgets类包含了一系列创建桌面应用的UI元素。 QtMultimedia包含了处理多媒体的内容和调用摄像头API的类。 QtBluetooth模块包含了查找和连接蓝牙的类。 QtNetwork包含了网络编程的类,这些工具能让TCP/IP和UDP开发变得更加方便和可靠。 QtPositioning包含了定位的类,可以使用卫星、WiFi甚至文本。 Engine包含了通过客户端进入和管理Qt Cloud的类。 QtWebSockets包含了WebSocket协议的类。 QtWebKit包含了一个基WebKit2的web浏览器。 QtWebKitWidgets包含了基于QtWidgets的WebKit1的类。 QtXml包含了处理xml的类,提供了SAX和DOM API的工具。 QtSvg提供了显示SVG内容的类,Scalable Vector Graphics (SVG)是一种是一种基于可扩展标记语言(XML),用于描述二维矢量图形的图形格式(这句话来自于维基百科)。 QtSql提供了处理数据库的工具。 QtTest提供了测试PyQt5应用的工具。

QT环境配置

安装pyqt5、pyqt5-tools
pip install pyqt5
pip install pyqt5-tools

pycharm配置QT开发环境,主要包括Qt Designer,Pyuic, Pyrcc的配置,具体配置参考:https://blog.csdn.net/zrt8019/article/details/102418472

Qt Designer用于配置QT拖拽式界面设计,生成*.ui文件(本质上是一个xml文件);
Pyuic用于将生成的ui文件转换为python文件。

PyQt5入门学习资料:https://maicss.gitbooks.io/pyqt5/content/%E4%BB%8B%E7%BB%8D.html
PyQt5中文学习github地址:https://github.com/maicss/PyQt5-Chinese-tutorial

以下便是我基于pyqt5写的一个比较low的计算器:

主程序代码:
# -*- coding: utf-8 -*- 
# @Time : 2019/12/4 9:20 
# @Author :  
# @Site :  
# @File : main.py 
# @Software: PyCharm
import sys
from PyQt5 import QtCore

from PyQt5.QtCore import pyqtSignal, QObject
from PyQt5.QtGui import QIcon
from PyQt5.QtWidgets import QMainWindow, QApplication, QMessageBox

from mycalc import Ui_MainWindow


class CalcSignal(QObject):
    """
        自定义信号
    """
    signal_number = pyqtSignal(int)
    signal_method = pyqtSignal(str)
    signal_clear = pyqtSignal(int)
    signal_result = pyqtSignal()


class MainWindow(QMainWindow):

    def __init__(self):
        super(MainWindow, self).__init__()
        self.first_number = 0
        self.method = ''
        self.sec_number = 0
        self.is_get_result = 0
        self.mysignal = CalcSignal()
        # 绑定信号和槽
        self.mysignal.signal_number.connect(self.deal_number)
        self.mysignal.signal_method.connect(self.deal_method)
        self.mysignal.signal_clear.connect(self.deal_clear)
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)
        self.ui.lineEdit.setText('0')
        self.ui.lineEdit.setFocusPolicy(QtCore.Qt.NoFocus)
        self._init_button()

    def _init_button(self):
        """
        初始化所有的button click事件绑定对应的回调函数
        :return:
        """
        # 设置按钮
        self.ui.zero.clicked.connect(self.num_click)
        self.ui.one.clicked.connect(self.num_click)
        self.ui.two.clicked.connect(self.num_click)
        self.ui.three.clicked.connect(self.num_click)
        self.ui.four.clicked.connect(self.num_click)
        self.ui.five.clicked.connect(self.num_click)
        self.ui.six.clicked.connect(self.num_click)
        self.ui.seven.clicked.connect(self.num_click)
        self.ui.eight.clicked.connect(self.num_click)
        self.ui.nine.clicked.connect(self.num_click)

        self.ui.point.clicked.connect(self.deal_point)
        # 计算方法
        self.ui.add.clicked.connect(self.method_click)
        self.ui.sub.clicked.connect(self.method_click)
        self.ui.multi.clicked.connect(self.method_click)
        self.ui.division.clicked.connect(self.method_click)
        # 结果
        self.ui.result.clicked.connect(self.deal_result)
        # 清空按钮
        self.ui.clear_all.clicked.connect(self.clear_click)
        self.ui.myclear.clicked.connect(self.clear_click)

    def num_click(self):
        """触发数字按钮信号"""
        number = self.sender()
        self.mysignal.signal_number.emit(int(number.text()))

    def method_click(self):
        """触发运算符信号"""
        method = self.sender().text()
        self.mysignal.signal_method.emit(method)

    def clear_click(self):
        """触发清空信号"""
        clear = self.sender().text()
        if clear == 'C':
            self.mysignal.signal_clear.emit(1)
        else:
            self.mysignal.signal_clear.emit(0)

    def deal_number(self, val):
        """
        点击数字回调函数
        :param val:
        :return:
        """
        temp = self.ui.lineEdit.text()
        if temp in ['+', '-', '*', '/']:
            self.ui.lineEdit.setText(str(val))
        else:
            if temp.find('.') == -1:
                temp = self.ui.lineEdit.text().lstrip('0')
            self.ui.lineEdit.setText(temp + str(val))

    def deal_method(self, val):
        """
        加减乘除运算处理回调
        :param val:
        :return:
        """
        temp = self.ui.lineEdit.text()
        if self.method == '':
            if temp not in ['+', '-', '*', '/']:
                self.first_number = eval(temp)
        else:
            if temp not in ['+', '-', '*', '/']:
                self.sec_number = eval(self.ui.lineEdit.text())
                if self.method == '+':
                    self.first_number = self.first_number + self.sec_number
                elif self.method == '-':
                    self.first_number = self.first_number - self.sec_number
                elif self.method == '*':
                    self.first_number = self.first_number * self.sec_number
                else:
                    if self.sec_number != 0:
                        self.first_number = self.first_number / self.sec_number
                self.sec_number = 0
        self.method = val
        self.ui.lineEdit.setText(val)

    def deal_clear(self, val):
        """
        两种清空回调函数
        :param val:
        :return:
        """
        if val:
            self.first_number = 0
            self.method = ''
            self.sec_number = 0
            self.ui.lineEdit.setText('0')
        else:
            if self.sec_number == 0 and self.method == '' and self.first_number != 0:
                self.first_number = 0
                self.ui.lineEdit.setText('0')
            elif self.sec_number == 0 and self.method != '':
                self.ui.lineEdit.setText('0')
            elif self.sec_number != 0:
                self.sec_number = 0
                if self.method != '':
                    self.ui.lineEdit.setText(self.method)
                else:
                    self.ui.lineEdit.setText('0')
            else:
                self.ui.lineEdit.setText('0')

    def deal_result(self):
        """
        处理等号事件
        :return:
        """
        temp = self.ui.lineEdit.text()
        if temp in ['+', '-', '*', '/']:
            self.method = ''
            self.sec_number = 0
            self.ui.lineEdit.setText(str(self.first_number))
            self.first_number = 0
            return
        self.sec_number = eval(temp)
        if self.method == '':
            result = eval(temp)
        elif self.method == '+':
            result = self.first_number + self.sec_number
        elif self.method == '-':
            result = self.first_number - self.sec_number
        elif self.method == '*':
            result = self.first_number * self.sec_number
        else:
            if self.sec_number != 0:
                result = self.first_number / self.sec_number
            else:
                result = 0
                print('除数不能为0')
                self.alert()
        self.method = ''
        self.sec_number = 0
        self.first_number = result
        self.ui.lineEdit.setText(str(result))

    def alert(self):
        """
        除数为0时重置所有,并弹框
        :return:
        """
        msgBox = QMessageBox()
        msgBox.setIcon(QMessageBox.Warning)
        msgBox.setWindowTitle(u'提示')
        msgBox.setText(u"除数不能为0")
        msgBox.setWindowIcon(QIcon('./favicon.ico'))

        # 隐藏ok按钮
        msgBox.addButton(QMessageBox.Ok)
        msgBox.button(QMessageBox.Ok).hide()

        # 模态对话框
        msgBox.exec_()

    def deal_point(self):
        """
        小数点事件
        :return:
        """
        temp = self.ui.lineEdit.text()
        if temp in ['+', '-', '*', '/']:
            self.ui.lineEdit.setText('0.')
        else:
            tempindex = temp.find('.')
            if tempindex == -1:
                self.ui.lineEdit.setText(temp + '.')


if __name__ == '__main__':
    app = QApplication(sys.argv)
    main_window = MainWindow()
    main_window.setWindowIcon(QIcon('./favicon.ico'))
    main_window.setWindowTitle('我的计算器')
    main_window.setFixedSize(560, 450)
    main_window.show()
    app.exec()
界面文件
# -*- coding: utf-8 -*-

# Form implementation generated from reading ui file 'mycalc.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_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(639, 600)
        font = QtGui.QFont()
        font.setPointSize(10)
        MainWindow.setFont(font)
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.lineEdit = QtWidgets.QLineEdit(self.centralwidget)
        self.lineEdit.setGeometry(QtCore.QRect(9, 62, 541, 71))
        font = QtGui.QFont()
        font.setPointSize(24)
        self.lineEdit.setFont(font)
        self.lineEdit.setObjectName("lineEdit")
        self.seven = QtWidgets.QPushButton(self.centralwidget)
        self.seven.setGeometry(QtCore.QRect(9, 197, 121, 41))
        font = QtGui.QFont()
        font.setPointSize(16)
        self.seven.setFont(font)
        self.seven.setObjectName("seven")
        self.four = QtWidgets.QPushButton(self.centralwidget)
        self.four.setGeometry(QtCore.QRect(10, 260, 121, 41))
        font = QtGui.QFont()
        font.setPointSize(16)
        self.four.setFont(font)
        self.four.setObjectName("four")
        self.eight = QtWidgets.QPushButton(self.centralwidget)
        self.eight.setGeometry(QtCore.QRect(150, 196, 131, 41))
        font = QtGui.QFont()
        font.setPointSize(16)
        self.eight.setFont(font)
        self.eight.setObjectName("eight")
        self.five = QtWidgets.QPushButton(self.centralwidget)
        self.five.setGeometry(QtCore.QRect(150, 264, 131, 41))
        font = QtGui.QFont()
        font.setPointSize(16)
        self.five.setFont(font)
        self.five.setObjectName("five")
        self.nine = QtWidgets.QPushButton(self.centralwidget)
        self.nine.setGeometry(QtCore.QRect(310, 194, 111, 41))
        font = QtGui.QFont()
        font.setPointSize(16)
        self.nine.setFont(font)
        self.nine.setObjectName("nine")
        self.six = QtWidgets.QPushButton(self.centralwidget)
        self.six.setGeometry(QtCore.QRect(310, 260, 111, 41))
        font = QtGui.QFont()
        font.setPointSize(16)
        self.six.setFont(font)
        self.six.setObjectName("six")
        self.point = QtWidgets.QPushButton(self.centralwidget)
        self.point.setGeometry(QtCore.QRect(10, 384, 121, 41))
        font = QtGui.QFont()
        font.setPointSize(16)
        self.point.setFont(font)
        self.point.setObjectName("point")
        self.zero = QtWidgets.QPushButton(self.centralwidget)
        self.zero.setGeometry(QtCore.QRect(150, 384, 131, 41))
        font = QtGui.QFont()
        font.setPointSize(16)
        self.zero.setFont(font)
        self.zero.setObjectName("zero")
        self.result = QtWidgets.QPushButton(self.centralwidget)
        self.result.setGeometry(QtCore.QRect(310, 386, 111, 41))
        font = QtGui.QFont()
        font.setPointSize(16)
        self.result.setFont(font)
        self.result.setObjectName("result")
        self.multi = QtWidgets.QPushButton(self.centralwidget)
        self.multi.setGeometry(QtCore.QRect(440, 194, 101, 41))
        font = QtGui.QFont()
        font.setPointSize(16)
        self.multi.setFont(font)
        self.multi.setObjectName("multi")
        self.division = QtWidgets.QPushButton(self.centralwidget)
        self.division.setGeometry(QtCore.QRect(440, 260, 101, 41))
        font = QtGui.QFont()
        font.setPointSize(16)
        self.division.setFont(font)
        self.division.setObjectName("division")
        self.add = QtWidgets.QPushButton(self.centralwidget)
        self.add.setGeometry(QtCore.QRect(440, 384, 101, 41))
        font = QtGui.QFont()
        font.setPointSize(16)
        self.add.setFont(font)
        self.add.setObjectName("add")
        self.clear_all = QtWidgets.QPushButton(self.centralwidget)
        self.clear_all.setGeometry(QtCore.QRect(307, 141, 241, 41))
        font = QtGui.QFont()
        font.setPointSize(16)
        self.clear_all.setFont(font)
        self.clear_all.setObjectName("clear_all")
        self.one = QtWidgets.QPushButton(self.centralwidget)
        self.one.setGeometry(QtCore.QRect(10, 324, 121, 41))
        font = QtGui.QFont()
        font.setPointSize(16)
        self.one.setFont(font)
        self.one.setObjectName("one")
        self.two = QtWidgets.QPushButton(self.centralwidget)
        self.two.setGeometry(QtCore.QRect(150, 324, 131, 41))
        font = QtGui.QFont()
        font.setPointSize(16)
        self.two.setFont(font)
        self.two.setObjectName("two")
        self.sub = QtWidgets.QPushButton(self.centralwidget)
        self.sub.setGeometry(QtCore.QRect(440, 324, 101, 41))
        font = QtGui.QFont()
        font.setPointSize(16)
        self.sub.setFont(font)
        self.sub.setObjectName("sub")
        self.three = QtWidgets.QPushButton(self.centralwidget)
        self.three.setGeometry(QtCore.QRect(310, 324, 111, 41))
        font = QtGui.QFont()
        font.setPointSize(16)
        self.three.setFont(font)
        self.three.setObjectName("three")
        self.myclear = QtWidgets.QPushButton(self.centralwidget)
        self.myclear.setGeometry(QtCore.QRect(9, 141, 271, 41))
        font = QtGui.QFont()
        font.setPointSize(16)
        self.myclear.setFont(font)
        self.myclear.setObjectName("myclear")
        MainWindow.setCentralWidget(self.centralwidget)
        self.menubar = QtWidgets.QMenuBar(MainWindow)
        self.menubar.setGeometry(QtCore.QRect(0, 0, 639, 23))
        self.menubar.setObjectName("menubar")
        MainWindow.setMenuBar(self.menubar)
        self.statusbar = QtWidgets.QStatusBar(MainWindow)
        self.statusbar.setObjectName("statusbar")
        MainWindow.setStatusBar(self.statusbar)

        self.retranslateUi(MainWindow)
        self.myclear.clicked.connect(self.lineEdit.clear)
        self.clear_all.clicked.connect(self.lineEdit.clear)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
        self.seven.setText(_translate("MainWindow", "7"))
        self.four.setText(_translate("MainWindow", "4"))
        self.eight.setText(_translate("MainWindow", "8"))
        self.five.setText(_translate("MainWindow", "5"))
        self.nine.setText(_translate("MainWindow", "9"))
        self.six.setText(_translate("MainWindow", "6"))
        self.point.setText(_translate("MainWindow", "."))
        self.zero.setText(_translate("MainWindow", "0"))
        self.result.setText(_translate("MainWindow", "="))
        self.multi.setText(_translate("MainWindow", "*"))
        self.division.setText(_translate("MainWindow", "/"))
        self.add.setText(_translate("MainWindow", "+"))
        self.clear_all.setText(_translate("MainWindow", "C"))
        self.one.setText(_translate("MainWindow", "1"))
        self.two.setText(_translate("MainWindow", "2"))
        self.sub.setText(_translate("MainWindow", "-"))
        self.three.setText(_translate("MainWindow", "3"))
        self.myclear.setText(_translate("MainWindow", "CE"))
预览效果图

你可能感兴趣的:(PyQt5简单应用--小试牛刀)