PyQt5常用信号


前言

记录本人常用的PyQt5编程,方便自身查阅,也许有缘能帮到网友。

持续更新中......

一、点击按钮切换窗口(回车登录)

在这里插入图片描述

self.ui.pushButton_login.clicked.connect(self.open_mainwindow)

在这里插入图片描述
写在初始化函数里。

    def keyPressEvent(self, event):   # 回车登录
        if str(event.key()) == '16777220' or str(event.key()) == '16777221':
            self.open_mainwindow()
            
    def open_mainwindow(self):
        if self.ui.lineEdit_username.text() == 'user' or self.ui.lineEdit_username.text() == 'USER':
            if self.ui.lineEdit_password.text() == '123':
                win.close()
                import pyqt5_mainwindow as main   # 等满足条件后再导入main类(mainwindow已经经过QMainWindow类编辑)
                self.one = main.WinMain()
                self.one.show()
                self.one.ui.stackedWidget_show.setCurrentIndex(0)
            else:
                import pyqt5_message as mess   # 等满足条件后再导入mess类(mess已经经过QMainWindow类编辑)
                self.two = mess.WinMessage()
                self.two.ui.label.setText('账户名或者密码错误!')
                self.two.show()
                self.ui.lineEdit_password.setText('')

写在类方法里就行。


二、两个或者多个窗口传递参数

这个对于开发应用来说十分必要,关键函数pyqtSignal

先举一个简单的例子:

通过应用小窗口输入账号密码登录,成功登录后关闭原窗口打开大窗口,大窗口有重新登录至工程师模式的按钮,点击该按钮不关闭大窗口并生成新的登录窗口,登录成功后大窗口改变界面。

在这里插入图片描述
参考 一、点击按钮切换窗口(回车登录),打开新窗口都不需要通讯,满足条件即可。

重点在于工程师模式登录成功后大窗口改变界面,并非简单粗暴关闭原窗口再打开。


在需要发送指令的类里面添加pyqtSignal:

from PyQt5.QtCore import pyqtSignal

class WinLogin(QMainWindow):
    signal_confirm = pyqtSignal(int)   # 放在最开头,别加self

在类方法里写入当达成什么条件后会发送信息:

    def open_mainwindow(self):
        if self.ui.lineEdit_username.text() == 'ADMIN' or self.ui.lineEdit_username.text() == 'admin':
            if self.ui.lineEdit_password.text() == 'emins' or self.ui.lineEdit_password.text() == 'EMINS':
                self.flag = 1
                self.signal_confirm.emit(self.flag)   # 达成条件,发送flag=1的信息
            else:
                import pyqt5_message as mess
                self.two = mess.WinMessage()
                self.two.ui.label.setText('请输入工程师模式账号!')
                self.two.show()
                self.ui.lineEdit_password.setText('')

在这里插入图片描述


在需要接受到信息的类方法里面添加接收反应:

    def change_engmode(self):
        import pyqt5_login_eng as ple
        self.one = ple.WinLogin()
        self.one.show()
        self.one.signal_confirm.connect(self.enter_engmode)

    def enter_engmode(self, flag):
        if flag == 1:
            self.ui.stackedWidget_show.setCurrentIndex(2)
            self.one.close()

在这里插入图片描述


三、正则化判断输入

在用户输入内容时,往往需要限制输入,为何呢?

举个例子,你程序的某个输入框本来只能处理int数据,这时用户输入了**&&等符号并提交,那么你的程序就会直接奔溃。

于是需要了解正则化判断输入:可以直接看这篇文章——【pyqt5】 关于QT限制输入约束的正则表达式详解和一些常用表达式

若是对正则化感兴趣,可以查看我写的另一篇文章:python常用正则化表达

导入库:

from PyQt5.QtGui import QRegExpValidator
from PyQt5.QtCore import QRegExp

在类初始化方法限定username输入:

        self.username_validator = QRegExpValidator(QRegExp(r'\b[a-zA-Z]{1,5}\b'))
        self.ui.lineEdit_username.setValidator(self.username_validator)

在这里插入图片描述

四、自定义QLabel缩放和框选图片

请添加图片描述

有所参考:PyQt5实现图片缩放、旋转

在PyUIC生成的py文件里新建一个QWidget类来代替QLabel

from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtWidgets import QApplication, QWidget, QStyleOption, QStyle
from PyQt5.QtGui import QPainter, QPixmap, QColor, QPen
from PyQt5.QtCore import pyqtSignal, QPoint, Qt, qAbs, QRect


