PyQt5 入门

2022-05-10 10:00:53 浏览数 (1)

文章目录
  • 1. 安装测试
  • 2. qt 设计师 designer
  • 3. 布局管理
    • 3.1 使用布局管理器布局
    • 3.2 使用容器布局
    • 3.3 实践
    • 3.4 窗体布局
    • 3.5 设置伙伴关系
    • 3.6 tab键顺序
    • 3.7 Eric 使用
  • 4. 信号、槽关联
    • 4.1 简单入门
    • 4.2 进阶
  • 5. 菜单与工具
    • 5.1 加载其他窗口
      • 主窗体 py
      • 子窗口 py
      • 调用主程序 py
      • 测试
  • 6. 打包资源

learn from 《PyQt5 快速开发与实战》

1. 安装测试

代码语言:javascript复制
# _*_ coding: utf-8 _*_
# @Time : 2022/4/4 23:11
# @Author : Michael
# @File : myfirst_qt1.py
# @desc :

# 安装 pip install pyqt5, pyqt5-tools

import sys
from PyQt5 import QtWidgets, QtCore

app = QtWidgets.QApplication(sys.argv)
widget = QtWidgets.QWidget()
widget.resize(360, 360)
widget.setWindowTitle('hello Michael, First Qt 应用')
widget.show()
sys.exit(app.exec_())
代码语言:javascript复制
# _*_ coding: utf-8 _*_
# @Time : 2022/4/4 23:26
# @Author : Michael
# @File : first_window.py
# @desc :
import sys
from PyQt5.QtWidgets import QApplication, QWidget, QPushButton, QMessageBox

class winform(QWidget):
    def __init__(self, parent=None):
        super(winform, self).__init__(parent)
        self.setGeometry(100, 100, 700, 350) # 窗口左上角的坐标,窗口宽高
        self.setWindowTitle('第一个窗口')
        quit = QPushButton('点击退出', self)
        quit.setGeometry(20, 10, 100, 35)
        quit.setStyleSheet("background-color: brown")
        quit.clicked.connect(self.close)

if __name__ == "__main__":
    app = QApplication(sys.argv)
    win = winform()
    win.show()
    sys.exit(app.exec_())

2. qt 设计师 designer

我的路径是:D:ProgramDataAnaconda3envscvLibsite-packagesqt5_applicationsQtbindesigner.exe

拖出一个按钮

保存 firstwindow.ui 文件,可以转成 py 代码

代码语言:javascript复制
pyuic5 -o firstui.py firstwindow.ui 

3. 布局管理

3.1 使用布局管理器布局

3.2 使用容器布局

右键下图 Frame 进行水平 布局

3.3 实践

拖出一些控件

左侧(有四个label,最上面一个显示的字符为空),进行垂直布局

spacers 表示布局不要挨在一起

display Widgets -> Vertical Line 表示左右两个布局管理器不是同一个类别,把他们区分开

选中所有布局,右键,水平布局

3.4 窗体布局

不选中任务控件,右键选择布局

打破布局:布局错了很多步,比撤销方便

3.5 设置伙伴关系

3.6 tab键顺序

3.7 Eric 使用

Eric6安装使用

使用 eric 可以快速的调试 UI 界面

编译完,会自动生成脚本,点击运行

4. 信号、槽关联

信号发射,连接的槽函数将会自动执行,连接使用QObject.signal.connect()

添加方法:

  • 窗口UI设计中添加
  • 写代码连接信号、槽
  • Eric “生成对话框代码”的功能

4.1 简单入门

创建 Widget 窗口,实现一个关闭按钮

拖入button,更改 text 为显示的文字,更改objectName 为 closeWin

使用 Eric 测试

4.2 进阶

接下来可以使用 命令行编译窗体,也可以使用 Eric “生成对话框代码”,使用后者来操作

右键ui文件,先编译窗体,再生成对话框代码

文件夹下多了一个 py 文件

代码语言:javascript复制
# -*- coding: utf-8 -*-

"""
Module implementing Form.
"""

from PyQt5.QtCore import pyqtSlot
from PyQt5.QtWidgets import QWidget

