【PyQt5 知识点示例代码】布局、菜单、信号与槽、对话框、组件

2023-04-11 11:58:34

代码选自 张少娴老师《Python量化交易从入门到实战》

重写按钮的关闭事件 closeEvent

在这里插入图片描述
核心就是重写父类QWidgetcloseEvent方法

import sys
from PyQt5.QtWidgets import QWidget, QPushButton, QApplication, QMessageBox


class Widget(QWidget):
    def __init__(self):
        super().__init__()
        self.initUI()

    def initUI(self):
        # 在窗口上创建一个按钮对象
        qbtn = QPushButton('关闭', self)
        # 将按钮对象的click事件连接到窗口的关闭方法
        qbtn.clicked.connect(self.close)
        # 指定按钮的位置
        qbtn.move(50, 50)

        # 设定窗口的位置和大小
        self.setGeometry(300, 300, 320, 160)
        self.setWindowTitle('请单击关闭按钮')
        self.show()

    def closeEvent(self, event):
        reply = QMessageBox.question(self, '提示信息',
                                     '确认要关闭窗口?',
                                     QMessageBox.Yes | QMessageBox.No,
                                     QMessageBox.No)
        if reply == QMessageBox.Yes:
            event.accept()
        else:
            event.ignore()


if __name__ == '__main__':
    app = QApplication(sys.argv)
    w = Widget()
    sys.exit(app.exec_())

布局

绝对布局

在这里插入图片描述
强行用move控制位置,不推荐这么做,页面兼容性很差

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

class Widget(QWidget):
    def __init__(self):
        super().__init__()
        self.initUI()

    def initUI(self):
        qbtn1 = QPushButton('功能1', self)
        qbtn1.move(50, 50)

        qbtn2 = QPushButton('功能2', self)
        qbtn2.move(100, 100)

        qbtn3 = QPushButton('功能3', self)
        qbtn3.move(150, 150)

        self.setGeometry(300, 300, 280, 170)
        self.setWindowTitle('绝对定位')
        self.show()

if __name__ == '__main__':
    app = QApplication(sys.argv)
    w = Widget()
    sys.exit(app.exec_())

盒布局

在这里插入图片描述
addStretch 表示“塞入弹簧”,用来控制盒布局的周围距离(塞的特多距离特大)

import sys
from PyQt5.QtWidgets import QWidget, QPushButton, QHBoxLayout, QVBoxLayout, QApplication

class Widget(QWidget):
    def __init__(self):
        super().__init__()
        self.initUI()

    def initUI(self):
        # 创建两个按钮对象
        okButton = QPushButton("确认")
        cancelButton = QPushButton("取消")

        hbox = QHBoxLayout()  # 创建一个水平盒布局对象hbox
        hbox.addStretch(4)
        hbox.addWidget(okButton)
        hbox.addWidget(cancelButton)
        hbox.addStretch(1)

        vbox = QVBoxLayout()    # 创建一个垂直盒布局对象vbox
        vbox.addStretch(1)
        vbox.addLayout(hbox)    # 弹簧把hbox压到了最下面

        self.setLayout(vbox)    # 将vbox设置为窗口的主布局对象

        self.setGeometry(300, 300, 360, 150)
        self.setWindowTitle('盒布局')
        self.show()

if __name__ == '__main__':
    app = QApplication(sys.argv)
    w = Widget()
    sys.exit(app.exec_())

网络布局

在这里插入图片描述

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

class Widget(QWidget):
    def __init__(self):
        super().__init__()
        self.initUI()

    def initUI(self):
        grid = QGridLayout()    # 创建一个网格布局grid,并将其设为窗口的主布局
        self.setLayout(grid)

        names = ['Cls', 'Bck', '', 'Close',  # 创建20个元素的字符串列表
                 '7', '8', '9', '/',
                 '4', '5', '6', '*',
                 '1', '2', '3', '-',
                 '0', '.', '=', '+']

        positions = [(i, j) for i in range(5) for j in range(4)]    # 创建20个元素的元组列表

        for position, name in zip(positions, names):    # 循环取每个坐标和按钮名称
            if name == '':  # 空字符串则什么都不做
                continue
            button = QPushButton(name)
            print(*position)
            grid.addWidget(button, *position)

        self.move(300, 160)
        self.setWindowTitle('计算器')
        self.show()

