PyQT5介绍及基本使用

news2024/11/15 19:58:02

文章目录

  • PyQt5
    • 1. PyQt5的下载与安装
      • 1.1 PyQt5介绍
      • 1.2 windows PyQt5的安装
    • 2.PyQt5基本UI
      • 2.1 第一个PyQt程序
      • 2.2 argv
      • 2.3 模块介绍
    • 3.基本UI
      • 3.1 按钮QPushButton
      • 3.2 文本QLabel
      • 3.3 输入框
      • 3.4 调整窗口大小
      • 3.5 调整窗口显示屏幕中间
      • 3.6 设置窗口icon
    • 4.布局
      • 4.1 QBoxLayout
        • 4.1.1 垂直布局
        • 4.1.2 水平布局
      • 4.2 QGridLayout
        • 网格布局
      • 4.3 QFormLayout
      • 4.4 抽屉布局
    • 5. 窗口
      • 5.1 分类
      • 5.2 QWidget
      • 5.2 QMainWindow
      • 5.3 QDialog
    • 6. 信号与槽
      • 6.1 信号与槽介绍
      • 6.2 案例
      • 6.3 自定义信号
    • 7.Qt Designer
      • 7.1 介绍
      • 7.2 下载
      • 7.3 安装&运行
      • 7.4 使用QT Designer
      • 7.5 使用流程

PyQt5

1. PyQt5的下载与安装

1.1 PyQt5介绍

Qt(官方发音 [kju:t])是一个跨平台的C++开发库,主要用来开发图形用户界面(Graphical User Interface,GUI)程序

Qt 是纯 C++ 开发的,正常情况下需要先学习C语言、然后在学习C++然后才能使用Qt开发带界面的程序

多亏了开源社区使得Qt 还可以用Python、Ruby、Perl 等脚本语言进行开发。

Qt 支持的操作系统有很多,例如通用操作系统 Windows、Linux、Unix,智能手机系统Android、iOS, 嵌入式系统等等。可以说是跨平台的

QT官网:https://doc.qt.io/qt-5/index.html

PyQt的开发者是英国的“Riverbank Computing”公司。它提供了GPL(简单的说,以GPL协议发布到网上的素材,你可以使用,也可以更改,但是经过你更改然后再次发布的素材必须也遵守GPL协议,主要要求是必须开源,而且不能删减原作者的声明信息等)与商业协议两种授权方式,因此它可以免费地用于自由软件的开发。

PyQt可以运行于Microsoft Windows、Mac OS X、Linux以及Unix的多数变种上

PyQt是Python语言的GUI(Graphical User Interface,简称 GUI,又称图形用户接口)编程解决方案之一

可以用来代替Python内置的Tkinter。其它替代者还有PyGTKwxPython等,与Qt一样,PyQt是一个自由软件

文档相关地址:https://www.riverbankcomputing.com/software/pyqt/

比较不错的参考资料:https://wiki.python.org/moin/PyQt/Tutorials

  • Qt (C++ 语言 GUI )

  • PyQt = Python + Qt技术

  • Tkinter

    Python官方采用的标准库,优点是作为Python标准库、稳定、发布程序较小,缺点是控件相对较少。

  • wxPython

    基于wxWidgets的Python库,优点是控件比较丰富,缺点是稳定性相对差点、文档少、用户少。

  • PySide2、PyQt5

    基于Qt 的Python库,优点是控件比较丰富、跨平台体验好、文档完善、用户多。

    缺点是 库比较大,发布出来的程序比较大。

    PyQt5 的开发者是英国的“Riverbank Computing”公司 , 而 PySide2 则是 qt 针对python语言提供的专门

1.2 windows PyQt5的安装

  1. 执行命令,允许创建虚拟环境
pip install virtualenv
pip install virtualenvwrapper-win
  1. 创建新的虚拟环境
mkvirtualenv -p python3 py3-qt --no-download
  1. 安装pyqt5(命令行)
workon py3-qt  #切换到py3-qt环境
pip install pyqt5 -i https://pypi.tuna.tsinghua.edu.cn/simple

image-20230515225937502

  1. 版本测试
# 如果执行成功,没有任何错误提示,则表明环境搭建成功
from PyQt5 import QtWidgets

# 当然也可以查看PyQt版本
from PyQt5.QtCore import *


print(QT_VERSION_STR)

image-20230515230526200

  • pip加速国内镜像
阿里云  https://mirrors.aliyun.com/pypi/simple/

中国科技大学 https://pypi.mirrors.ustc.edu.cn/simple/

豆瓣(douban) https://pypi.douban.com/simple/

清华大学 https://pypi.tuna.tsinghua.edu.cn/simple/

中国科学技术大学 https://pypi.mirrors.ustc.edu.cn/simple/

2.PyQt5基本UI

2.1 第一个PyQt程序

import sys

from PyQt5.QtWidgets import QApplication, QWidget # 1.导入模块