from .Ui_signal_slog1 import Ui_Form


class Form(QWidget, Ui_Form):
    """
    Class documentation goes here.
    """
    def __init__(self, parent=None):
        """
        Constructor
        
        @param parent reference to the parent widget (defaults to None)
        @type QWidget (optional)
        """
        super(Form, self).__init__(parent)
        self.setupUi(self)
    
    @pyqtSlot(bool)
    def on_select_box_clicked(self, checked):
        """
        Slot documentation goes here.
        
        @param checked DESCRIPTION
        @type bool
        """
        # TODO: not implemented yet
        raise NotImplementedError

上面代码还没有实现,修改代码后:

代码语言:javascript复制
# -*- coding: utf-8 -*-

"""
Module implementing Form.
"""

from PyQt5.QtCore import pyqtSlot
from PyQt5.QtWidgets import QWidget
from PyQt5 import QtCore, QtGui, QtWidgets
from Ui_signal_slog1 import Ui_Form


class Form(QWidget, Ui_Form):
    """
    Class documentation goes here.
    """
    def __init__(self, parent=None):
        """
        Constructor
        
        @param parent reference to the parent widget (defaults to None)
        @type QWidget (optional)
        """
        super(Form, self).__init__(parent)
        self.setupUi(self)
        self.select_box.setChecked(True) # 设置默认是选中状态
    
    @pyqtSlot(bool)
    def on_select_box_clicked(self, checked):
        """
        Slot documentation goes here.
        
        @param checked DESCRIPTION
        @type bool
        """
        self.label_display.setVisible(checked)
        self.lineEdit.setEnabled(checked)
if __name__ == '__main__':
    import sys
    app = QtWidgets.QApplication(sys.argv)
    form = Form()
    form.show()
    sys.exit(app.exec_())

也可以在 Qt 中编辑

5. 菜单与工具

新建 mainWindow

输入 文件(&F)括号内是快捷键设置

子菜单

添加快捷键

添加工具栏

添加动作

添加信号、槽

代码语言:javascript复制
# -*- coding: utf-8 -*-

# Form implementation generated from reading ui file 'D:gitcodePython_learningqtch1menu_bar_tool_bar.ui'
#
# Created by: PyQt5 UI code generator 5.15.4
#
# WARNING: Any manual changes made to this file will be lost when pyuic5 is
# run again.  Do not edit this file unless you know what you are doing.

# Ui_menu_bar_tool_bar.py

from PyQt5 import QtCore, QtGui, QtWidgets


class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(422, 161)
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        MainWindow.setCentralWidget(self.centralwidget)
        self.menubar = QtWidgets.QMenuBar(MainWindow)
        self.menubar.setGeometry(QtCore.QRect(0, 0, 422, 26))
        self.menubar.setObjectName("menubar")
        self.menu_F = QtWidgets.QMenu(self.menubar)
        self.menu_F.setObjectName("menu_F")
        self.menu = QtWidgets.QMenu(self.menubar)
        self.menu.setObjectName("menu")
        MainWindow.setMenuBar(self.menubar)
        self.statusbar = QtWidgets.QStatusBar(MainWindow)
        self.statusbar.setObjectName("statusbar")
        MainWindow.setStatusBar(self.statusbar)
        self.toolBar = QtWidgets.QToolBar(MainWindow)
        self.toolBar.setObjectName("toolBar")
        MainWindow.addToolBar(QtCore.Qt.TopToolBarArea, self.toolBar)
        self.actionopen_O = QtWidgets.QAction(MainWindow)
        self.actionopen_O.setObjectName("actionopen_O")
        self.actionnew_N = QtWidgets.QAction(MainWindow)
        self.actionnew_N.setObjectName("actionnew_N")
        self.actionclose = QtWidgets.QAction(MainWindow)
        self.actionclose.setObjectName("actionclose")
        self.addWinAction = QtWidgets.QAction(MainWindow)
        self.addWinAction.setObjectName("addWinAction")
        self.menu_F.addAction(self.actionopen_O)
        self.menu_F.addAction(self.actionnew_N)
        self.menu_F.addAction(self.actionclose)
        self.menubar.addAction(self.menu_F.menuAction())
        self.menubar.addAction(self.menu.menuAction())
        self.toolBar.addAction(self.addWinAction)

        self.retranslateUi(MainWindow)
        self.actionclose.triggered.connect(MainWindow.close)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
        self.menu_F.setTitle(_translate("MainWindow", "文件(&F)"))
        self.menu.setTitle(_translate("MainWindow", "编辑(E)"))
        self.toolBar.setWindowTitle(_translate("MainWindow", "toolBar"))
        self.actionopen_O.setText(_translate("MainWindow", "open(O)"))
        self.actionopen_O.setShortcut(_translate("MainWindow", "Ctrl O"))
        self.actionnew_N.setText(_translate("MainWindow", "new(N)"))
        self.actionclose.setText(_translate("MainWindow", "close"))
        self.addWinAction.setText(_translate("MainWindow", "添加窗体"))


