• 本篇文章主要记录笔者在使用PyQt5的过程中,一些常用的代码技巧,以及好用可复用的代码

  • 如何实现软件只能启动单应用

def is_running(start_name: str):"""判断程序是否运行"""out_socket = QtNetwork.QLocalSocket()out_socket.connectToServer(start_name)is_running = out_socket.waitForConnected()print(is_running)return is_runningif is_running(start_name="test"):print("程序在运行")
else:localServer = QtNetwork.QLocalServer()localServer.listen("test")

  • 软件打包的spec文件的编写
# -*- mode: python ; coding: utf-8 -*-block_cipher = Nonea = Analysis(['main.py'],pathex=['xxx'],binaries=[],datas=[('resource','resource')],hiddenimports=[],hookspath=[],hooksconfig={},runtime_hooks=[],excludes=[],win_no_prefer_redirects=False,win_private_assemblies=False,cipher=block_cipher,noarchive=False)
pyz = PYZ(a.pure, a.zipped_data,cipher=block_cipher)exe = EXE(pyz,a.scripts,a.binaries,a.zipfiles,a.datas,  [],name='main',debug=False,bootloader_ignore_signals=False,strip=False,upx=True,upx_exclude=[],runtime_tmpdir=None,console=False,disable_windowed_traceback=False,target_arch=None,codesign_identity=None,entitlements_file=None,icon= "music.ico")

  • 自定义边框的程序
    实现效果:
