TD课程汇总【五】首个PyQt窗口的实现

编写环境:

  • 安装软件:pycharm,Qt Designer

  • python版本: py3.7,

  • 必要的包: pyqt5,pyside2

整体过程的实现

1.安装pyside2或pyqt5

1)安装pyside2

  • 安装pyside2(pyqt5是不带designer的,需要单独安装且没有汉化,所以推荐直接安装pyside2)
    打开cmd输入下面代码,进行安装
pip install pyside2
  • Designer.exe路径
python安装路径\Lib\site-packages\PySide\designer.exe
  • uic包
python安装路径\Lib\site-packages\pyside2uic

2)安装pyqt5:

pip install pyqt5
pip install PyQt5-tools -i http://pypi.douban.com/simple --trusted-`  # designerpip安装 代码

2.UI绘制

  • 简单说一下常用操作,直接从控件库拖动到工作区就可以,有时候有的控件重叠没办法放到需要的控件下也可以将控件拖动到大纲,然后再调整位置,微调建议用代码,designer貌似有自动吸附
    TD课程汇总【五】首个PyQt窗口的实现_第1张图片

  • 右侧列出的属性值跟工作区的状态是联动的,绘制过程中,属性值会跟着改变,对属性没掌握的同学可以通过工作区的调整来判断对应的属性,信号与槽也是属性的展示

  • 绘制过程中可以按ctrl + R预览

  • F4切换到连接信号槽状态,

如图所示,将一个按钮的点击信号连接到另一个空间的隐藏属性上,鼠标放到pushButton上变红,点击拖曳到下面的文本框上,出现接地符号,松开
插入连接的指示灯,交替显示从QWidget继承的信号与槽是没重置的,所以看到的数量会少很多,
另外,信号的类型跟槽的类型要保持一致,当单击clicker(bool),左侧可连接的槽也会发生变化
TD课程汇总【五】首个PyQt窗口的实现_第2张图片

  • F3返回绘制模式,确认完成保存ui文件

3.ui转py

  • 通过代码实现
import pyside2uic
with open(r'D:\Users\Desktop\startWindow.py', 'w') as f:
    pyside2uic.compileUi(r'D:\Users\Desktop\startWindow.ui', f)
  • pycharm创建ui转py工具
    文件→设置→工具→外部工具然后单击小加号
    三行分别是:
  1. pyside2写法
Program:C:\Users\XingLian\Anaconda3\envs\python3\Scripts\pyside2-uic.exe
Arguments: -o $FileNameWithoutExtension$.py $FileName$x
Working directory:$FileDir$
  1. pyqt5写法
Program:C:\Users\xinglian\anaconda3\envs\python3\python.exe
Arguments: -m PyQt5.uic.pyuic $FileName$ -o $FileNameWithoutExtension$.py
Working directory:$FileDir$

编辑好之后点ok保存,然后在画好的ui上快捷就可以快速的转成py文件了

4.py窗口的显示

转换后的py文件是一个类,还需要一个实例化,以及调用的过程,

将下面代码粘贴到底部,执行,你画好的窗口就出来了:

import sys
from PyQt5 import QtWidgets 
import window
if __name__ = "__init__":
app = QtWidgets.QApplication(sys.argv)  # 创建一个QApplication,也就是你要开发的软件app
MainWindow = QtWidgets.QMainWindow()  # 实例化一个QMainWindow,用来装载你需要的各种组件、控件
ui = window.Ui_objectZip()  # ui是Ui_MainWindow()类的实例化对象
ui.setupUi(MainWindow)  # 执行类中的setupUi方法,方法的参数是第二步中创建的QMainWindow
MainWindow.show()  # 执行QMainWindow的show()方法,显示这个QMainWindow
sys.exit(app.exec_())

这里有一个 if __name_ _ = "__init__" :的原因是这个文件只有测试的时候才会执行,为了防止之后修改ui重新转换py导致写好的代码丢失,通常这个ui转换出来的py会通过继承的方式在另一个类中调用,而不是直接修改,

5.ui与功能的分离(这个纠结了很久,卡死在了继承上)

class ShowWindow(QMainWindow, window.Ui_Main_Window):
    # 继承的父类window.Ui_Main_Window是ui的class
    def __init__(self):
    	# 继承只是继承了def的方法, super执行了父类的__init__方法
   		super(ShowWindow, self).__init__()  # 安装 QMainWindow 窗口
    	# 此时的self具有了ui的所有属性及方法
    	# 测试代码这个位置有一个实例化的过程,这里因为继承的关系
    	# self已经具有QtWidgets.QMainWindow()的属性,可以将self作为参数传入setupUI中
    	self.setupUi(self)  # 执行父类中的setupUi方法 ui测试代码中,这里的
    	self.show()  # 执行QMainWindow的show()方法,显示这个QMainWindow
    	
   
