一篇文章带你入门 PyQt (designer)

文件下载位置在文末


最近沉迷于用Python写GUI,但我之前写Py的GUI都是用的tkinter,然而tkinter实在是太丑了,而且代码编写难度大,布局困难,直接把我劝退了。偶然想起Python可以用PyQt5进行GUI的编写,有可视化的界面,代码也不复杂,于是我果断选择
一篇文章带你入门 PyQt (designer)_第1张图片
在网上找了相关的教程,发现大部分都是直接上代码,对新手非常不友好,而且看得我是一脸懵逼。找了很多文章,综合了许多内容,才写成了这篇文章

本篇通过一个完整的实例来进行PyQt5的学习


以下是正文:

效果展示

本篇通过PyQt5制作一个MD5加密器,并将其打包为exe文件,从中进行对PyQt5的学习

虽然这个项目没有涵盖PyQt5的所有内容但用到了如文件选择的常用功能,掌握了这个项目,其他的也大致可以依葫芦画瓢了

先来看看程序的运行结果
一篇文章带你入门 PyQt (designer)_第2张图片
一篇文章带你入门 PyQt (designer)_第3张图片
接下来正式开始

安装

使用PyQt开发,要先下载相关的第三方库的工具
这里一次性把打包exe的工具也安装了
随便创建一个文件,将其后缀名改为 .bat
在文件中输入

ins.bat

pip install PyQt5 -i https://mirrors.aliyun.com/pypi/simple/
pip install pyqt5-tools -i https://mirrors.aliyun.com/pypi/simple/
pip install pyinstaller -i https://mirrors.aliyun.com/pypi/simple/

保存退出,双击运行,会弹出一个黑色的框,等安装好后就会自动消失
一篇文章带你入门 PyQt (designer)_第4张图片
安装完成后,在Python解释器中输入以下语句,如果没有报错即为安装成功

import PyQt5

如图即为安装成功
一篇文章带你入门 PyQt (designer)_第5张图片

使用designer编辑界面

在电脑里找到designer.exe文件
一篇文章带你入门 PyQt (designer)_第6张图片
在这里记住这个文件的位置,待会要用,同时给这个文件创一个桌面快捷方式,如图
在这里插入图片描述

这样的话比较方便打开进行GUI界面的编辑

然后打开Pycharm,创建一个项目,取名md5_qt

在这里创建一个包,名为ui,用来存放ui文件

再创建一个包,名为windows,用来存放py文件

最后创建一个入口程序,取名为md5.py

创建好大概是这样的

一篇文章带你入门 PyQt (designer)_第7张图片
然后配置一下Pycharm中的快捷方式

在Pycharm中选中 File->Setting->Tools->External Tools
一篇文章带你入门 PyQt (designer)_第8张图片
一篇文章带你入门 PyQt (designer)_第9张图片
点右边的加号,在弹出的窗口中修改快捷工具信息
Qt Designer
一篇文章带你入门 PyQt (designer)_第10张图片

其中,Program位置填的是之前designer.exe的位置
Working directory:

$FileDir$

PyUIC
再次点击加号,配置PyUIC的信息
一篇文章带你入门 PyQt (designer)_第11张图片
其中Program位置填写的Python的安装路径
Arguments:

-m PyQt5.uic.pyuic  $FileName$ -o $FileNameWithoutExtension$.py

Working directory:

$FileDir$

配置好后,在ui文件夹上右键,选择External Tools->Qt Designer,打开Qt Designer进行可视化界面编辑
一篇文章带你入门 PyQt (designer)_第12张图片
一篇文章带你入门 PyQt (designer)_第13张图片
在新建窗口位置点击Main Window,选择创建以创建一个主窗口
一篇文章带你入门 PyQt (designer)_第14张图片
一篇文章带你入门 PyQt (designer)_第15张图片

在左侧是组件控制,在这里可以控制你窗口中的组件
右上角是对象查看器,这里会显示窗口中所有组件及其结构,方便进行管理
右侧是属性编辑器,在这里设置组件的一些属性,如文本,名称等等
右下角是资源管理器,在这里设置信号、动作,资源
中间是编辑区,在这里编辑你的窗口
上方是菜单栏,这里有些常用的功能

