按道理来说python不应该拿来设计界面,本来他也不是这个擅长的,完全可以用WPF等使用python封装代码,但是也是实际用到了,就想一整套下来全用python。
据了解主流的界面库有pyqt和tkinter,但是看pyqt内置界面编辑器,控件布局很方便,所以这里就记录一下。
我们分四个步骤说明:
- pyqt库下载和安装
- 界面设计器和布局
- py生成器
- 界面原理
1 pyqt库下载和安装
使用pycharm可以和你方便的安装库
点击添加新的库,我们需要的就是画圈的这两个 直接安装就好
如果使用原生python,那就pip命令安装
pip install PyQt5
# (使用国内的源则可用如下的命令:pip install PyQt5 -i https://pypi.tuna.tsinghua.edu.cn/simple,
pip install PyQt5-tools -i https://pypi.tuna.tsinghua.edu.cn/simple
安装后创建一个py测试一下,看好不好用
from PyQt5 import QtWidgets, QtGui
import sys
app = QtWidgets.QApplication(sys.argv)
window = QtWidgets.QWidget()
window.show()
sys.exit(app.exec_())
能出来界面就是没问题
第二步 使用界面编辑器
pyqt的一大优势就是自带界面编辑器,我们可以方便的使用控件,设计属性和布局。该设计器是exe文件,直接运行就可以
路径在我们安装的pyqt-tool的包里面,大概是这个样子:
找到你安装python的路径,在下面的Lib文件夹下的site-packages中找到目标库,下面就有dsigner.exe
双击打开,我们创建一个main窗体
左侧区域是控件区域 中间是实时的窗口显示 右侧是属性窗体。用过VB和wpf的应该都熟悉,这已经是界面开发器的模板了都。
左侧控件直接拖拽到界面,右侧可以更改控件属性
如果嫌弃每次都需要打开文件路径麻烦,那么我们可以将这个工具添加到pycharm的工具箱中,以后可以直接调用。pycharm允许自定义调用,我们将这个designer程序加一下看看。
还是file-setting 这次打开的选项是External tools,扩展工具 点击+号添加
这个界面大家看一眼应该就理解了,python可以调用外部程序,工具的名字自己命名到时候工具箱总显示的就是这个名字,调用的程序就是你填的路径。
name随意 程序路径就是我们的designer.exe的路径。下面的工作路径就是本项目路径,里面提供了快捷选项,点按钮选就可以
确认之后我们的工具里就会有这个添加的了,工程或者文件上右键选择扩展工具就可以直接打开界面而不用自己去找
3. py生成器
我们界面设计器实际上用的是CSS等布局结构,不是py代码,所以无法直接使用,这里还有一个转换的过程。
我们新建一个python工程,然后使用工具开始编辑界面,然后将文件保存在工程的目录下
file-NEW project新建一个工程 然后用designer编辑界面
将文件保存在项目路径下,接下来使用py生成器生成py代码,可以看到界面时.ui文件
这次要用的文件是这个
我们需要使用该库中得pyuic模块编译ui文件,进入ui文件所在的目录也就是项目目录
按住shift 右键在此处打开powershell
执行的命令是这个:
py -3 -m PyQt5.uic.pyuic detect.ui -o detect.py
# 使用python 导入PyQt5库中的uic.pyuic模块 将detect.ui编译为detect.py
# 我这里用py -3 因为我安装了2和3两个版本 正常直接就python就可以
可以看到里面多了py文件,打开一看就是我们的界面布局,只不过现在是python表示
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'detect.ui'
#
# Created by: PyQt5 UI code generator 5.11.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("MainWindow")
MainWindow.resize(517, 370)
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.pushButton = QtWidgets.QPushButton(self.centralwidget)
self.pushButton.setGeometry(QtCore.QRect(410, 30, 81, 31))
self.pushButton.setObjectName("pushButton")
self.listrules = QtWidgets.QListWidget(self.centralwidget)
self.listrules.setGeometry(QtCore.QRect(30, 70, 461, 221))
self.listrules.setObjectName("listrules")
self.textEdit = QtWidgets.QTextEdit(self.centralwidget)
self.textEdit.setGeometry(QtCore.QRect(30, 30, 241, 31))
self.textEdit.setObjectName("textEdit")
self.pushButton_2 = QtWidgets.QPushButton(self.centralwidget)
self.pushButton_2.setGeometry(QtCore.QRect(410, 300, 81, 31))
self.pushButton_2.setObjectName("pushButton_2")
MainWindow.setCentralWidget(self.centralwidget)
self.menubar = QtWidgets.QMenuBar(MainWindow)
self.menubar.setGeometry(QtCore.QRect(0, 0, 517, 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)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
self.pushButton.setText(_translate("MainWindow", "添加规则"))
self.pushButton_2.setText(_translate("MainWindow", "开始检测"))
这只是布局,在加上窗口初始化的代码就可以用了
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'detect.ui'
#
# Created by: PyQt5 UI code generator 5.11.2
#
# WARNING! All changes made in this file will be lost!
from PyQt5 import QtCore, QtGui, QtWidgets
import sys
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(517, 370)
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.pushButton = QtWidgets.QPushButton(self.centralwidget)
self.pushButton.setGeometry(QtCore.QRect(410, 30, 81, 31))
self.pushButton.setObjectName("pushButton")
self.listrules = QtWidgets.QListWidget(self.centralwidget)
self.listrules.setGeometry(QtCore.QRect(30, 70, 461, 221))
self.listrules.setObjectName("listrules")
self.textEdit = QtWidgets.QTextEdit(self.centralwidget)
self.textEdit.setGeometry(QtCore.QRect(30, 30, 241, 31))
self.textEdit.setObjectName("textEdit")
self.pushButton_2 = QtWidgets.QPushButton(self.centralwidget)
self.pushButton_2.setGeometry(QtCore.QRect(410, 300, 81, 31))
self.pushButton_2.setObjectName("pushButton_2")
MainWindow.setCentralWidget(self.centralwidget)
self.menubar = QtWidgets.QMenuBar(MainWindow)
self.menubar.setGeometry(QtCore.QRect(0, 0, 517, 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)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
self.pushButton.setText(_translate("MainWindow", "添加规则"))
self.pushButton_2.setText(_translate("MainWindow", "开始检测"))
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv) # 初始化界面
window = QtWidgets.QMainWindow() #窗体类型 主窗体
ui = Ui_MainWindow()
ui.setupUi(window) # 绑定窗体布局 绑定到window窗体
window.show() # 显示窗体
sys.exit(app.exec_())
这就可以用了,哈哈。这里如果嫌麻烦,依旧可以吧pyuic模块有导入为工具
还是file-settings-tools-external tool-添加,这次的信息如下:
上次是直接调用exe,这次是调用python 然后附带参数,所以这里的程序路径为python,参数写
-m PyQt5.uic.pyuic $FileName$ -o $FileNameWithoutExtension$.py
这里使用快捷路径 将文件全编为py 我们也可以像刚才那样具体到文件名
然后工具就可以直接使用了,右键点击需要编译的ui文件,选择工具
4 界面原理
可能有人知道有人不知道,windows就是基于界面的,而界面又是消息驱动的,消息引发诸多的事件。
前文我们那些控件,按钮可以点击,列表可以显示,我们布局之后还需要绑定事件,这样控件才能发挥实质的操作-响应。
这里先不多说,下次再讲,对这个感兴趣的可以去查一查,界面是如何显示如何响应的