# 其中创建app的过程都要放在class的外面    
app = QtWidgets.QApplication(sys.argv)
foo = ShowWindow()
sys.exit(app.exec_())

6.控件的属性查询(这个貌似只能靠积累了,然后就是dir跟google)

绘制过程中,右侧的属性,以及槽与信号的链接过程,也是属性的积累过程,修改的时候看看对应的属性名,知道转换成代码自己是修改了什么

7.粘上我的案例

  • 首先是ui转的py
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'window.ui'
# Created by: PyQt5 UI code generator 5.13.0
# WARNING! All changes made in this file will be lost!
from PySide2 import QtCore, QtGui, QtWidgets

class Ui_Main_Window(object):
    def setupUi(self, Main_Window):
        Main_Window.setObjectName("Main_Window")
        Main_Window.setWindowModality(QtCore.Qt.NonModal)
        Main_Window.resize(376, 155)
        self.horizontalLayoutWidget_3 = QtWidgets.QWidget(Main_Window)
        self.horizontalLayoutWidget_3.setGeometry(QtCore.QRect(10, 0, 191, 41))
        self.horizontalLayoutWidget_3.setObjectName("horizontalLayoutWidget_3")
        self.horizontalLayout_3 = QtWidgets.QHBoxLayout(self.horizontalLayoutWidget_3)
        self.horizontalLayout_3.setContentsMargins(0, 0, 0, 0)
        self.horizontalLayout_3.setObjectName("horizontalLayout_3")
        self.ass_RB = QtWidgets.QRadioButton(self.horizontalLayoutWidget_3)
        self.ass_RB.setChecked(True)
        self.ass_RB.setObjectName("ass_RB")
        self.horizontalLayout_3.addWidget(self.ass_RB)
        self.shot_RB = QtWidgets.QRadioButton(self.horizontalLayoutWidget_3)
        self.shot_RB.setObjectName("shot_RB")
        self.horizontalLayout_3.addWidget(self.shot_RB)
        self.horizontalLayoutWidget_4 = QtWidgets.QWidget(Main_Window)
        self.horizontalLayoutWidget_4.setGeometry(QtCore.QRect(10, 100, 341, 41))
        self.horizontalLayoutWidget_4.setObjectName("horizontalLayoutWidget_4")
        self.horizontalLayout_4 = QtWidgets.QHBoxLayout(self.horizontalLayoutWidget_4)
        self.horizontalLayout_4.setContentsMargins(0, 0, 0, 0)
        self.horizontalLayout_4.setObjectName("horizontalLayout_4")
        self.task_LE = QtWidgets.QLineEdit(self.horizontalLayoutWidget_4)
        sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Fixed)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(self.task_LE.sizePolicy().hasHeightForWidth())
        self.task_LE.setSizePolicy(sizePolicy)
        self.task_LE.setMinimumSize(QtCore.QSize(0, 25))
        self.task_LE.setMaxLength(32780)
        self.task_LE.setObjectName("task_LE")
        self.horizontalLayout_4.addWidget(self.task_LE)
        self.run_B = QtWidgets.QPushButton(self.horizontalLayoutWidget_4)
        self.run_B.setMinimumSize(QtCore.QSize(0, 25))
        self.run_B.setObjectName("run_B")
        self.horizontalLayout_4.addWidget(self.run_B)
        self.horizontalLayoutWidget_5 = QtWidgets.QWidget(Main_Window)
        self.horizontalLayoutWidget_5.setGeometry(QtCore.QRect(10, 60, 341, 51))
        self.horizontalLayoutWidget_5.setObjectName("horizontalLayoutWidget_5")
        self.horizontalLayout_5 = QtWidgets.QHBoxLayout(self.horizontalLayoutWidget_5)
        self.horizontalLayout_5.setContentsMargins(0, 0, 0, 0)
        self.horizontalLayout_5.setObjectName("horizontalLayout_5")
        self.path_LE = QtWidgets.QLineEdit(self.horizontalLayoutWidget_5)
        sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Fixed)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(self.path_LE.sizePolicy().hasHeightForWidth())
        self.path_LE.setSizePolicy(sizePolicy)
        self.path_LE.setMinimumSize(QtCore.QSize(250, 25))
        self.path_LE.setMaxLength(32780)
        self.path_LE.setObjectName("path_LE")
        self.horizontalLayout_5.addWidget(self.path_LE)
        self.path_B = QtWidgets.QToolButton(self.horizontalLayoutWidget_5)
        self.path_B.setMinimumSize(QtCore.QSize(0, 25))
        self.path_B.setObjectName("path_B")
        self.horizontalLayout_5.addWidget(self.path_B)
        self.verticalLayoutWidget = QtWidgets.QWidget(Main_Window)
        self.verticalLayoutWidget.setGeometry(QtCore.QRect(10, 40, 343, 21))
        self.verticalLayoutWidget.setObjectName("verticalLayoutWidget")
        self.verticalLayout = QtWidgets.QVBoxLayout(self.verticalLayoutWidget)
        self.verticalLayout.setContentsMargins(0, 0, 0, 0)
        self.verticalLayout.setObjectName("verticalLayout")
        spacerItem = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding)
        self.verticalLayout.addItem(spacerItem)
        self.horizontalLayout = QtWidgets.QHBoxLayout()
        self.horizontalLayout.setContentsMargins(10, -1, 0, -1)
        self.horizontalLayout.setObjectName("horizontalLayout")
        self.lay_RB = QtWidgets.QRadioButton(self.verticalLayoutWidget)
        self.lay_RB.setObjectName("lay_RB")
        self.horizontalLayout.addWidget(self.lay_RB)
        self.ani_RB = QtWidgets.QRadioButton(self.verticalLayoutWidget)
        self.ani_RB.setChecked(True)
        self.ani_RB.setObjectName("ani_RB")
        self.horizontalLayout.addWidget(self.ani_RB)
        self.cfx_RB = QtWidgets.QRadioButton(self.verticalLayoutWidget)
        self.cfx_RB.setChecked(False)
        self.cfx_RB.setObjectName("cfx_RB")
        self.horizontalLayout.addWidget(self.cfx_RB)
        self.verticalLayout.addLayout(self.horizontalLayout)
        self.horizontalLayout_2 = QtWidgets.QHBoxLayout()
        self.horizontalLayout_2.setContentsMargins(10, -1, -1, -1)
        self.horizontalLayout_2.setObjectName("horizontalLayout_2")
        self.mod_RB = QtWidgets.QRadioButton(self.verticalLayoutWidget)
        self.mod_RB.setEnabled(True)
        self.mod_RB.setMinimumSize(QtCore.QSize(106, 0))
        self.mod_RB.setCheckable(True)
        self.mod_RB.setChecked(False)
        self.mod_RB.setAutoExclusive(True)
        self.mod_RB.setObjectName("mod_RB")
        self.horizontalLayout_2.addWidget(self.mod_RB)
        self.rig_RB = QtWidgets.QRadioButton(self.verticalLayoutWidget)
        self.rig_RB.setEnabled(True)
        self.rig_RB.setMinimumSize(QtCore.QSize(106, 0))
        self.rig_RB.setChecked(True)
        self.rig_RB.setAutoExclusive(True)
        self.rig_RB.setObjectName("rig_RB")
        self.horizontalLayout_2.addWidget(self.rig_RB)
        self.srf_RB = QtWidgets.QRadioButton(self.verticalLayoutWidget)
        self.srf_RB.setEnabled(True)
        self.srf_RB.setMinimumSize(QtCore.QSize(106, 0))
        self.srf_RB.setCheckable(True)
        self.srf_RB.setAutoExclusive(True)
        self.srf_RB.setObjectName("srf_RB")
        self.horizontalLayout_2.addWidget(self.srf_RB)
        self.verticalLayout.addLayout(self.horizontalLayout_2)
        spacerItem1 = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding)
        self.verticalLayout.addItem(spacerItem1)

        self.retranslateUi(Main_Window)
        self.shot_RB.toggled['bool'].connect(self.cfx_RB.setVisible)
        self.shot_RB.toggled['bool'].connect(self.ani_RB.setVisible)
        self.ass_RB.toggled['bool'].connect(self.srf_RB.setVisible)
        self.ass_RB.toggled['bool'].connect(self.rig_RB.setVisible)
        self.ass_RB.toggled['bool'].connect(self.mod_RB.setVisible)
        self.shot_RB.toggled['bool'].connect(self.lay_RB.setVisible)
        QtCore.QMetaObject.connectSlotsByName(Main_Window)
        Main_Window.setTabOrder(self.ass_RB, self.shot_RB)
        Main_Window.setTabOrder(self.shot_RB, self.lay_RB)
        Main_Window.setTabOrder(self.lay_RB, self.ani_RB)
        Main_Window.setTabOrder(self.ani_RB, self.cfx_RB)
        Main_Window.setTabOrder(self.cfx_RB, self.mod_RB)
        Main_Window.setTabOrder(self.mod_RB, self.rig_RB)
        Main_Window.setTabOrder(self.rig_RB, self.srf_RB)
        Main_Window.setTabOrder(self.srf_RB, self.path_LE)
        Main_Window.setTabOrder(self.path_LE, self.path_B)
        Main_Window.setTabOrder(self.path_B, self.task_LE)
        Main_Window.setTabOrder(self.task_LE, self.run_B)

    def retranslateUi(self, Main_Window):
        _translate = QtCore.QCoreApplication.translate
        Main_Window.setWindowTitle(_translate("Main_Window", "打包工具"))
        self.ass_RB.setText(_translate("Main_Window", "asset"))
        self.shot_RB.setText(_translate("Main_Window", "shot"))
        self.task_LE.setText(_translate("Main_Window", "输入镜头号,用英文逗号间隔"))
        self.run_B.setText(_translate("Main_Window", "打包"))
        self.path_LE.setText(_translate("Main_Window", "默认在桌面"))
        self.path_B.setText(_translate("Main_Window", " 存放路径 "))
        self.lay_RB.setText(_translate("Main_Window", "lay"))
        self.ani_RB.setText(_translate("Main_Window", "ani"))
        self.cfx_RB.setText(_translate("Main_Window", "cfx"))
        self.mod_RB.setText(_translate("Main_Window", "mod"))
        self.rig_RB.setText(_translate("Main_Window", "rig"))
        self.srf_RB.setText(_translate("Main_Window", "srf"))