# 定义可伸缩QLabel
class MyLabel(QWidget):  # 不可用QMainWindow,因为QLabel继承自QWidget
    signal_roi = pyqtSignal(list)

    def __init__(self, img_pth, img_state):
        super(MyLabel, self).__init__()
        self.imgPixmap = QPixmap(img_pth)  # 载入图片,不覆写,显示的图片都用scaledImg表达
        self.init_ui_face()
        self.init_img()
        self.scale_width = int(self.init_img_width / 10)   # 定义缩放最小单位
        self.scale_height = int(self.init_img_height / 10)
        self.scaledImg = self.imgPixmap.scaled(self.init_img_size)  # 初始化缩放图
        self.singleOffset = QPoint(0, 0)  # 初始化偏移值
        self.img_state = img_state   # True是移动,False是截图
        self.isLeftPressed = False  # 图片被点住(鼠标左键)标志位
        self.isImgLabelArea = True  # 鼠标进入label图片显示区域
        self.isCutPressLeft = False   # 图片选择标志
        self.isSentROI = False   # 发送坐标标志

    def init_ui_face(self):
        # 初始化界面大小
        self.desktop = QApplication.desktop()
        self.screenRect = self.desktop.screenGeometry()
        self.screenheight = self.screenRect.height()
        self.screenwidth = self.screenRect.width()
        self.open_height = int(self.screenheight * 0.6) - 114
        self.open_width = int(self.screenwidth * 0.4) - 18
        self.resize(self.open_width, self.open_height)

    def init_img(self):
        # 初始化图片尺寸(等比例填充全满QLabel,会有部分看不见)
        if self.imgPixmap.width() > self.imgPixmap.height():
            self.ratio = self.imgPixmap.width() / self.imgPixmap.height()
            self.init_img_height = self.width() / self.ratio
            self.init_img_width = self.width()
            self.init_img_size = QtCore.QSize(self.init_img_width, self.init_img_height)

        else:
            self.ratio = self.imgPixmap.width() / self.imgPixmap.height()
            self.init_img_height = self.height()
            self.init_img_width = self.height() * self.ratio
            self.init_img_size = QtCore.QSize(self.init_img_width, self.init_img_height)

    # def init_img(self):
    #     # 初始化图片尺寸(等比例最大放置于QLabel,全图都能看)
    #     self.img_ratio = self.imgPixmap.width() / self.imgPixmap.height()
    #     self.label_ratio = self.width() / self.height()
    #     if self.img_ratio > self.label_ratio:
    #         self.init_img_height = self.imgPixmap.height() * self.width() / self.imgPixmap.width()
    #         self.init_img_width = self.width()
    #         self.init_img_size = QtCore.QSize(self.init_img_width, self.init_img_height)
    #
    #     else:
    #         self.init_img_height = self.height()
    #         self.init_img_width = self.imgPixmap.width() * self.height() / self.imgPixmap.height()
    #         self.init_img_size = QtCore.QSize(self.init_img_width, self.init_img_height)
    
    def paintEvent(self, event):
        self.painter = QPainter()
        self.painter.begin(self)    # 开始重绘
        shadowColor = QColor(0, 0, 0, 100)  # 黑色半透明
        penColor = QColor(0, 0, 255)     # 画笔颜色
        self.painter.setPen(QPen(penColor, 1, Qt.SolidLine, Qt.RoundCap))    # 设置画笔,蓝色,1px大小,实线,圆形笔帽

        self.painter.drawPixmap(self.singleOffset, self.scaledImg)   # 在offset点上绘制缩放图
        # 找到缩放图的bottom right
        self.scaledImg_br = QPoint(self.scaledImg.width(), self.scaledImg.height()) + self.singleOffset
        self.scaledImg_rect = QRect(self.singleOffset, self.scaledImg_br)   # 缩放图的坐标
        self.painter.fillRect(self.scaledImg_rect, shadowColor)   # 绘制阴影

        # 截取状态下才进行截图
        if self.isCutPressLeft is True:
            pickRect = self.getRectangle(self.beginPosition, self.endPosition)  # 获得要截图的矩形框
            # 进行offset修正
            self.cut_rect = QRect(pickRect.topLeft() - self.singleOffset, pickRect.bottomRight() - self.singleOffset)
            # 设定在缩放图内截取才有效
            if self.cut_rect.height() > 0 and self.cut_rect.width() > 0:
                self.captureImage = self.scaledImg.copy(self.cut_rect)  # 捕获缩放图矩形框内的图片
                self.painter.drawPixmap(pickRect.topLeft(), self.captureImage)  # 填充截图的图片
                self.painter.drawRect(pickRect)  # 画矩形边框

        self.painter.end()

    def getRectangle(self, beginPoint, endPoint):
        # 限制画框区域
        pickRectWidth = int(qAbs(beginPoint.x() - endPoint.x()))
        pickRectHeight = int(qAbs(beginPoint.y() - endPoint.y()))

        pickRectLeft = beginPoint.x() if beginPoint.x() < endPoint.x() else endPoint.x()
        pickRectLeft = pickRectLeft if pickRectLeft > self.singleOffset.x() else self.singleOffset.x()
        pickRectTop = beginPoint.y() if beginPoint.y() < endPoint.y() else endPoint.y()
        pickRectTop = pickRectTop if pickRectTop > self.singleOffset.y() else self.singleOffset.y()
        pickRectRight = pickRectLeft + pickRectWidth if pickRectLeft + pickRectWidth < self.singleOffset.x() \
            + self.scaledImg.width() else self.singleOffset.x() + self.scaledImg.width()
        pickRectBottom = pickRectTop + pickRectHeight if pickRectTop + pickRectHeight < self.singleOffset.y() \
            + self.scaledImg.height() else self.singleOffset.y() + self.scaledImg.height()

        pickRectWidth = pickRectRight - pickRectLeft
        pickRectHeight = pickRectBottom - pickRectTop

        pickRect = QRect(pickRectLeft, pickRectTop, pickRectWidth, pickRectHeight)

        # 避免高度宽度为0时候报错
        if pickRectWidth == 0:
            pickRect.setWidth(2)
        if pickRectHeight == 0:
            pickRect.setHeight(2)

        return pickRect

    def mousePressEvent(self, event):
        if self.img_state:
            self.setCursor(QtGui.QCursor(QtCore.Qt.OpenHandCursor))
            if event.buttons() == QtCore.Qt.LeftButton:
                self.isLeftPressed = True
                self.preMousePosition = event.pos()

        else:
            self.setCursor(QtGui.QCursor(QtCore.Qt.ArrowCursor))
            if event.button() == QtCore.Qt.LeftButton:
                self.isCutPressLeft = True
                self.beginPosition = event.pos()

    def zoom_out(self):
        self.scaledImg = self.imgPixmap.scaled(self.scaledImg.width() + self.scale_width,
                                               self.scaledImg.height() + self.scale_height)
        self.repaint()

    def zoom_in(self):
        self.scaledImg = self.imgPixmap.scaled(self.scaledImg.width() - self.scale_width,
                                               self.scaledImg.height() - self.scale_height)
        self.repaint()

    def wheelEvent(self, event):
        angle = event.angleDelta() / 8
        angleY = angle.y()
        if angleY > 0:
            self.scaledImg = self.imgPixmap.scaled(self.scaledImg.width() + self.scale_width,
                                                   self.scaledImg.height() + self.scale_height)
            newWidth = event.x() - (self.scaledImg.width() * (event.x() - self.singleOffset.x())) \
                       / (self.scaledImg.width() - self.scale_width)
            newHeight = event.y() - (self.scaledImg.height() * (event.y() - self.singleOffset.y())) \
                        / (self.scaledImg.height() - self.scale_height)
            self.singleOffset = QPoint(newWidth, newHeight)
            self.repaint()

        else:
            if self.scaledImg.width() > self.scale_width and self.scaledImg.height() > self.scale_height:
                self.scaledImg = self.imgPixmap.scaled(self.scaledImg.width() - self.scale_width,
                                                       self.scaledImg.height() - self.scale_height)
                newWidth = event.x() - (self.scaledImg.width() * (event.x() - self.singleOffset.x())) \
                           / (self.scaledImg.width() + self.scale_width)
                newHeight = event.y() - (self.scaledImg.height() * (event.y() - self.singleOffset.y())) \
                            / (self.scaledImg.height() + self.scale_height)
                self.singleOffset = QPoint(newWidth, newHeight)
                self.repaint()

    def mouseReleaseEvent(self, event):
        if self.img_state:
            if event.buttons() == QtCore.Qt.LeftButton:
                self.isLeftPressed = False

        else:
            if event.buttons() == QtCore.Qt.LeftButton:
                self.endPosition = event.pos()
                self.isCutPressLeft = False
            self.isSentROI = True

        if event.button() == QtCore.Qt.RightButton:
            self.singleOffset = QPoint(0, 0)
            self.init_img()
            self.scaledImg = self.imgPixmap.scaled(self.init_img_size)
            self.repaint()

    def mouseMoveEvent(self, event):
        if self.img_state:
            if self.isLeftPressed:
                self.endMousePosition = event.pos() - self.preMousePosition
                self.singleOffset = self.singleOffset + self.endMousePosition
                self.preMousePosition = event.pos()
                self.repaint()
        else:
            if self.isCutPressLeft is True:
                self.endPosition = event.pos()
                self.update()

    def calculate_coordinate(self):
        # 计算并发送所选坐标对应最初图片的坐标值
        if self.isSentROI:
            self.scale_ratio = self.imgPixmap.width() / self.scaledImg.width()
            self.roi_top = int(self.cut_rect.top() * self.scale_ratio)
            self.roi_left = int(self.cut_rect.left() * self.scale_ratio)
            self.roi_right = int(self.cut_rect.right() * self.scale_ratio)
            self.roi_bottom = int(self.cut_rect.bottom() * self.scale_ratio)
            self.roi = [self.roi_left, self.roi_top, self.roi_right, self.roi_bottom]
            self.signal_roi.emit(self.roi)

放入UI的object类内

        self.label = MyLabel(img_pth, self.img_state)
        # self.label.setMouseTracking(False)   # 若有设置鼠标跟踪的记得关闭

可以在主程序的类内初始化函数内加入pysignal接收端,用于接收框选的坐标值

self.ui.label.signal_roi.connect(self.save_roi)
  • 1
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值