if __name__ == "__main__":
    import sys
    app = QtWidgets.QApplication(sys.argv)
    MainWindow = QtWidgets.QMainWindow()
    ui = Ui_MainWindow()
    ui.setupUi(MainWindow)
    MainWindow.show()
    sys.exit(app.exec_())
代码语言:javascript复制
# -*- coding: utf-8 -*-
# menu_bar_tool_bar.py
"""
Module implementing MainWindow.
"""

import sys
from PyQt5.QtCore import pyqtSlot
from PyQt5.QtWidgets import QMainWindow, QApplication, QFileDialog

from Ui_menu_bar_tool_bar import Ui_MainWindow


class MainWindow(QMainWindow, Ui_MainWindow):
    """
    Class documentation goes here.
    """
    def __init__(self, parent=None):
        """
        Constructor
        
        @param parent reference to the parent widget (defaults to None)
        @type QWidget (optional)
        """
        super(MainWindow, self).__init__(parent)
        self.setupUi(self)
        self.actionclose.triggered.connect(self.on_actionclose_triggered)
        self.actionopen_O.triggered.connect(self.on_actionopen_O_triggered)
    
    @pyqtSlot()
    def on_actionnew_N_triggered(self):
        """
        Slot documentation goes here.
        """
        # TODO: not implemented yet
        raise NotImplementedError
    
    @pyqtSlot()
    def on_actionclose_triggered(self):
        """
        Slot documentation goes here.
        """
        self.statusbar.showMessage("再见!")
    
    @pyqtSlot()
    def on_actionopen_O_triggered(self):
        """
        Slot documentation goes here.
        """
        file,  ok = QFileDialog.getOpenFileName(self,  "打开",  "D:/",  "ALL Files(*);; Text Files(*TxT)")
        self.statusbar.showMessage(file)

if __name__  == "__main__":
    app = QApplication(sys.argv)
    win = MainWindow()
    win.show()
    sys.exit(app.exec_())

5.1 加载其他窗口

  • 新建 ui

使用 Eric 编译两个 UI 文件,并做修改

主窗体 py
代码语言:javascript复制
# -*- coding: utf-8 -*-

# Form implementation generated from reading ui file 'D:gitcodePython_learningqtch1menu_bar_tool_bar.ui'
#
# Created by: PyQt5 UI code generator 5.15.4
#
# WARNING: Any manual changes made to this file will be lost when pyuic5 is
# run again.  Do not edit this file unless you know what you are doing.

# Ui_menu_bar_tool_bar.py

from PyQt5 import QtCore, QtGui, QtWidgets