if __name__ == '__main__':
    # 2.创建一个 QApplication 对象,指向QApplication ,接受命令行参数

    app = QApplication(sys.argv)
    #  3. 创建一个  QWidget对象
    w = QWidget()

    # 4. 设置窗口标题
    w.setWindowTitle("第一个PyQt")

    # 5. 展示窗口
    w.show()

    # 程序进行循环等待状态
    app.exec()

image-20230515230700956

2.2 argv

import sys

print(sys.argv)

image-20230515231412243

2.3 模块介绍

PyQt中有非常多的功能模块,开发中最常用的功能模块主要有三个:

  • QtCore:包含了核心的非GUI的功能。主要和时间、文件与文件夹、各种数据、流、URLs、mime类文件、进程与线程一起使用
  • QtGui:包含了窗口系统、事件处理、2D图像、基本绘画、字体和文字类
  • QtWidgets:包含了一些列创建桌面应用的UI元素

可以参考PyQt官网的所有模块,地址:https://www.riverbankcomputing.com/static/Docs/PyQt5/module_index.html#ref-module-index

C++具体实现的API文档,地址:https://doc.qt.io/qt-5/qtwidgets-module.html

用到什么功能就它相关的api或者别人分享的使用心得,这是学习最快的方式

3.基本UI

窗口内的所有控件,若想在窗口中显示,都需要表示它的父亲是谁,而不能直接使用 show 函数显示

3.1 按钮QPushButton

import sys

from PyQt5.QtWidgets import QApplication, QWidget, QPushButton

if __name__ == '__main__':
    app = QApplication(sys.argv)

    w = QWidget()

    # 设置窗口标题
    w.setWindowTitle("第一个PyQt程序")

    # 在窗口里面添加控件
    btn = QPushButton("按钮")

    # 设置按钮的父亲是当前窗口,等于是添加到窗口中显示
    btn.setParent(w)

    # 展示窗口
    w.show()

    # 程序进行循环等待状态
    app.exec()

image-20230515231855120

3.2 文本QLabel

纯文本控件名称为 QLabel , 位于 PyQt5.QtWidgets 里面

纯文本控件仅仅作为标识显示而已,类似输入内容前的一段标签提示(账号 、密码)

import sys
from PyQt5.QtWidgets import QApplication, QWidget, QPushButton, QLabel
if __name__ == '__main__':
    app = QApplication(sys.argv)

    w = QWidget()

    # 设置窗口标题
    w.setWindowTitle("第一个PyQt")

    # # 下面创建一个Label,然后调用方法指定父类
    # label = QLabel("账号: ", w)
    # # 设置父对象
    # label.setParent(w)

    # 下面创建一个Label(纯文本),在创建的时候指定了父对象
    label = QLabel("账号: ", w)

    # 显示位置与大小 : x, y , w, h
    label.setGeometry(20, 20, 30, 30)

    # 展示窗口
    w.show()

    # 程序进行循环等待状态
    app.exec()

image-20230515232214756

import sys

from PyQt5.QtWidgets import QApplication, QWidget, QPushButton, QLabel

if __name__ == '__main__':
    app = QApplication(sys.argv)

    w = QWidget()

    # 设置窗口标题
    w.setWindowTitle("第一个PyQt")

    # # 下面创建一个Label,然后调用方法指定父类
    # label = QLabel("账号: ", w)
    # 设置父对象
    # label.setParent(w)

    # 下面创建一个Label(纯文本),在创建的时候指定了父对象
    label = QLabel("账号: ", w)

    # 显示位置与大小 : x, y , w, h
    label.setGeometry(20, 20, 30, 30)

    # 展示窗口
    w.show()

    # 程序进行循环等待状态
    app.exec()

image-20230515232244255

3.3 输入框

import sys

from PyQt5.QtWidgets import QApplication, QWidget, QPushButton, QLabel, QLineEdit

if __name__ == '__main__':
    app = QApplication(sys.argv)

    w = QWidget()

    # 设置窗口标题
    w.setWindowTitle("第一个PyQt")

    # 纯文本
    label = QLabel("账号", w)
    label.setGeometry(20, 20, 30, 20)

    # 文本框
    edit = QLineEdit(w)
    edit.setPlaceholderText("请输入账号")
    edit.setGeometry(55, 20, 200, 20)

    # 在窗口里面添加控件
    btn = QPushButton("注册", w)
    # x,y,w,h
    btn.setGeometry(50, 80, 70, 30)

    # 展示窗口
    w.show()

    # 程序进行循环等待状态
    app.exec()

3.4 调整窗口大小

  • resize
import sys

from PyQt5.QtWidgets import QApplication, QWidget, QPushButton, QLabel, QLineEdit

if __name__ == '__main__':
    app = QApplication(sys.argv)
    w = QWidget()
    # 设置窗口标题
    w.setWindowTitle("第一个PyQt5程序")

    # 窗口的大小
    w.resize(500,500)
    # 纯文本
    label = QLabel("账号", w)
    # 设置位置x,y,w,h
    label.setGeometry(20, 20, 30, 20)
    # 文本框
    edit = QLineEdit(w)
    edit.setPlaceholderText("请输入账号")
    edit.setGeometry(55, 20, 200, 20)
    # 在窗口里面添加控件
    btn = QPushButton("注册", w)
    btn.setGeometry(50, 80, 70, 30)
    # 展示窗口
    w.show()
    # 程序进行循环等待状态
    app.exec()