if __name__ == '__main__':
    app = QApplication(sys.argv)
    w = Widget()
    sys.exit(app.exec_())

状态栏、菜单栏、子菜单、勾选菜单、右键菜单

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

import sys
from PyQt5.QtWidgets import QMainWindow, QApplication, QAction, QMenu
from PyQt5.QtGui import QIcon

class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        self.initUI()

    def initUI(self):
        # 行为相关的代码
        # 创建一个行为对象
        exitAction = QAction(QIcon('exit.png'), '退出(&Q)', self)
        # 设置行为的快捷键
        exitAction.setShortcut('Ctrl+Q')
        # 设置行为的状态栏提示文本
        exitAction.setStatusTip('退出应用程序。')
        # 将该行为作关联到窗口的关闭事件
        exitAction.triggered.connect(self.close)

        # 菜单栏相关的代码
        # 创建一个菜单栏
        menubar = self.menuBar()
        # 在菜单栏中添加一个菜单
        fileMenu = menubar.addMenu('文件(&F)')

        # 创建两个行为和一个菜单,并将两个行为添加到菜单
        impTextAct = QAction('文本文件', self)
        impPictAct = QAction('图形文件', self)
        impMenu = QMenu('导入', self)
        impMenu.addAction(impTextAct)
        impMenu.addAction(impPictAct)

        fileMenu.addMenu(impMenu)   # 将子菜单添加到父菜单
        fileMenu.addSeparator()     # 在菜单中加入一条分隔线
        fileMenu.addAction(exitAction)

        # 将行为添加到菜单
        fileMenu.addAction(exitAction)

        # ①创建一个带勾选功能的行为
        viewStatAct = QAction('显示状态栏', self, checkable=True)
        viewStatAct.setStatusTip('状态栏显示开关。')
        viewStatAct.setChecked(True)
        viewStatAct.triggered.connect(self.toggleMenu)

        # ②创建一个新的菜单,并添加到菜单栏当中
        viewMenu = menubar.addMenu('视图(&V)')
        viewMenu.addAction(viewStatAct)

        self.statusBar().showMessage('就绪')

        self.setGeometry(300, 300, 360, 160)
        self.setWindowTitle('主窗口')
        self.show()

    def toggleMenu(self, state):
        """③行为“显示状态栏”的处理函数"""
        statusbar = self.statusBar()
        if state:
            statusbar.show()
        else:
            statusbar.hide()

    def contextMenuEvent(self, event):
           cmenu = QMenu(self)

           func1Act = cmenu.addAction("功能1")
           func2Act = cmenu.addAction("功能2")
           quitAct = cmenu.addAction("退出")
           action = cmenu.exec_(self.mapToGlobal(event.pos()))

           if action == quitAct:
               self.close()

if __name__ == '__main__':
    app = QApplication(sys.argv)
    w = MainWindow()
    sys.exit(app.exec_())

信号与槽

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

点击按钮显示窗口

在这里插入图片描述

import sys
from PyQt5.QtWidgets import QMainWindow, QPushButton, QApplication, QMessageBox

class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        self.initUI()

    def initUI(self):
        btn1 = QPushButton("按钮1", self)
        btn1.move(30, 50)
        btn1.clicked.connect(self.showMsg)

        btn2 = QPushButton("按钮2", self)
        btn2.move(150, 50)
        btn2.clicked.connect(self.showMsg)  # btn2与btn1连接到相同的槽函数

        self.setGeometry(300, 300, 290, 150)
        self.setWindowTitle('信号与槽')
        self.show()

    def showMsg(self):
        sender = self.sender()  # 获取信号是由哪个控件发出的,可以获取到btn1或btn2
        QMessageBox.information(self, '提示信息', f'{sender.text()}被按下。')

if __name__ == '__main__':
    app = QApplication(sys.argv)
    ex = MainWindow()
    sys.exit(app.exec_())

重写keyPressEvent - Esc关闭窗口

在这里插入图片描述

import sys
from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import QWidget, QApplication