class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(401, 328)
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.gridLayoutWidget = QtWidgets.QWidget(self.centralwidget)
        self.gridLayoutWidget.setGeometry(QtCore.QRect(-1, -1, 611, 441))
        self.gridLayoutWidget.setObjectName("gridLayoutWidget")
        self.gridlayout1 = QtWidgets.QGridLayout(self.gridLayoutWidget)
        self.gridlayout1.setContentsMargins(0, 0, 0, 0)
        self.gridlayout1.setObjectName("gridlayout1")
        MainWindow.setCentralWidget(self.centralwidget)
        self.menubar = QtWidgets.QMenuBar(MainWindow)
        self.menubar.setGeometry(QtCore.QRect(0, 0, 401, 26))
        self.menubar.setObjectName("menubar")
        self.menu_F = QtWidgets.QMenu(self.menubar)
        self.menu_F.setObjectName("menu_F")
        self.menu = QtWidgets.QMenu(self.menubar)
        self.menu.setObjectName("menu")
        MainWindow.setMenuBar(self.menubar)
        self.statusbar = QtWidgets.QStatusBar(MainWindow)
        self.statusbar.setObjectName("statusbar")
        MainWindow.setStatusBar(self.statusbar)
        self.toolBar = QtWidgets.QToolBar(MainWindow)
        self.toolBar.setObjectName("toolBar")
        MainWindow.addToolBar(QtCore.Qt.TopToolBarArea, self.toolBar)
        self.actionopen_O = QtWidgets.QAction(MainWindow)
        self.actionopen_O.setObjectName("actionopen_O")
        self.actionnew_N = QtWidgets.QAction(MainWindow)
        self.actionnew_N.setObjectName("actionnew_N")
        self.actionclose = QtWidgets.QAction(MainWindow)
        self.actionclose.setObjectName("actionclose")
        self.addWinAction = QtWidgets.QAction(MainWindow)
        self.addWinAction.setObjectName("addWinAction")
        self.menu_F.addAction(self.actionopen_O)
        self.menu_F.addAction(self.actionnew_N)
        self.menu_F.addAction(self.actionclose)
        self.menubar.addAction(self.menu_F.menuAction())
        self.menubar.addAction(self.menu.menuAction())
        self.toolBar.addAction(self.addWinAction)

        self.retranslateUi(MainWindow)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
        self.menu_F.setTitle(_translate("MainWindow", "文件(&F)"))
        self.menu.setTitle(_translate("MainWindow", "编辑(E)"))
        self.toolBar.setWindowTitle(_translate("MainWindow", "toolBar"))
        self.actionopen_O.setText(_translate("MainWindow", "open(O)"))
        self.actionopen_O.setShortcut(_translate("MainWindow", "Ctrl O"))
        self.actionnew_N.setText(_translate("MainWindow", "new(N)"))
        self.actionclose.setText(_translate("MainWindow", "close"))
        self.addWinAction.setText(_translate("MainWindow", "添加窗体"))


if __name__ == "__main__":
    import sys
    app = QtWidgets.QApplication(sys.argv)
    MainWindow = QtWidgets.QMainWindow()
    ui = Ui_MainWindow()
    ui.setupUi(MainWindow)
    MainWindow.show()
    sys.exit(app.exec_())
子窗口 py
代码语言:javascript复制
# -*- coding: utf-8 -*-

# Form implementation generated from reading ui file 'D:gitcodePython_learningqtch1childform2.ui'
#
# Created by: PyQt5 UI code generator 5.15.4
#
# WARNING: Any manual changes made to this file will be lost when pyuic5 is
# run again.  Do not edit this file unless you know what you are doing.

# Ui_childform2.py

from PyQt5 import QtCore, QtGui, QtWidgets