import enum
from PyQt5 import QtGui, QtCore
from PyQt5.QtWidgets import QApplication, QWidget, QLineEdit
from PyQt5.QtWidgets import QPushButton, QTextEdit, QGridLayout, QHBoxLayout, QFrame, QStyle, QStyleOption
from PyQt5.QtGui import QPainter, QPainterPath, QPen, QBrush, QColor, QPalette, QRegion, QMouseEvent, QHoverEvent
from PyQt5.QtCore import QRect, QRectF, QSize, QPoint, QEvent, QMarginsfrom widgets.components.custom_border_draggers import LeftDragger, RightDragger, TopDragger, BottomDragger
from widgets.components.custom_border_draggers import TopLeftDragger, TopRightDragger, BottomLeftDragger, BottomRightDragger
from PyQt5.QtCore import *
from PyQt5.QtWidgets import QWidget, QApplication
from PyQt5.QtGui import *
from PyQt5.QtGui import *
from PyQt5.QtCore import *
from PyQt5.QtWidgets import *class TitleToolButton(QPushButton):def __init__(self):super().__init__()self.init_all()def init_all(self):self.setFixedSize(QSize(24,24))passdef set_icon(self, icon_path:str):icon_ = QIcon()icon_.addFile(icon_path)self.setIcon(icon_)class TitleBarWidget(QWidget):resize_window_signal = pyqtSignal()min_window_signal = pyqtSignal()close_window_signal = pyqtSignal()def __init__(self):super().__init__()self.init_all()def init_all(self):self.setAttribute(Qt.WA_TranslucentBackground)  # 场景透明self.setAttribute(Qt.WA_StyledBackground, True)self.hbox_layout = QHBoxLayout()self.setLayout(self.hbox_layout)self.hbox_layout.setSpacing(0)self.hbox_layout.setContentsMargins(0,0,0,0)self.setFixedHeight(40)self.setStyleSheet(self.styleSheet() + "QWidget {background-color: rgb(232, 222, 248);} QPushButton { background-color: rgb(232, 222, 248); border: 0px; }""QPushButton:hover{background-color: rgb(216, 207, 232);} QPushButton:pressed{background-color: rgb(207, 198, 223);}")self.hbox_layout.addStretch()# set min max close buttonsself.min_button = TitleToolButton()self.min_button.set_icon("resource/image/window/min_btn.png")self.min_button.clicked.connect(self.slots_min_button_clicked)self.hbox_layout.addWidget(self.min_button)self.max_button = TitleToolButton()self.max_button.set_icon("resource/image/window/max_btn.png")self.max_button.clicked.connect(self.slots_max_button_clicked)self.hbox_layout.addWidget(self.max_button)self.close_button = TitleToolButton()self.close_button.set_icon("resource/image/window/close_btn.png")self.close_button.clicked.connect(self.slots_close_button_clicked)self.hbox_layout.addWidget(self.close_button)self.hbox_layout.addItem(QSpacerItem(10, 10, QSizePolicy.Fixed, QSizePolicy.Fixed))def slots_min_button_clicked(self):"""明明规则: 槽函数 + 对象 + 事件类型:return:"""self.min_window_signal.emit()def slots_max_button_clicked(self):"""明明规则: 槽函数 + 对象 + 事件类型:return:"""self.resize_window_signal.emit()def slots_close_button_clicked(self):"""明明规则: 槽函数 + 对象 + 事件类型:return:"""self.close_window_signal.emit()def paintEvent(self, a0: QtGui.QPaintEvent) -> None:painter = QPainter(self)painter.setRenderHint(QPainter.Antialiasing)brush = QBrush(Qt.SolidPattern)color = QColor()color.setRgb(232, 222, 248)brush.setColor(color)painter.setBrush(brush)painter.setPen(Qt.transparent)rect = self.rect()rect.setWidth(rect.width() )rect.setHeight(rect.height() )painter.drawRoundedRect(rect, 10, 10)def mouseDoubleClickEvent(self, a0: QtGui.QMouseEvent) -> None:self.resize_window_signal.emit()class BaseFramelessWidget(QWidget):class State(enum.Enum):Init = 0Moving = 1Resizing = 2def __init__(self, target=None):super().__init__()# 最小700 * 700 最大和界面一样大self.setMinimumSize(900, 700)self.setMaximumSize(QDesktopWidget().availableGeometry().width(), QDesktopWidget().availableGeometry().height())self.state = BaseFramelessWidget.State.Initself.leftButtonPressed = Falseself.borderMargin = 5self.cornerMargin = 5self.activeBorderDragger = Noneself.borderDraggers = (LeftDragger(), RightDragger(), TopDragger(), BottomDragger())self.cornerDraggers = (TopLeftDragger(), TopRightDragger(), BottomLeftDragger(), BottomRightDragger())self.wholeWidgetDragPos = Noneself.setAttribute(Qt.WA_TranslucentBackground)  # 场景透明self.target = targetif not target:self.target = selfself.target.setMouseTracking(True)self.target.setWindowFlags(QtCore.Qt.WindowType.FramelessWindowHint)self.target.setAttribute(QtCore.Qt.WidgetAttribute.WA_Hover)self.target.installEventFilter(self)self.vbox_layout = QVBoxLayout()self.setLayout(self.vbox_layout)self.title_bar = TitleBarWidget()self.init_title_bar(self.title_bar)self.title_bar.resize_window_signal.connect(self.slots_resize_window)self.title_bar.close_window_signal.connect(self.slots_close_button_clicked)self.title_bar.min_window_signal.connect(self.slots_min_button_clicked)def init_title_bar(self, title_bar: QWidget):"""初始化标题栏:param title_bar::return:"""self.vbox_layout.setSpacing(0)self.vbox_layout.setContentsMargins(0,0,0,0)self.vbox_layout.addWidget(title_bar, 0 , Qt.AlignTop)passdef setBorderMargin(self, margin):self.borderMargin = margindef setCornerMargin(self, margin):self.cornerMargin = margindef selectActiveBorderDragger(self, pos):activeDragger = Nonefor dragger in self.borderDraggers:if dragger.isActive(pos, self.target.frameGeometry(), self.borderMargin):activeDragger = draggerfor dragger in self.cornerDraggers:if dragger.isActive(pos, self.target.frameGeometry(), self.cornerMargin):activeDragger = draggerreturn activeDraggerdef eventFilter(self, o, e):if e.type() == QEvent.Type.MouseMove or \e.type() == QEvent.Type.HoverMove or \e.type() == QEvent.Type.Leave or \e.type() == QEvent.Type.MouseButtonPress or \e.type() == QEvent.Type.MouseButtonRelease:switcher = {QEvent.Type.MouseMove: self.mouseMove,QEvent.Type.HoverMove: self.mouseHover,QEvent.Type.Leave: self.mouseLeave,QEvent.Type.MouseButtonPress: self.mousePress,QEvent.Type.MouseButtonRelease: self.mouseRelease}switcher.get(e.type())(e)return Trueelse:return super().eventFilter(o, e)def mousePress(self, event):if event.buttons() == QtCore.Qt.MouseButton.LeftButton:self.leftButtonPressed = Trueself.activeBorderDragger = self.selectActiveBorderDragger(event.globalPos())if self.activeBorderDragger is not None:self.state = BaseFramelessWidget.State.Resizingself.target.update()elif self.target.rect().marginsRemoved(QMargins(self.borderMargin, \self.borderMargin, \self.borderMargin, \self.borderMargin)) \.contains(event.pos()):self.state = BaseFramelessWidget.State.Movingself.target.update()self.wholeWidgetDragPos = event.pos()def mouseMove(self, event):if self.leftButtonPressed:if self.state == BaseFramelessWidget.State.Moving:self.target.move((event.globalPos() - self.wholeWidgetDragPos))elif self.state == BaseFramelessWidget.State.Resizing:rect = self.target.frameGeometry()self.activeBorderDragger.updateGeometry(rect, event.globalPos())if rect.width() <= self.target.minimumSize().width():rect.setLeft(self.target.frameGeometry().x())if rect.height() <= self.target.minimumSize().height():rect.setTop(self.target.frameGeometry().y())self.target.setGeometry(rect)def mouseHover(self, event):self.updateCursorShape(self.target.mapToGlobal(event.pos()))def mouseLeave(self, event):self.target.unsetCursor()self.target.update()def mouseRelease(self, event):if self.leftButtonPressed:self.leftButtonPressed = Falseself.state = BaseFramelessWidget.State.Initself.target.update()self.activeBorderDragger = Noneself.wholeWidgetDragPos = Nonedef updateCursorShape(self, pos):if self.target.isFullScreen() or self.target.isMaximized():if self.cursorchanged:self.target.unsetCursor()returnself.cursorchanged = TrueborderDragger = self.selectActiveBorderDragger(pos)if borderDragger is not None:self.target.setCursor(borderDragger.getCursorShape())else:self.target.unsetCursor()self.target.update()def paintEvent(self, a0: QtGui.QPaintEvent) -> None:painter = QPainter(self)painter.setRenderHint(QPainter.Antialiasing)brush = QBrush(Qt.SolidPattern)color = QColor()color.setRgb(243, 237, 247)brush.setColor(color)painter.setBrush(brush)painter.setPen(Qt.transparent)rect = self.rect()rect.setWidth(rect.width() )rect.setHeight(rect.height() )painter.drawRoundedRect(rect, 10, 10)def slots_resize_window(self):desktop = QDesktopWidget().availableGeometry()if self.size() == self.maximumSize():x =  (desktop.width() - self.minimumSize().width()) /2y = (desktop.height() - self.minimumSize().height()) /2self.setGeometry(int(x),int(y),self.minimumSize().width(),self.minimumSize().height())else:x =  (desktop.width() - self.maximumSize().width()) /2y = (desktop.height() - self.maximumSize().height()) /2self.setGeometry(x,y,self.maximumSize().width(),self.maximumSize().height())def slots_min_button_clicked(self):"""明明规则: 槽函数 + 对象 + 事件类型:return:"""self.showMinimized()def slots_close_button_clicked(self):"""明明规则: 槽函数 + 对象 + 事件类型:return:"""self.close()import sysif __name__ == '__main__':# 测试功能app = QApplication(sys.argv)widget = BaseFramelessWidget()widget.setMinimumSize(400, 400)widget.show()sys.exit(app.exec_())