class Widget(QWidget):
    def __init__(self):
        super().__init__()
        self.initUI()

    def initUI(self):
        self.setGeometry(300, 300, 360, 130)  # (pos_x, pos_y, width, height)
        self.setWindowTitle('按Esc键关闭窗口')
        self.show()

    # 重写了键盘事件处理器
    def keyPressEvent(self, e):
        if e.key() == Qt.Key_Escape:
            self.close()

if __name__ == '__main__':
    app = QApplication(sys.argv)
    w = Widget()
    sys.exit(app.exec_())

内置槽函数 - 滚动条控制LCD

在这里插入图片描述

import sys
from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import QWidget, QLCDNumber, QSlider, QVBoxLayout, QApplication

class Widget(QWidget):
    def __init__(self):
        super().__init__()
        self.initUI()

    def initUI(self):
        # 创建一个QLCDNumber控件,QLCDNumber用于显示一个带有仿真显示屏效果的数字
        lcd = QLCDNumber(self)
        # 创建一个QSlider控件,QSlider提供了一个水平或垂直滑动条
        sld = QSlider(Qt.Horizontal, self)

        vbox = QVBoxLayout()
        vbox.addWidget(lcd)
        vbox.addWidget(sld)

        self.setLayout(vbox)
        # 将滑动条的valueChanged信号与LCD的display槽函数连接
        sld.valueChanged.connect(lcd.display)

        self.setGeometry(300, 300, 300, 150)
        self.setWindowTitle('LCD显示')
        self.show()

if __name__ == '__main__':
    app = QApplication(sys.argv)
    w = Widget()
    sys.exit(app.exec_())

自定义信号

在这里插入图片描述

自定义信号方法一:自定义信号类继承QObject

import sys
from PyQt5.QtCore import pyqtSignal, QObject
from PyQt5.QtWidgets import QMainWindow, QApplication

class MySignal(QObject):    # 自定义信号需要继承QObject
    sigClose = pyqtSignal()

class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        self.initUI()

    def initUI(self):
        self.sig = MySignal():
        self.sig.sigClose.connect(self.close)   # 将sig的sigClose信号与窗口的close()槽函数连接

        self.setGeometry(300, 300, 320, 150)
        self.setWindowTitle('单击鼠标关闭')
        self.show()

    # 重写mousePressEvent事件处理器,该处理器在鼠标按下时触发
    def mousePressEvent(self, event):
        self.sig.sigClose.emit()    # 将sig的sigClose信号发出,会调用与之连接的close()槽函数
        # self.close()

if __name__ == '__main__':
    app = QApplication(sys.argv)
    w = MainWindow ()
    sys.exit(app.exec_())

自定义信号方法二:直接在MainWindow类中定义信号属性,不需要专门定义一个类

import sys
from PyQt5.QtCore import pyqtSignal
from PyQt5.QtWidgets import QMainWindow, QApplication

class MainWindow(QMainWindow):
    # 直接在MainWindow类中定义信号属性,不需要专门定义一个类
    sigClose = pyqtSignal()

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

    def initUI(self):
        # 将sigClose信号与窗口的close()槽函数连接
        self.sigClose.connect(self.close)

        self.setGeometry(300, 300, 320, 150)
        self.setWindowTitle('单击鼠标关闭')
        self.show()

    def mousePressEvent(self, event):
        self.sigClose.emit()

if __name__ == '__main__':
    app = QApplication(sys.argv)
    w = MainWindow ()
    sys.exit(app.exec_())

事件对象、重写mouseMoveEvent

在这里插入图片描述

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

class Widget(QWidget):
    def __init__(self):
        super().__init__()
        self.initUI()

    def initUI(self):
        # QLabel控件用于显示文本
        self.label = QLabel("x: 0,  y: 0        ", self)
        self.label.move(10, 10)

        # 鼠标指针移动可能会触发鼠标移动事件,该事件如果开启会被频繁触发,默认是不开启的
        self.setMouseTracking(True)

        self.setGeometry(300, 300, 350, 200)
        self.setWindowTitle('事件对象')
        self.show()

    def mouseMoveEvent(self





							
  • 作者:萌宅鹿同学
  • 原文链接:https://luzhenyu.blog.csdn.net/article/details/115337794
    更新时间:2023-04-11 11:58:34