class ui_childform(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(479, 332)
        MainWindow.setStyleSheet("")

        self.textEdit = QtWidgets.QTextEdit(MainWindow)
        self.textEdit.setGeometry(QtCore.QRect(90, 100, 131, 31))
        self.textEdit.setObjectName("textEdit")

        self.retranslateUi(MainWindow)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "Form"))
        self.textEdit.setHtml(_translate("MainWindow", "<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">n"
"<html><head><meta name="qrichtext" content="1" /><style type="text/css">n"
"p, li { white-space: pre-wrap; }n"
"</style></head><body style=" font-family:'SimSun'; font-size:9pt; font-weight:400; font-style:normal;">n"
"<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">我是子窗口内容</p></body></html>"))


if __name__ == "__main__":
    import sys
    app = QtWidgets.QApplication(sys.argv)
    MainWindow = QtWidgets.QMainWindow()
    ui = ui_childform()
    ui.setupUi(MainWindow)
    MainWindow.show()
    sys.exit(app.exec_())
调用主程序 py
代码语言:javascript复制
# -*- coding: utf-8 -*-
# childform2.py

import sys
from PyQt5.QtCore import pyqtSlot
from PyQt5.QtWidgets import QMainWindow, QWidget, QApplication, QFileDialog
from Ui_childform2 import ui_childform
from Ui_menu_bar_tool_bar import Ui_MainWindow


class MainWindow_withchild(QMainWindow, Ui_MainWindow):

    def __init__(self, parent=None):
        super(MainWindow_withchild, self).__init__(parent)
        self.setupUi(self)

        self.child = my_childform()  # 创建子窗口实例
        self.actionclose.triggered.connect(self.close)
        self.actionopen_O.triggered.connect(self.openMsg)
        self.addWinAction.triggered.connect(self.childshow)

    def childshow(self):
        self.gridlayout1.addWidget(self.child)
        self.child.show()

    def openMsg(self):
        file, ok = QFileDialog.getOpenFileName(self, "打开", "C:/", "All Files (*);;Text Files (*.txt)")
        # 在状态栏显示文件地址
        self.statusbar.showMessage(file)


class my_childform(QWidget, ui_childform):
    def __init__(self):
        super(my_childform, self).__init__()
        self.setupUi(self)


if __name__ == "__main__":
    app = QApplication(sys.argv)
    win = MainWindow_withchild()
    win.show()
    sys.exit(app.exec_())
测试

6. 打包资源

将资源转换成 python 文件

步骤:

  • 新建资源
  • Qt 新建 widget 窗口,添加资源
  • 查看文件
代码语言:javascript复制
<RCC>
  <qresource prefix="img">
    <file>img/1.jpg</file>
  </qresource>
</RCC>
  • 使用文件
  • 转换 ui 到 py文件,使用 eric 操作,或者使用命令行
  • 转换资源文件 pyrcc5 .apprcc.qrc -o apprcc_rc.py
  • import 导入生成的文件 apprcc_rc.py
代码语言:javascript复制
# -*- coding: utf-8 -*-

# Form implementation generated from reading ui file 'D:gitcodePython_learningqtch1add_resource.ui'
#
# Created by: PyQt5 UI code generator 5.15.4
#
# WARNING: Any manual changes made to this file will be lost when pyuic5 is
# run again.  Do not edit this file unless you know what you are doing.


# Ui_add_resource.py

from PyQt5 import QtCore, QtGui, QtWidgets


class Ui_Form(object):
    def setupUi(self, Form):
        Form.setObjectName("Form")
        Form.resize(400, 300)
        self.label = QtWidgets.QLabel(Form)
        self.label.setGeometry(QtCore.QRect(30, 30, 351, 231))
        self.label.setText("")
        self.label.setPixmap(QtGui.QPixmap(":/img/img/1.jpg"))
        self.label.setObjectName("label")

        self.retranslateUi(Form)
        QtCore.QMetaObject.connectSlotsByName(Form)

    def retranslateUi(self, Form):
        _translate = QtCore.QCoreApplication.translate
        Form.setWindowTitle(_translate("Form", "Form"))
import apprcc_rc


if __name__ == "__main__":
    import sys
    app = QtWidgets.QApplication(sys.argv)
    Form = QtWidgets.QWidget()
    ui = Ui_Form()
    ui.setupUi(Form)
    Form.show()
    sys.exit(app.exec_())

调用

代码语言:javascript复制
# -*- coding: utf-8 -*-
# add_resource.py

from PyQt5.QtCore import pyqtSlot
from PyQt5.QtWidgets import QWidget, QApplication

from Ui_add_resource import Ui_Form


class Form(QWidget, Ui_Form):
    """
    Class documentation goes here.
    """
    def __init__(self, parent=None):
        """
        Constructor
        
        @param parent reference to the parent widget (defaults to None)
        @type QWidget (optional)
        """
        super(Form, self).__init__(parent)
        self.setupUi(self)

if __name__ == "__main__":
    import sys
    app = QApplication(sys.argv)
    form = Form()
    form.show()
    sys.exit(app.exec_())

0 人点赞