接下来通过你想要的控件从左边拖到中间即可

大概设计成这个样子
一篇文章带你入门 PyQt (designer)_第16张图片
这里要注意一些东西,选中控件,在右侧可以设置组件的名称,例如这个加密按钮,我就给它取名为encry_btn
一篇文章带你入门 PyQt (designer)_第17张图片
在给组件取名时要注意它的实际含义,取名要有意义且容易记,在程序开发过程中会非常方便

最后保存退出,将文件取名为MainWindow.ui

另外,如果不想设计界面的话,可以直接用我设计好的界面代码,将代码复制进文件,即可完成布局


<ui version="4.0">
 <class>MainWindowclass>
 <widget class="QMainWindow" name="MainWindow">
  <property name="geometry">
   <rect>
    <x>0x>
    <y>0y>
    <width>494width>
    <height>602height>
   rect>
  property>
  <property name="windowTitle">
   <string>MainWindowstring>
  property>
  <widget class="QWidget" name="centralwidget">
   <widget class="QLabel" name="Title_Label">
    <property name="geometry">
     <rect>
      <x>160x>
      <y>0y>
      <width>161width>
      <height>81height>
     rect>
    property>
    <property name="font">
     <font>
      <family>Arialfamily>
      <pointsize>28pointsize>
      <weight>87weight>
      <bold>truebold>
     font>
    property>
    <property name="styleSheet">
     <string notr="true">color:rgb(255, 0, 0);
font-weight:700;
string>
    property>
    <property name="text">
     <string>MD5加密string>
    property>
    <property name="alignment">
     <set>Qt::AlignCenterset>
    property>
   widget>
   <widget class="QLabel" name="label_1">
    <property name="geometry">
     <rect>
      <x>30x>
      <y>70y>
      <width>221width>
      <height>51height>
     rect>
    property>
    <property name="font">
     <font>
      <family>Arialfamily>
      <pointsize>20pointsize>
     font>
    property>
    <property name="text">
     <string>请输入加密内容:string>
    property>
   widget>
   <widget class="QTextEdit" name="original_text">
    <property name="geometry">
     <rect>
      <x>30x>
      <y>120y>
      <width>441width>
      <height>101height>
     rect>
    property>
    <property name="font">
     <font>
      <family>Arialfamily>
      <pointsize>18pointsize>
     font>
    property>
   widget>
   <widget class="QPushButton" name="file_btn">
    <property name="geometry">
     <rect>
      <x>370x>
      <y>80y>
      <width>101width>
      <height>31height>
     rect>
    property>
    <property name="font">
     <font>
      <family>Arialfamily>
      <pointsize>16pointsize>
     font>
    property>
    <property name="text">
     <string>选择文件string>
    property>
   widget>
   <widget class="QPushButton" name="encry_btn">
    <property name="geometry">
     <rect>
      <x>30x>
      <y>240y>
      <width>100width>
      <height>40height>
     rect>
    property>
    <property name="font">
     <font>
      <family>Arialfamily>
      <pointsize>20pointsize>
     font>
    property>
    <property name="text">
     <string>加密string>
    property>
   widget>
   <widget class="QPushButton" name="clear_btn">
    <property name="geometry">
     <rect>
      <x>370x>
      <y>240y>
      <width>100width>
      <height>40height>
     rect>
    property>
    <property name="font">
     <font>
      <family>Arialfamily>
      <pointsize>20pointsize>
     font>
    property>
    <property name="text">
     <string>清空string>
    property>
   widget>
   <widget class="QLabel" name="label_2">
    <property name="geometry">
     <rect>
      <x>190x>
      <y>290y>
      <width>121width>
      <height>51height>
     rect>
    property>
    <property name="font">
     <font>
      <family>Arialfamily>
      <pointsize>22pointsize>
     font>
    property>
    <property name="text">
     <string>加密结果string>
    property>
   widget>
   <widget class="QTextEdit" name="res_shower">
    <property name="geometry">
     <rect>
      <x>30x>
      <y>350y>
      <width>441width>
      <height>111height>
     rect>
    property>
    <property name="font">
     <font>
      <family>Arialfamily>
      <pointsize>18pointsize>
     font>
    property>
   widget>
   <widget class="QPushButton" name="exit_btn">
    <property name="geometry">
     <rect>
      <x>30x>
      <y>480y>
      <width>441width>
      <height>71height>
     rect>
    property>
    <property name="font">
     <font>
      <family>Arialfamily>
      <pointsize>24pointsize>
     font>
    property>
    <property name="text">
     <string>退出程序string>
    property>
   widget>
  widget>
  <widget class="QMenuBar" name="menubar">
   <property name="geometry">
    <rect>
     <x>0x>
     <y>0y>
     <width>494width>
     <height>23height>
    rect>
   property>
  widget>
  <widget class="QStatusBar" name="statusbar"/>
 widget>
 <resources/>
 <connections>
  <connection>
   <sender>exit_btnsender>
   <signal>clicked()signal>
   <receiver>exit_btnreceiver>
   <slot>close()slot>
   <hints>
    <hint type="sourcelabel">
     <x>234x>
     <y>543y>
    hint>
    <hint type="destinationlabel">
     <x>188x>
     <y>541y>
    hint>
   hints>
  connection>
  <connection>
   <sender>exit_btnsender>
   <signal>clicked()signal>
   <receiver>exit_btnreceiver>
   <slot>close()slot>
   <hints>
    <hint type="sourcelabel">
     <x>221x>
     <y>550y>
    hint>
    <hint type="destinationlabel">
     <x>210x>
     <y>538y>
    hint>
   hints>
  connection>
 connections>