3.5 调整窗口显示屏幕中间

  • move:移动屏幕
import sys

from PyQt5.QtWidgets import QApplication, QWidget, QPushButton, QLabel, QLineEdit,QDesktopWidget

if __name__ == '__main__':
    app = QApplication(sys.argv)
    w = QWidget()
    # 设置窗口标题
    w.setWindowTitle("第一个PyQt5程序")

    # 窗口的大小
    w.resize(500,500)

    # 调整到左上角
    # w.move(0,0)

    # 获取屏幕中心点
    center = QDesktopWidget().availableGeometry().center()
    print("center:",center)
    x = center.x()
    y = center.y()
    # print(x/2,y/2)
    w.move(x//2,y//2)
    # 纯文本

    print(w.frameSize())
    print(w.frameGeometry())
    print(w.frameGeometry().getRect())

    # 居中显示
    old_x,old_y,width,height = w.frameGeometry().getRect()
    w.move(x-width//2,y-height//2)


    label = QLabel("账号", w)
    # 设置位置x,y,w,h
    label.setGeometry(20, 20, 30, 20)
    # 文本框
    edit = QLineEdit(w)
    edit.setPlaceholderText("请输入账号")
    edit.setGeometry(55, 20, 200, 20)
    # 在窗口里面添加控件
    btn = QPushButton("注册", w)
    btn.setGeometry(50, 80, 70, 30)
    # 展示窗口
    w.show()
    # 程序进行循环等待状态
    app.exec()

image-20230519234729204

3.6 设置窗口icon

可下载icon网址

import sys

from PyQt5.QtGui import QIcon
from PyQt5.QtWidgets import QApplication, QWidget

if __name__ == '__main__':
    app = QApplication(sys.argv)

    # 创建一个QWidget
    w = QWidget()
    # 设置标题
    w.setWindowTitle("看看我图标帅吗")
    # 设置图标
    w.setWindowIcon(QIcon('test.jpg'))
    # 显示QWidget
    w.show()

    app.exec()

image-20230519235041396

4.布局

在Qt里面布局分为四个大类 :

  • QBoxLayout
  • QGridLayout
  • QFormLayout
  • QStackedLayout

4.1 QBoxLayout

直译为:盒子布局

一般使用它的两个子类QHBoxLayoutQVBoxLayout 负责水平和垂直布局

4.1.1 垂直布局

import sys
from PyQt5.QtWidgets import QApplication, QVBoxLayout, QWidget, QPushButton, QGroupBox, QMainWindow
from PyQt5.QtCore import Qt


class MyWindow(QWidget):
    def __init__(self):
        # 切记一定要调用父类的__init__方法,因为它里面有很多对UI空间的初始化操作
        super().__init__()
        # 设置大小
        self.resize(300, 300)
        # 设置标题
        self.setWindowTitle("垂直布局")
        # 垂直布局
        layout = QVBoxLayout()

        # 作用是在布局器中增加一个伸缩量,里面的参数表示QSpacerItem的个数,默认值为零
        # 会将你放在layout中的空间压缩成默认的大小

        # 下面的笔试1:1:1:2 : 2
        layout.addStretch(1)
        # 按钮1
        btn1 = QPushButton("按钮1")
        # 添加到布局器中
        # layout.addWidget(btn1, Qt.AlignmentFlag.AlignTop)
        layout.addWidget(btn1)

        layout.addStretch(1)

        # 按钮2
        btn2 = QPushButton("按钮2")
        # 添加到布局器
        layout.addWidget(btn2)

        layout.addStretch(1)

        # 按钮3
        btn3 = QPushButton("按钮3")
        # 添加到布局器
        layout.addWidget(btn3)

        layout.addStretch(2)

        btn4 = QPushButton("按钮4")
        # 添加到布局器
        layout.addWidget(btn4)

        layout.addStretch(2)

        self.setLayout(layout)


if __name__ == '__main__':
    app = QApplication(sys.argv)
    # 创建一个QWidget子类
    w = MyWindow()
    w.show()
    app.exec()

image-20230520000242070

4.1.2 水平布局

import sys
from PyQt5.QtWidgets import QApplication, QWidget, QGroupBox, QVBoxLayout, QHBoxLayout, QRadioButton


class MyWindow(QWidget):

    def __init__(self):
        super().__init__()
        self.init_ui()

    def init_ui(self):
        # 最外层的垂直布局,包含两部分:爱好和性别
        container = QVBoxLayout()
        # -----创建第1个组,添加多个组件-----
        # hobby 主要是保证他们是一个组。
        hobby_box = QGroupBox("爱好")
        # v_layout 保证三个爱好是垂直摆放
        v_layout = QVBoxLayout()
        btn1 = QRadioButton("抽烟")
        btn2 = QRadioButton("喝酒")
        btn3 = QRadioButton("烫头")
        # 添加到v_layout中
        v_layout.addWidget(btn1)
        v_layout.addWidget(btn2)
        v_layout.addWidget(btn3)
        # 把v_layout添加到hobby_box中
        hobby_box.setLayout(v_layout)

        # -----创建第2个组,添加多个组件-----
        # 性别组
        gender_box = QGroupBox("性别")
        # 性别容器
        h_layout = QHBoxLayout()
        # 性别选项
        btn4 = QRadioButton("男")
        btn5 = QRadioButton("女")
        # 追加到性别容器中
        h_layout.addWidget(btn4)
        h_layout.addWidget(btn5)
        # 添加到 box中
        gender_box.setLayout(h_layout)

        # 把爱好的内容添加到容器中
        container.addWidget(hobby_box)
        # 把性别的内容添加到容器中
        container.addWidget(gender_box)


        # 音乐标签
        music_box = QGroupBox("音乐")
        m_layout = QHBoxLayout()

        btn6 = QRadioButton("古风")
        btn7 = QRadioButton("流行")

        m_layout.addWidget(btn6)
        m_layout.addWidget(btn7)

        music_box.setLayout(m_layout)


        container.addWidget(music_box)




        # 设置窗口显示的内容是最外层容器
        self.setLayout(container)


if __name__ == '__main__':
    app = QApplication(sys.argv)

    w = MyWindow()
    w.show()

    app.exec()

image-20230526230756063

4.2 QGridLayout

网格布局

import sys
from PyQt5.QtWidgets import QApplication, QWidget, QVBoxLayout, QPushButton, QLineEdit, QGridLayout


class MyWindow(QWidget):

    def __init__(self):
        super().__init__()
        self.init_ui()

    def init_ui(self):
        self.setWindowTitle("计算器")
        # 准备数据
        data = {
            0: ["7", "8", "9", "+", "("],
            1: ["4", "5", "6", "-", ")"],
            2: ["1", "2", "3", "*", "<-"],
            3: ["0", ".", "=", "/", "C"]
        }
        # 整体垂直布局
        layout = QVBoxLayout()
        # 输入框
        edit = QLineEdit()
        edit.setPlaceholderText("请输入内容")
        # 把输入框添加到容器中
        layout.addWidget(edit)
        # 网格布局
        grid = QGridLayout()
        # 循环创建追加进去
        for line_number, line_data in data.items():
            # 此时line_number是第几行,line_data是当前行的数据
            for col_number, number in enumerate(line_data):
                # 此时col_number是第几列,number是要显示的符号
                btn = QPushButton(number)
                # grid.addWidget(btn)
                grid.addWidget(btn, line_number, col_number)

        # 把网格布局追加到容器中
        layout.addLayout(grid)

        self.setLayout(layout)


if __name__ == '__main__':
    app = QApplication(sys.argv)

    w = MyWindow()
    w.show()

    app.exec()

image-20230526231843507

4.3 QFormLayout

一般适用于提交数据form表单。比如: 登录,注册类似的场景

import sys

from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import QVBoxLayout, QFormLayout, QLineEdit, QPushButton, QApplication, QWidget


class MyWindow(QWidget):

    def __init__(self):
        super().__init__()
        self.init_ui()

    def init_ui(self):
        # 设定当前Widget的宽高(可以拉伸大小)
        # self.resize(300, 200)
        # 禁止改变宽高(不可以拉伸)
        self.setFixedSize(300, 150)

        # 外层容器
        container = QVBoxLayout()

        # 表单容器
        form_layout = QFormLayout()

        # 创建1个输入框
        edit = QLineEdit()
        edit.setPlaceholderText("请输入账号")
        form_layout.addRow("账号:", edit)

        # 创建另外1个输入框
        edit2 = QLineEdit()
        edit2.setPlaceholderText("请输入密码")
        form_layout.addRow("密码:", edit2)

        # 将from_layout添加到垂直布局器中
        container.addLayout(form_layout)

        # 按钮
        login_btn = QPushButton("登录")
        login_btn.setFixedSize(100, 30)

        # 把按钮添加到容器中,并且指定它的对齐方式
        container.addWidget(login_btn, alignment=Qt.AlignRight)

        # 设置当前Widget的布局器,从而显示这个布局器中的子控件
        self.setLayout(container)


if __name__ == '__main__':
    app = QApplication(sys.argv)

    w = MyWindow()
    w.show()

    app.exec()

image-20230526232028808

4.4 抽屉布局

提供了多页面切换的布局,一次只能看到一个界面。 抽屉布局

import sys
from PyQt5.QtWidgets import QApplication, QWidget, QVBoxLayout, QPushButton, QStackedLayout, QLabel


class Window1(QWidget):
    def __init__(self):
        super().__init__()
        QLabel("我辈岂是蓬蒿人", self)
        self.setStyleSheet("background-color:green;")


class Window2(QWidget):
    def __init__(self):
        super().__init__()
        QLabel("人生得以须尽欢", self)
        self.setStyleSheet("background-color:red;")


class MyWindow(QWidget):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.create_stacked_layout()
        self.init_ui()

    def create_stacked_layout(self):
        # 创建堆叠(抽屉)布局
        self.stacked_layout = QStackedLayout()
        # 创建单独的Widget
        win1 = Window1()
        win2 = Window2()
        # 将创建的2个Widget添加到抽屉布局器中
        self.stacked_layout.addWidget(win1)
        self.stacked_layout.addWidget(win2)

    def init_ui(self):
        # 设置Widget大小以及固定宽高
        self.setFixedSize(300, 270)

        # 1. 创建整体的布局器
        container = QVBoxLayout()

        # 2. 创建1个要显示具体内容的子Widget
        widget = QWidget()
        widget.setLayout(self.stacked_layout)
        widget.setStyleSheet("background-color:grey;")

        # 3. 创建2个按钮,用来点击进行切换抽屉布局器中的Widget
        btn_press1 = QPushButton("抽屉1")
        btn_press2 = QPushButton("抽屉2")
        # 给按钮添加事件(即点击后要调用的函数)
        btn_press1.clicked.connect(self.btn_press1_clicked)
        btn_press2.clicked.connect(self.btn_press2_clicked)

        # 4. 将需要显示的空间添加到布局器中
        container.addWidget(widget)
        container.addWidget(btn_press1)
        container.addWidget(btn_press2)

        # 5. 设置当前要显示的Widget,从而能够显示这个布局器中的控件
        self.setLayout(container)

    def btn_press1_clicked(self):
        # 设置抽屉布局器的当前索引值,即可切换显示哪个Widget
        self.stacked_layout.setCurrentIndex(0)

    def btn_press2_clicked(self):
        # 设置抽屉布局器的当前索引值,即可切换显示哪个Widget
        self.stacked_layout.setCurrentIndex(1)


if __name__ == "__main__":
    app = QApplication(sys.argv)

    win = MyWindow()
    win.show()

    app.exec()

image-20230526232309149

5. 窗口

5.1 分类

在Qt中,生成窗口有三种方式: QWidget | QMainWindow | QDialog

  1. QWidget

控件和窗口的父类 ,自由度高(什么都东西都没有),没有划分菜单、工具栏、状态栏、主窗口 等区域

  1. QMainWindow

QWidget的子类,包含菜单栏,工具栏,状态栏,标题栏等,中间部分则为主窗口区域

  1. QDialog

对话框窗口的基类

5.2 QWidget

import  sys

from PyQt5.QtWidgets import QWidget, QLabel , QApplication

class mywnd(QWidget):

    def __init__(self):
        super(mywnd, self).__init__()
        self.initUI()

    def initUI(self):
        label = QLabel("这是文字~~" )
        label.setStyleSheet("font-size:30px;color:red")
        label.setParent(self)

if __name__ == '__main__':
    app = QApplication(sys.argv)

    w = mywnd()

    #设置窗口标题
    w.setWindowTitle("qwidget")

    # 展示窗口
    w.show()

    # 程序进行循环等待状态
    app.exec()

image-20230526232850921

5.2 QMainWindow

import sys

from PyQt5.QtWidgets import QMainWindow, QLabel, QApplication


class MyWindow(QMainWindow):

    def __init__(self):
        super().__init__()
        self.init_ui()

    def init_ui(self):
        label = QLabel("这是文字~~")
        label.setStyleSheet("font-size:30px;color:red")

        # 调用父类中的menuBar,从而对菜单栏进行操作
        menu = self.menuBar()
        # 如果是Mac的话,菜单栏不会在Window中显示而是屏幕顶部系统菜单栏位置
        # 下面这一行代码使得Mac也按照Windows的那种方式在Window中显示Menu
        menu.setNativeMenuBar(False)

        file_menu = menu.addMenu("文件")
        file_menu.addAction("新建")
        file_menu.addAction("打开")
        file_menu.addAction("保存")

        edit_menu = menu.addMenu("编辑")
        edit_menu.addAction("复制")
        edit_menu.addAction("粘贴")
        edit_menu.addAction("剪切")

        # 设置中心内容显示
        self.setCentralWidget(label)


if __name__ == '__main__':
    app = QApplication(sys.argv)

    w = MyWindow()
    # 设置窗口标题
    w.setWindowTitle("我是窗口标题....")
    # 展示窗口
    w.show()

    # 程序进行循环等待状态
    app.exec()

image-20230526233306456

5.3 QDialog

import sys

from PyQt5.QtWidgets import QDialog, QPushButton, QApplication


class MyDialog(QDialog):

    def __init__(self):
        super().__init__()
        self.init_ui()

    def init_ui(self):
        ok_btn = QPushButton("确定", self)
        ok_btn.setGeometry(50, 50, 100, 30)


if __name__ == '__main__':
    app = QApplication(sys.argv)

    w = MyDialog()
    # 设置窗口标题
    w.setWindowTitle("对话框")
    # 展示窗口
    w.show()

    # 程序进行循环等待状态
    app.exec()

image-20230526233352946

6. 信号与槽

6.1 信号与槽介绍

一、说明
信号和槽是 Qt的核心内容

  1. 信号(signal)
    其实就是事件(按钮点击 、内容发生改变 、窗口的关闭事件) 或者是 状态 (check选中了, togglebutton 切换。)

当程序触发了某种状态或者发生了某种事件(比如:按钮被点击了, 内容改变等等),那么即可发射出来一个信号。

  1. 槽( slot)
    若想捕获这个信号,然后执行相应的逻辑代码,那么就需要使用到槽 , 槽实际上是一个函数, 当信号发射出来后,会执行与之绑定的槽函数

  2. 将信号与槽链接
    为了能够实现,当点击某个按钮时执行某个逻辑,需要把具体的信号和具体的槽函数绑定到一起.

操作大体流程如下

对象.信号.connect(槽函数)

img

当出现了某一种信号(某一种事件)的时候,我们需要执行一段代码(用函数来包装这份代码。)

解决办法

信号和槽

6.2 案例

功能:接收信号

import sys

from PyQt5.QtWidgets import QApplication, QWidget, QPushButton


class MyWindow(QWidget):
    def __init__(self):
        super().__init__()
        self.init_ui()

    def init_ui(self):
        # 更改当前Widge的宽高
        self.resize(500, 300)
        # 创建一个按钮
        btn = QPushButton("点我点我", self)
        # 设置窗口位置、宽高
        btn.setGeometry(200, 200, 100, 30)
        # 将按钮被点击时触发的信号与我们定义的函数(方法)进行绑定
        # 注意:这里没有(),即写函数的名字,而不是名字()
        btn.clicked.connect(self.click_my_btn)

    def click_my_btn(self, arg):
        # 槽函数,点击按钮则调用该函数
        # 这里的参数正好是信号发出,传递的参数
        print("点击按钮啦~", arg)


if __name__ == '__main__':
    app = QApplication(sys.argv)

    w = MyWindow()
    w.show()

    app.exec()

image-20230526234343799

6.3 自定义信号

除了接收Qt自带的信号之外,我们也可以自行定义信号,在合适的时机,自行发射信号

自定义信号需要使用到 pyqtSignal来声明信号 ,并且需要在类中的函数之外声明

如果会自定义信号,那么信号和槽基本上也就掌握了。否则永远只会接收别人发射出的信号

import sys
import time

from PyQt5.QtWidgets import *
from PyQt5.QtCore import *


class MyWindow(QWidget):
    # 声明一个信号 只能放在函数的外面
    my_signal = pyqtSignal(str)

    def __init__(self):
        super().__init__()
        self.init_ui()
        self.msg_history = list()  # 用来存放消息

    def init_ui(self):
        self.resize(500, 200)

        # 创建一个整体布局器
        container = QVBoxLayout()

        # 用来显示检测到漏洞的信息
        self.msg = QLabel("")
        self.msg.resize(440, 15)
        # print(self.msg.frameSize())
        self.msg.setWordWrap(True)  # 自动换行
        self.msg.setAlignment(Qt.AlignCenter)  # 靠上
        self.msg.setStyleSheet("background-color: yellow; color: red;")

        # 创建一个滚动对象
        scroll = QScrollArea()
        scroll.setWidget(self.msg)

        # 创建垂直布局器,用来添加自动滚动条
        v_layout = QVBoxLayout()
        v_layout.addWidget(scroll)

        # 创建水平布局器
        h_layout = QHBoxLayout()
        btn = QPushButton("开始检测", self)
        # 绑定按钮的点击,点击按钮则开始检测
        btn.clicked.connect(self.check)
        h_layout.addStretch(1)  # 伸缩器
        h_layout.addWidget(btn)
        h_layout.addStretch(1)

        # 操作将要显示的控件以及子布局器添加到container
        container.addLayout(v_layout)
        container.addLayout(h_layout)

        # 设置布局器
        self.setLayout(container)

        # 绑定信号和槽
        self.my_signal.connect(self.my_slot)

    def my_slot(self, msg):
        # 更新内容
        print(msg)
        self.msg_history.append(msg)
        self.msg.setText("<br>".join(self.msg_history))
        self.msg.resize(440, self.msg.frameSize().height() + 15)
        self.msg.repaint()  # 更新内容,如果不更新可能没有显示新内容

    def check(self):
        for i, ip in enumerate(["192.168.1.%d" % x for x in range(1, 255)]):
            msg = "模拟,正在检查 %s 上的漏洞...." % ip
            # print(msg)
            if i % 5 == 3:
                # 表示发射信号 对象.信号.发射(参数)
                self.my_signal.emit(msg + "【发现漏洞】")
            time.sleep(0.01)


if __name__ == '__main__':
    app = QApplication(sys.argv)

    w = MyWindow()
    w.show()

    app.exec()

image-20230526235615971

7.Qt Designer

7.1 介绍

纯靠代码来编写界面,效率属实是有点底,今天我们用另外一个辅助设计图形化的软件 QT Designer

7.2 下载

Mac版本:[http://download.codetutor.top/software/Mac/Qt%20Designer.dmg](http://download.codetutor.top/software/Mac/Qt Designer.dmg)

Windows版本:[http://download.codetutor.top/software/win/Qt%20Designer%20Setup.exe](http://download.codetutor.top/software/win/Qt Designer Setup.exe)

7.3 安装&运行

安装过程很简单,按照正常软件安装即可,安装后的图片如下图:

image-20201123214407351

但Mac平台用户要注意,运行时会出现如下图问题

img

解决办法:在“应用程序”文件夹,按住control键然后运行。只需要这种方式运行第一次即可,以后运行就像普通软件一样打开

image-20201123214951153

7.4 使用QT Designer

Mac运行之后的效果如下:

image-20201123215209758

7.5 使用流程

1.创建一个基于QWidget的界面

image-20201123215321248

2.此时会创建一个新的窗口,如下效果

image-20201123215359517

3.拖动想要的控件

image-20201123215551661

4.选中控件,看属性

image-20201123215750887

5.修改属性

image-20201123215829602

6.如果没有看到preperty等窗口怎么办?看下图

image-20201123220059274

7.信号与槽(没有没有看到Singal/Slot Editor请按照上一步操作进行显示)

image-20201123220951729

8.预览效果

image-20201123221137373

9.保存

image-20201123221409036

10.python代码使用test.ui文件

若要加载ui文件,则需要导入 uic 模块 , 它位于PyQt5

"""
动态加载ui文件
"""

import sys

from PyQt5.QtWidgets import QApplication
from PyQt5 import uic

if __name__ == '__main__':
    app = QApplication(sys.argv)

    ui = uic.loadUi("./test.ui")
    # 展示窗口
    ui.show()

    app.exec()

image-20201123221857466

参考资料

www.itprojects.cn

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/655876.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Spring Security系列之授权(Authorization)架构

文章目录 AuthorizationManagerAuthorizationFilterRequest Matcher AuthorizationManager AuthorizationManager 被授 AuthorizationFilter 调用&#xff0c;负责做出最终的访问控制决定。AuthorizationManager 接口包含两个方法。 default void verify(Supplier<Authent…

ABBYY FineReader15最新版图片文字识别转换软件

在日常生活中&#xff0c;我们会遇到需要将各种文字、图片、扫描图片等转换为文字的情况。想要轻松解决这些问题&#xff0c;需要使用到OCR文字识别。但对于许多新手来说&#xff0c;OCR文字识别是陌生的。今天小编就给大家介绍一下&#xff0c;OCR文字识别怎么使用&#xff0c…

RabbitMQ如何保证消息幂等性

用户对于同一操作发起的一次请求或者多次请求的结果是一致的&#xff0c;不会因为多次点击而产生副作用。 举个简单的例子&#xff0c;那就是支付&#xff0c;用户购买商品后支付&#xff0c;支付扣款成功&#xff0c;但是返回结果的时候网络异常&#xff0c;此时钱已经扣了&am…

DJ8-4 shell 语句的分类、shell 的结构性语句

目录 8.7 shell 编程 8.7.1 shell 编程的基本过程 8.7.2 实例 8.7.3 shell 程序和语句 8.8 说明性语句和功能性语句 8.8.1 说明性语句&#xff08;注释行&#xff09; 8.8.2 常用的功能性语句 8.9 结构性语句 8.9.1 条件语句 if 8.9.2 测试语句 test 8.9.…

什么牌子的电容笔质量好耐用?平板第三方电容笔了解下

苹果的电容笔和普通的电容笔有何区别&#xff1f;其实&#xff0c;就书写情况而言&#xff0c;两者相差不多。只是苹果电容笔生在重量上&#xff0c;更加的沉重&#xff0c;而且还配备了一个特殊的重力传感器&#xff0c;能够准确的感觉到重力对线条的粗细变化。由于苹果这款产…

手机操作系统的沉浮往事(上)

移动终端操作系统&#xff0c;也就是指手机、平板电脑等设备所使用的操作系统。 在移动互联网高度发达的今天&#xff0c;我们使用移动终端操作系统的时长&#xff0c;可能已经远远超过了Windows等桌面操作系统。 那么&#xff0c;你真正了解这些移动终端操作系统吗&#xff1f…

抖音seo源码开发部署技术解析

抖音seo源码开发是一项非常重要的技术&#xff0c;开发需要深入了解抖音平台的特点和用户需求&#xff0c;积累丰富的SEO经验&#xff0c;并不断学习和更新SEO技能&#xff0c;才能不断提高视频在搜索引擎中的曝光率和播放量。 抖音seo开发需要哪些技术 了解抖音的算法和规则&…

浏览器被2345劫持了怎么搞

起因我下载了某些修改东西&#xff0c;然后就被2345篡改了浏览器的数据。我是在虚拟机里下载的&#xff0c;但是虚拟机其实也是物理机的一部分&#xff0c;实际上下载的还是到了物理机里面&#xff0c;于是浏览器打开就变成了2345的导航页面 1 解决方案&#xff1a; 浏览器主页…

DJ8-2 shell 的命令形式、shell 的变量、shell 的内部命令

目录 8.3 shell 可识别的命令形式 8.3.1 单条命令 8.3.2 多条命令 8.3.3 复合命令 8.3.4 后台命令 8.4 shell 变量和引用符 8.4.1 环境变量 plus. echo 命令的使用 8.4.2 系统变量 8.4.3 局部变量&#xff08;用户变量&#xff09; 8.4.4 单引号、双引号、…

跨境电商领域的ChatGPT使用攻略

今天分享一个电商领域的ChatGPT应用指南! 一、写谷歌广告词 提示词: 现在你是一名谷歌广告的编写人员&#xff0c;你需要为xxx产品写10条谷歌广告标题和谷歌广告描述。要求是: 1.用英文输出你的答案 2.广告的标题和广告描述的字数等要符合谷歌的标准 3.广告要引人入胜&#xf…

OceanBase—01(入门篇——使用docker安装OceanBase以及介绍连接OB的几种方式)

OceanBase—01&#xff08;入门篇——使用docker安装OceanBase以及介绍连接OB的几种方式&#xff09; 1. 前言1.1 安装部署参考1.1.1 安装前提1.1.2 参考 1.1 修改数据库用户名密码1.2 总结常见连接命令 2. 安装部署OceanBase2.1 启动 OceanBase 数据库实例2.1.1 默认拉取最新版…

代码审计——XSS详解

为方便您的阅读&#xff0c;可点击下方蓝色字体&#xff0c;进行跳转↓↓↓ 01 漏洞描述02 审计要点03 漏洞特征04 漏洞案例05 修复方案 01 漏洞描述 跨站脚本攻击&#xff08;Cross Site Script&#xff09;是一种将恶意JavaScript代码插入到其他Web用户页面里执行以达到攻击…

没网络的CentOS7的Docker容器安装Java诊断神器Arthas

操作过程 1. 先把jar包下载到本地的windwos2. 打包复制到服务器3. 启动容器设置4.重启容器并使用Arthas 1. 先把jar包下载到本地的windwos 下载地址 下载好后jar&#xff0c;然后CMD执行命令 java -jar arthas-boot.jar 然后随便进入某个jvm进程查看&#xff0c;会见到Conso…

【技术新趋势】面向图像文档的版面智能分析与理解

目录 一、什么是OCR&#xff1f;什么是版面分析理解&#xff1f;二、文档版面分析2.1、版面布局类型2.2、面向文档图像版面分析的实例分割2.3、逻辑结构分析 三、文档版面理解3.1、位置嵌入3.2、表格数据提取 四、智能文档处理技术新解决方案 人类撰写文档是为了记录和保存信息…

Zoho Books助力跨境贸易!深入了解其多币种处理功能

对于跨境行业而言&#xff0c;合作不同的客户以当地货币收取付款是一个不简单的任务。现在&#xff0c;Zoho Books 推出了新的高级多币种处理功能&#xff0c;让多货币付款或收款不再困扰。&#xff08;注意&#xff1a;此功能在Zoho Books的专业版&#xff0c;高级版&#xff…

使用 ChatGPT 创建 APP 的最佳实践

导读&#xff1a;如果你想用用ChatGPT创建应用程序来赚钱&#xff0c;这是你需要知道的。 本文字数&#xff1a;2900&#xff0c;阅读时长大约&#xff1a;18分钟 如果你想用ChatGPT创建应用程序来赚钱&#xff0c;这是你需要知道的。 我最好先说出坏消息。如果你认为可以两手…

【后端开发】尚硅谷 SpringCloud 学习笔记

文章目录 一、cloud组件二、环境搭建2.1 创建父工程2.2 支付模块构建2.3 消费者模块构建2.3.1 引入RestTemplate2.3.2 远程调用支付模块 三、Eureka3.1 基础知识3.2 单机版Eureka安装3.3 服务注册3.4 Eureka集群3.4.1 Eureka端配置3.4.2 微服务端配置3.4.3 restTemplate负载均衡…

如何让ChatGPT制作XMind思维导图

一、使用ChatGPT辅助生成内容 给大家一个思路&#xff0c;比如我想制作《股神巴菲特给儿女的一生忠告》相关的思维导图&#xff0c;那我们可以在ChatGPT上提问“请使用markdown格式写出股神巴菲特给儿女的一生忠告的思维导图&#xff0c;以代码格式输出”。 生成后&#xff0…

teleport堡垒机的一些问题

teleport文件下载&#xff0c;将teleport服务映射到公网&#xff0c;权限已经分派好了&#xff0c;但无法ssh&#xff0c;这是什么原因呢&#xff1f; 注意teleport助手的版本要跟部署的是一致的&#xff0c;否则会检测不到状态 出现下面的问题&#xff0c;应该还是在防火墙的端…

奇舞周刊第496期:ChatGPT 的工作原理,这篇文章说清楚了!

记得点击文章末尾的“ 阅读原文 ”查看哟~ 下面先一起看下本期周刊 摘要 吧~ 奇舞推荐 ■ ■ ■ ChatGPT 的工作原理&#xff0c;这篇文章说清楚了&#xff01; ChatGPT 能够自动生成一些读起来表面上甚至像人写的文字的东西&#xff0c;这非常了不起&#xff0c;而且出乎意料。…