依赖的文件:

from PyQt5 import QtGui, QtCore
from PyQt5.QtWidgets import QApplication, QWidget, QLineEdit
from PyQt5.QtWidgets import QPushButton, QTextEdit, QGridLayout, QHBoxLayout, QFrame, QStyle, QStyleOption
from PyQt5.QtGui import QPainter, QPainterPath, QPen, QBrush, QColor, QPalette, QRegion
from PyQt5.QtCore import QRect, QRectF, QSize, QPoint, QEvent# Hope this will not affect performance much.
class BorderDragger:def isActive(self, pos, framerect, borderWidth):raise Exception("Not implemented")def updateGeometry(self, framerect, pos):raise Exception("Not implemented")def getCursorShape(self):raise Exception("Not implemented")class CornerDragger(BorderDragger):verDragger = BorderDragger()horDragger = BorderDragger()def isActive(self, pos, framerect, borderWidth):return self.verDragger.isActive(pos, framerect, borderWidth) and \self.horDragger.isActive(pos, framerect, borderWidth)def updateGeometry(self, framerect, pos):self.verDragger.updateGeometry(framerect, pos)self.horDragger.updateGeometry(framerect, pos)def getCursorShape(self):raise Exception("Not implemented")class LeftDragger(BorderDragger):def isActive(self, pos, framerect, borderWidth):return framerect.contains(pos) and \pos.x() >= framerect.x() and \pos.x() <= framerect.x() + borderWidthdef updateGeometry(self, framerect, pos):framerect.setLeft(pos.x())def getCursorShape(self):return QtCore.Qt.CursorShape.SizeHorCursorclass RightDragger(BorderDragger):def isActive(self, pos, framerect, borderWidth):return framerect.contains(pos) and \pos.x() >= framerect.x() + framerect.width() - borderWidth and \pos.x() <= framerect.x() + framerect.width()def updateGeometry(self, framerect, pos):framerect.setRight(pos.x())def getCursorShape(self):return QtCore.Qt.CursorShape.SizeHorCursorclass TopDragger(BorderDragger):def isActive(self, pos, framerect, borderWidth):return framerect.contains(pos) and \pos.y() >= framerect.y() and \pos.y() <= framerect.y() + borderWidthdef updateGeometry(self, framerect, pos):framerect.setTop(pos.y())def getCursorShape(self):return QtCore.Qt.CursorShape.SizeVerCursorclass BottomDragger(BorderDragger):def isActive(self, pos, framerect, borderWidth):return framerect.contains(pos) and \pos.y() >= framerect.y() + framerect.height() - borderWidth and \pos.y() <= framerect.y() + framerect.height()def updateGeometry(self, framerect, pos):framerect.setBottom(pos.y())def getCursorShape(self):return QtCore.Qt.CursorShape.SizeVerCursorclass TopLeftDragger(CornerDragger):def __init__(self):self.verDragger = TopDragger()self.horDragger = LeftDragger()def getCursorShape(self):return QtCore.Qt.CursorShape.SizeFDiagCursorclass TopRightDragger(CornerDragger):def __init__(self):self.verDragger = TopDragger()self.horDragger = RightDragger()def getCursorShape(self):return QtCore.Qt.CursorShape.SizeBDiagCursorclass BottomLeftDragger(CornerDragger):def __init__(self):self.verDragger = BottomDragger()self.horDragger = LeftDragger()def getCursorShape(self):return QtCore.Qt.CursorShape.SizeBDiagCursorclass BottomRightDragger(CornerDragger):def __init__(self):self.verDragger = BottomDragger()self.horDragger = RightDragger()def getCursorShape(self):return QtCore.Qt.CursorShape.SizeFDiagCursor

  • Python打包后配置资源文件访问