ui>

完事后就是这个样子
一篇文章带你入门 PyQt (designer)_第18张图片
然后右键MainWindow.ui文件,选择External Tools->PyUIC
一篇文章带你入门 PyQt (designer)_第19张图片
然后生成了一个MainWIndow.py文件,把这个文件移到windows包下
如图
一篇文章带你入门 PyQt (designer)_第20张图片
此时文件内容应该是这样

# -*- coding: utf-8 -*-

from PyQt5 import QtCore, QtGui, QtWidgets


class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(494, 602)
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.Title_Label = QtWidgets.QLabel(self.centralwidget)
        self.Title_Label.setGeometry(QtCore.QRect(160, 0, 161, 81))
        font = QtGui.QFont()
        font.setFamily("Arial")
        font.setPointSize(28)
        font.setBold(True)
        font.setWeight(87)
        self.Title_Label.setFont(font)
        self.Title_Label.setStyleSheet("color:rgb(255, 0, 0);\n"
"font-weight:700;\n"
"")
        self.Title_Label.setAlignment(QtCore.Qt.AlignCenter)
        self.Title_Label.setObjectName("Title_Label")
        self.label_1 = QtWidgets.QLabel(self.centralwidget)
        self.label_1.setGeometry(QtCore.QRect(30, 70, 221, 51))
        font = QtGui.QFont()
        font.setFamily("Arial")
        font.setPointSize(20)
        self.label_1.setFont(font)
        self.label_1.setObjectName("label_1")
        self.original_text = QtWidgets.QTextEdit(self.centralwidget)
        self.original_text.setGeometry(QtCore.QRect(30, 120, 441, 101))
        font = QtGui.QFont()
        font.setFamily("Arial")
        font.setPointSize(18)
        self.original_text.setFont(font)
        self.original_text.setObjectName("original_text")
        self.file_btn = QtWidgets.QPushButton(self.centralwidget)
        self.file_btn.setGeometry(QtCore.QRect(370, 80, 101, 31))
        font = QtGui.QFont()
        font.setFamily("Arial")
        font.setPointSize(16)
        self.file_btn.setFont(font)
        self.file_btn.setObjectName("file_btn")
        self.encry_btn = QtWidgets.QPushButton(self.centralwidget)
        self.encry_btn.setGeometry(QtCore.QRect(30, 240, 100, 40))
        font = QtGui.QFont()
        font.setFamily("Arial")
        font.setPointSize(20)
        self.encry_btn.setFont(font)
        self.encry_btn.setObjectName("encry_btn")
        self.clear_btn = QtWidgets.QPushButton(self.centralwidget)
        self.clear_btn.setGeometry(QtCore.QRect(370, 240, 100, 40))
        font = QtGui.QFont()
        font.setFamily("Arial")
        font.setPointSize(20)
        self.clear_btn.setFont(font)
        self.clear_btn.setObjectName("clear_btn")
        self.label_2 = QtWidgets.QLabel(self.centralwidget)
        self.label_2.setGeometry(QtCore.QRect(190, 290, 121, 51))
        font = QtGui.QFont()
        font.setFamily("Arial")
        font.setPointSize(22)
        self.label_2.setFont(font)
        self.label_2.setObjectName("label_2")
        self.res_shower = QtWidgets.QTextEdit(self.centralwidget)
        self.res_shower.setGeometry(QtCore.QRect(30, 350, 441, 111))
        font = QtGui.QFont()
        font.setFamily("Arial")
        font.setPointSize(18)
        self.res_shower.setFont(font)
        self.res_shower.setObjectName("res_shower")
        self.exit_btn = QtWidgets.QPushButton(self.centralwidget)
        self.exit_btn.setGeometry(QtCore.QRect(30, 480, 441, 71))
        font = QtGui.QFont()
        font.setFamily("Arial")
        font.setPointSize(24)
        self.exit_btn.setFont(font)
        self.exit_btn.setObjectName("exit_btn")
        MainWindow.setCentralWidget(self.centralwidget)
        self.menubar = QtWidgets.QMenuBar(MainWindow)
        self.menubar.setGeometry(QtCore.QRect(0, 0, 494, 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.exit_btn.clicked.connect(self.exit_btn.close)
        self.exit_btn.clicked.connect(self.exit_btn.close)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
        self.Title_Label.setText(_translate("MainWindow", "MD5加密"))
        self.label_1.setText(_translate("MainWindow", "请输入加密内容:"))
        self.file_btn.setText(_translate("MainWindow", "选择文件"))
        self.encry_btn.setText(_translate("MainWindow", "加密"))
        self.clear_btn.setText(_translate("MainWindow", "清空"))
        self.label_2.setText(_translate("MainWindow", "加密结果"))
        self.exit_btn.setText(_translate("MainWindow", "退出程序"))

至于文件内容是什么意思,并不需要知道(因为我也不知道),总之在这个文件中实现了窗口的布局

主代码编写

此时的代码是不能运行的,所以要准备一个主程序作为GUI的入口
我先把代码贴出来,再一一讲解

#-*- encoding = utf-8 -*-
import hashlib
import sys

from PyQt5 import QtWidgets
from PyQt5.QtWidgets import QMainWindow, QFileDialog

from Windows.MainWindow import Ui_MainWindow


class MyWindow(QMainWindow,Ui_MainWindow):
    def __init__(self):
        super(MyWindow,self).__init__()
        self.setupUi(self)
        self.exit_btn.clicked.connect(lambda :sys.exit())
        self.encry_btn.clicked.connect(self.encry)
        self.file_btn.clicked.connect(self.file_choose)
        self.clear_btn.clicked.connect(lambda :self.original_text.setText(''))
    def encry(self):
        text=self.original_text.toPlainText()
        result=hashlib.md5(text.encode()).hexdigest()
        self.res_shower.setText(result)
        print("[==>加密成功<==]\n|{%s}==>{%s}|"%(text,result))

    def file_choose(self):
        filename,filetype=QFileDialog.getOpenFileName(self,"打开文件","/","文本文件(*.txt);全部文件(*.*)")
        if filename!="":
            f=open(filename,'r',encoding='utf-8')
            text=f.read()
            self.original_text.setText(text)
            self.encry()

if __name__ == '__main__':
    app=QtWidgets.QApplication(sys.argv)
    ui=MyWindow()
    ui.show()
    sys.exit(app.exec_())

文件主入口

from PyQt5 import QtWidgets
from PyQt5.QtWidgets import QMainWindow
from Windows.MainWindow import Ui_MainWindow

class MyWindow(QMainWindow,Ui_MainWindow):
    def __init__(self):
        super(MyWindow,self).__init__()
        self.setupUi(self)

if __name__ == '__main__':
    app=QtWidgets.QApplication(sys.argv)
    ui=MyWindow()
    ui.show()
    sys.exit(app.exec_())

此时运行文件,会看到我们之前编辑的界面,但是尝试按其中的按钮,会发现没有反应。
这是因为这里只实现了窗口的显示,没有实现具体的功能

代码讲解
首先创建了一个自定义类MyWindow继承了QMainWindow,并且调用了父类的构造方法,设置界面ui。接下来在main部分创建了一个QApplication的对象,取名为app,同时创建MyWindow的对象,显示界面。最后一行代码用来退出程序,如果没有最后一行就会一闪而过

按钮绑定
之前的界面按下按钮是没有反应的,要给按钮设置了相应的行为,程序才有了生命。想要给按钮设置函数,可以用这个代码

按钮对象.clicked.connect(函数名)

例如我要给名为exit_btn的按钮设置退出程序的函数,就是这个样子

exit_btn.clicked.connect(lambda :sys.exit())

这样对代码进行修改,就变成了这样

class MyWindow(QMainWindow,Ui_MainWindow):
    def __init__(self):
        super(MyWindow,self).__init__()
        self.setupUi(self)
        self.exit_btn.clicked.connect(lambda :sys.exit())
        self.encry_btn.clicked.connect(self.encry)
        self.file_btn.clicked.connect(self.file_choose)
        self.clear_btn.clicked.connect(lambda :self.original_text.setText(''))
    def encry(self):
        pass

    def file_choose(self):
        pass

代码讲解
按钮前方有一个self是因为所要控制的按钮是当前界面的按钮对象,加上了self才能将程序指针指到按钮上
此外,这里的名称就是Qt Designer中的ObjectName
在这里插入图片描述

在clear_btn的函数位置,用到了setText方法,这个方法是设置组件上的文本,这里是按下按钮后将输入框的文本设置为空

加密代码
接下来看看加密函数的代码

    def encry(self):
        text=self.original_text.toPlainText()
        result=hashlib.md5(text.encode()).hexdigest()
        self.res_shower.setText(result)
        print("[==>加密成功<==]\n|{%s}==>{%s}|"%(text,result))

首先通过组件对象的toPlainText方法获取了组件的文本,这里是获取用户的输入内容,接下来通过md5加密函数将明文加密为密文,然后将结果展示框的内容设置为加密后的结果,同时控制台输出内容

文件选择
先看代码

    def file_choose(self):
        filename,filetype=QFileDialog.getOpenFileName(self,"打开文件","/","文本文件(*.txt);全部文件(*.*)")
        if filename!="":
            f=open(filename,'r',encoding='utf-8')
            text=f.read()
            self.original_text.setText(text)
            self.encry()

首先创建了一个QFileDialog对象,这个对象是文件选择框,调用它的getOpenFileName方法来加载一个已经存在的文件,这个函数的返回结果是一个元组,元组的第一项是文件的绝对路径,第二项是文件类型。函数的参数

QFileDialog.getOpenFileName(self,"标题","起始路径","文件类型")

例如我将标题设为选择文件,将起始路径设置为根路径,在这里接受两种文件类型(文本文件(.txt)和全部文件(.*)),弹出的窗口就是这样
一篇文章带你入门 PyQt (designer)_第21张图片

接下来判断是否选择文件,如果选择了文件,则新建一个文件对象,获取文件内容,将输入框内容设置为文件内容,再调用加密函数

exe打包

写好的项目在文件夹中就是这个样子
一篇文章带你入门 PyQt (designer)_第22张图片
打开dos,cd到这个目录,输入

pyinstaller -F md5.py

其中这个md5.py是文件名,也可以改成其他的
静静等待即可
打包好后的exe文件在dist文件夹中,其它的文件夹和文件可以删除

下载地址

github:https://github.com/13337356453/md5
csdn:https://download.csdn.net/download/realmels/14832594

你可能感兴趣的:(PyQt5,python,pyqt)