if __name__ == "__main__":
    print("do")
    import sys
    app = QtWidgets.QApplication(sys.argv)
    MainWindow = QtWidgets.QMainWindow()
    ui = Ui_Main_Window()
    ui.setupUi(MainWindow)
    ui.retranslateUi(MainWindow)

    MainWindow.show()
    sys.exit(app.exec_())
  • 然后这是实现功能的py,功能部分为了方便观看用print代替了
# -*- coding: utf-8 -*-
# .@FileName:main
# @Date....:2019-10-28  22:37   
# ..:XingLian	
import pprint # 用于打印dir的结果,一个方法一行看起来更清晰m明了
import window # ui文件的名字
import sys

from PySide2 import QtWidgets
from PySide2.QtWidgets import QFileDialog
from PySide2.QtWidgets import QMainWindow

class ShowWindow(QMainWindow, window.Ui_Main_Window):
    def __init__(self):
        super(ShowWindow, self).__init__()  # 安装 QMainWindow 窗口
        self.setupUi(self)  # 执行父类中的setupUi方法,方法的参数是第二步中创建的QMainWindow
        self.setup_ui2()
        self.show()  # 执行QMainWindow的show()方法,显示这个QMainWindow

    def setup_ui2(self):
    # 这里是控件的编辑,默认隐藏designer是画不出来的,只能编辑代码
        self.ani_RB.hide()
        self.lay_RB.hide()
        self.cfx_RB.hide()
        self.path_LE.setReadOnly(1)
        
    def signal_connect(self):
    # 链接信号与槽,将按钮的点击信号链接到命令上
        # pprint.pprint(dir(self.path_B))
        # 碰到不记得拼写的命令记得dir跟Google
        self.path_B.clicked.connect(self.set_path_common)
        self.run_B.clicked.connect(self.main_common)

    def get_rb_sl(self):
        for i in ['cfx', 'ani', 'lay', 'mod', 'rig', 'srf']:
            rb_sl_str = rf'self.{i}_RB.isChecked()'
            if eval(rb_sl_str):
                return eval(rf'self.{i}_RB.text()')

    def set_path_common(self):
        selected_directory = QFileDialog.getExistingDirectory(self, "选取文件夹", shot_num_list.get_desktop())
        self.path_LE.setText(selected_directory)

    def main_common(self):
        typ = self.get_rb_sl()
        task_list = self.task_LE.text().split(',')
        opath = self.path_LE.text()
        if opath == '默认在桌面':
            opath = shot_num_list.get_desktop()

        for task in task_list:
            print(typ, task, opath)
        #     self.do_zip_common(typ, task, opath)


  app = QtWidgets.QApplication(sys.argv)
  foo = ShowWindow()
  sys.exit(app.exec_())

你可能感兴趣的:(TD课程汇总【五】首个PyQt窗口的实现)