# 资源文件目录访问
def source_path(relative_path):# 是否Bundle Resourceif getattr(sys, 'frozen', False):base_path = sys._MEIPASSelse:base_path = os.path.abspath(".")return os.path.join(base_path, relative_path)# 修改当前工作目录,使得资源文件可以被正确访问
cd = source_path('')
os.chdir(cd)

  • PyQt5 创建程序基本流程
import sys
from PyQt6.QtGui import *
from PyQt6.QtWidgets import *
from PyQt6.QtCore import *app = QApplication(sys.argv) # 窗体# 窗体实现部分
widget = QWidget()
widget.show()# 等待程序退出【阻塞】
ret = app.exec()
sys.exit(ret)

  • PyQt5播放音频
    def play_video(self, video_name, is_circle):self.preview_label.setVisible(False)self.player = QMediaPlayer()self.vw.setAttribute(Qt.WA_StyledBackground, True)self.vw.setStyleSheet("QWidget{background-color: rgb(25, 28, 40)}")self.vw.setFixedHeight(360)if self.start_vw == False:self.hbox_preview_layout.addWidget(self.vw)self.start_vw = Trueself.vw.show()self.player.setVideoOutput(self.vw)  # 视频播放输出的widget,就是上面定义的if is_circle:print("循环播放")self.play_list = QMediaPlaylist()self.play_list.setPlaybackMode(QMediaPlaylist.Loop)self.play_list.addMedia(QMediaContent(QUrl(video_name)))self.player.setPlaylist(self.play_list)else:self.player.setMedia(QMediaContent(QUrl(video_name)))  # 选取视频文件self.player.play()  # 播放视频

未完。。。待续

