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

推荐阅读更多精彩内容