awesome PyQt5 的奇技淫巧相关推荐

  1. pyqt5搭建的简单的图像处理界面_PyQt5 布局浅析

    PyQt5是Python环境下用来开发UI界面的一个包.它容易上手,对初学者友好,并且拥有丰富的函数库,可以实现大部分桌面应用的开发需求,且支持QSS语言,能够对界面风格做个性化调整.总体来说,PyQ ...

  2. Python PyQt5 PySerial 书签备份 2018/12/6

    Bookmarks 书签栏 PyQt5 事件和信号 · PyQt5 中文教程 艾伦智能/pyqt5 pyserial-github pySerial API - pySerial 3.0 docume ...

  3. Anaconda3+python3.7.10+TensorFlow2.3.0+PyQt5环境搭建

    Anaconda3+python3.7.10+TensorFlow2.3.0+PyQt5环境搭建 一.Anaconda 创建 python3.7环境 1.进入 C:\Users\用户名 目录下,找到 ...

  4. pycharm+PyQt5+python最新开发环境配置,踩坑过程详解

    安装工具: Pycharm 专业版2017.3 PyQT5 python3 pyqt5-tools 设置扩展工具的参数找到setting->tools->external tools,点击 ...

  5. 开发工业上位机 用pyqt5_用Pyqt5开发的基于MTCNN、FaceNet人脸考勤系统

    import sys import cv2 from PyQt5 import QtCore, QtGui, QtWidgets from PyQt5.QtWidgets import * from ...

  6. pyqt5 视频播放器

    问题交流.反馈请到 https://github.com/moneypi/pyqt5_mediaplayer 首先肯定要安装pyqt5,顺便也安装一下opencv pip install PyQt5 ...

  7. Python培训分享:PyQT是什么?PyQt4和PyQt5的区别是什么?

    今天小编为大家介绍的课程是关于Python培训方面的教程,主要讲的是PyQT是什么?PyQt4和PyQt5的区别是什么?来看看下面的详细介绍吧. Python培训分享:PyQT是什么?PyQt4和Py ...

  8. 浏览器tab关闭事件_Python--使用Pyqt5实现简易浏览器(最新版本测试过)

    Python--使用Pyqt5实现简易浏览器(最新版本测试过) 博客说明 文章所涉及的资料来自互联网整理和个人总结,意在于个人学习和经验汇总,如有什么地方侵权,请联系本人删除,谢谢! 准备环境 首先我 ...

  9. 在macos上基于python2.7安装PyQt5

    在macos上基于python2.7安装PyQt5 在python3上面安装PyQt5是十分简单的,可是,在python2.7上安装这个东西,着实让人折腾了一把.要总结一下,年纪大了,记性不好. 首先 ...

最新文章

  1. swift (Singleton)模式
  2. 谭浩强C程序设计第四版答案
  3. 页面布局 HTML 4.0 Transitional” VS XHTML 1.0 Transitional 新的不一定就好用!
  4. java 技能鉴定_JAVA试题-技能鉴定
  5. c++二维数组指针详解
  6. python背景图片加载代码_2019.12.05-背景图片设置代码
  7. 万能文件在线预览项目,开源!
  8. uos安装方法_国产UOS(统一操作系统),虚拟机安装体验
  9. windows2016+sqlserver2017集群搭建alwayson之域控篇
  10. java 输入任何字符继续_Thinking in Java 4th chap13笔记-字符串
  11. android service 样例(电话录音和获取系统当前时间)
  12. 阿里AI两项技术刷新行业纪录,为城市大脑,OR也为无人车?
  13. python 启动参数_python启动参数
  14. shiro框架 4种授权方式 说明
  15. 简单机器学习系统的构建以及对于不对称性的分类介绍和性能评价
  16. [病毒分析]熊猫烧香应急处理方法
  17. 跨平台web app教育设备的一些设计标准
  18. Oracle 一种简单粗暴的办法解析XML文件的例子
  19. 高智伟:数据管理赋能交通行业数字化转型
  20. 软件版本(release、stable、lastest)的区别

热门文章

  1. 全流程重构京东服务市场系统
  2. 微博营销之微博软文撰写的几个技巧
  3. Android系统级开发进程清理功能的一些记录和发现
  4. 菜单MenuItem的使用
  5. 业内视频超分辨率新标杆!快手大连理工研究登上CVPR 2022
  6. 12306静态页面HTML制作
  7. Kali Aircrack-NG HashCat 破解Wi-Fi密码
  8. 女孩子:现代的“三从四德”
  9. iOS 什么时候调用dealloc
  10. Web 与排版学上的字体问题