Python——桌面摄像头软件(附源码+打包)

目录

一、前言

二、桌面摄像头软件

2.1、下载项目

2.2、功能介绍

三、打包工具(nuitka)

 四、项目文件复制(我全部合到一个文件里面了)

五、结语


一、前言

看见b站的向军大叔用electron制作了一个桌面摄像头软件

但是,我不怎么熟悉前端,自己就用pyside6简单制作一个

二、桌面摄像头软件

2.1、下载项目

软件下载地址:(下载后,双击即可运行——60MB左右)

https://wwm.lanzout.com/ibIEL1q0xt8d
密码:eg34

工程文件下载地址:

camera-python.zip - 蓝奏云

启动项目:

# 下载包
pip install -r requirements.txt

# 运行项目
python main.py

2.2、功能介绍

启动后,会自动打开默认摄像头

基础操作

左键长按:拖拽移动

滚轮上下滑动:放大和缩小摄像头画面

右键设置操作

选择边框颜色(rgb格式)

选择摄像头(自由切换)

窗口变形(正方形窗口和圆形窗口的切换)

隐藏

退出

系统托盘(可右键选择隐藏或出现,以及退出)

三、打包工具(nuitka)

 Python——Windows使用Nuitka2.0打包(保姆级教程)-CSDN博客

我的打包命令:

 

nuitka --mingw64 --show-progress --standalone --disable-console --enable-plugin=pyside6 --plugin-enable=numpy --onefile --remove-output --windows-icon-from-ico=logo.ico camera.py

 四、项目文件复制(我全部合到一个文件里面了)

# -*- coding: utf-8 -*-
# @Author : pan
import time
import cv2
import numpy as np

from PySide6.QtCore import (Qt, QTimer, QPropertyAnimation, QEasingCurve,
                            QParallelAnimationGroup, QThread, QMutex,
                            Signal, Slot, QCoreApplication, QDate, QDateTime,
                            QLocale, QMetaObject, QObject, QPoint, QRect,
                            QSize, QTime, QUrl, QAbstractAnimation, QEvent)
from PySide6.QtGui import (QPixmap, QPainter, QColor, QFontMetrics, QPen,
                           QWheelEvent, QCursor, QAction, QImage, QPainterPath,
                           QBrush, QConicalGradient, QFont, QFontDatabase,
                           QGradient, QIcon, QKeySequence, QLinearGradient,
                           QRadialGradient, QTransform)
from PySide6.QtWidgets import (QApplication, QWidget, QLabel, QMenu, QDialog,
                               QVBoxLayout, QLineEdit, QPushButton, QMessageBox,
                               QInputDialog, QFrame, QHBoxLayout, QLayout,
                               QSizePolicy, QSpacerItem, QSystemTrayIcon)



# 提示组件
class Toast(QWidget):
    def __init__(
        self,
        text: str,
        duration: int = 3000,
        parent: QWidget = None,
    ):
        super().__init__(parent)
        self.setWindowFlags(Qt.FramelessWindowHint | Qt.WindowStaysOnTopHint)
        self.setAttribute(Qt.WA_TranslucentBackground, True)
        self.duration = duration

        label = QLabel(self)
        label.setText(text)
        label.setStyleSheet("""
            background-color: rgba(60, 179, 113, 0.8);
            color: white;
            font-size: 16px;
            padding: 12px;
            border-radius: 4px;
        """)
        label.setAlignment(Qt.AlignCenter)

        fm = QFontMetrics(label.font())
        width = fm.boundingRect(text).width() + 80

        # 高度与宽度
        label.setFixedWidth(width)
        label.setFixedHeight(40)

        self.setGeometry(*self.calculatePosition(label.sizeHint()))



        self.fadeIn()

        self.animationTimer = QTimer()

        self.animationTimer.timeout.connect(self.fadeOut)
        self.animationTimer.start(self.duration)

    def calculatePosition(self, sizeHint):
        if self.parent() is not None:
            # 如果存在父窗口,计算使Toast窗口相对于父窗口居中的位置
            x = self.parent().width() / 2 - sizeHint.width()/2
            y = 10

        else:
            # 如果没有父窗口,计算使Toast窗口相对于屏幕居中的位置
            desktopRect = QApplication.primaryScreen().availableGeometry()
            x = (desktopRect.width() - sizeHint.width()) // 2
            y = (desktopRect.height() - sizeHint.height()) // 2
        return x, y, sizeHint.width(), sizeHint.height()

    def fadeIn(self):
        # 创建并设置淡入动画
        fadeInAnimation = QPropertyAnimation(self, b"windowOpacity", self)
        fadeInAnimation.setStartValue(0)
        fadeInAnimation.setEndValue(1)
        fadeInAnimation.setDuration(500)
        fadeInAnimation.finished.connect(lambda: print('加载成功'))
        # 启动淡入动画
        fadeInAnimation.start()

        print('in')

    # 淡出动画
    def fadeOut(self):
        print('out')
        # 停止计时器
        self.animationTimer.stop()
        # 断开计时器的超时信号与当前方法的连接
        self.animationTimer.timeout.disconnect(self.fadeOut)

        # 创建并设置并行动画组
        self.parallelAnimation = QParallelAnimationGroup()

        # 创建并设置不透明度动画
        self.opacityAnimation = QPropertyAnimation(self, b"windowOpacity")
        self.opacityAnimation.setStartValue(1.0)
        self.opacityAnimation.setEndValue(0.0)
        self.opacityAnimation.setDuration(500)

        # 创建并设置位置动画
        self.yAnimation = QPropertyAnimation(self, b"geometry")
        targetY = self.y() - 10
        self.yAnimation.setStartValue(self.geometry())
        self.yAnimation.setEndValue(self.geometry().translated(0, targetY))
        self.yAnimation.setDuration(500)
        self.yAnimation.setEasingCurve(QEasingCurve.OutCubic)

        # 将动画添加到并行动画组中
        self.parallelAnimation.addAnimation(self.opacityAnimation)
        self.parallelAnimation.addAnimation(self.yAnimation)

        # 连接并行动画组的完成信号与关闭窗口的槽
        self.parallelAnimation.finished.connect(self.close)

        # 启动动画组
        self.parallelAnimation.start(QAbstractAnimation.DeleteWhenStopped)


    def paintEvent(self, event):
        painter = QPainter(self)
        painter.fillRect(self.rect(), QColor(0, 0, 0, 0))

    def mousePressEvent(self, event):
        pass

# 弹窗 输入框
class Ui_InputColor(QWidget):
    textEntered = Signal(str)  # 定义一个带有字符串参数的信号

    def __init__(self):
        super().__init__()
        self.drag_position = None


    def setupUi(self, Form):

        Form.setObjectName("Form")  # 直接设置对象名称
        Form.resize(200, 70)

        # 设置背景颜色和透明度
        Form.setWindowFlags(Qt.FramelessWindowHint)  # 设置无边框窗口
        Form.setAttribute(Qt.WA_TranslucentBackground)  # 设置窗口透明

        self.bg_gray = QFrame(Form)
        self.bg_gray.setObjectName(u"bg_gray")
        self.bg_gray.setGeometry(QRect(0, 0, 200, 65))
        self.bg_gray.setStyleSheet(u".QFrame{\n"
"	background-color: rgb(234,236,243);\n"
"	border-radius:5px;\n"
"}")
        self.bg_gray.setFrameShape(QFrame.StyledPanel)
        self.bg_gray.setFrameShadow(QFrame.Raised)
        self.verticalLayout_3 = QVBoxLayout(self.bg_gray)
        self.verticalLayout_3.setSpacing(0)
        self.verticalLayout_3.setObjectName(u"verticalLayout_3")
        self.verticalLayout_3.setContentsMargins(10, 11, 4, 11)
        self.verticalLayout_2 = QVBoxLayout()
        # 设置右侧边距为5px
        self.verticalLayout_2.setContentsMargins(0, 0, 7, 0)

        self.verticalLayout_2.setObjectName(u"verticalLayout_2")
        self.window_top = QHBoxLayout()
        self.window_top.setSpacing(10)
        self.window_top.setObjectName(u"window_top")
        self.window_top.setSizeConstraint(QLayout.SetFixedSize)
        self.window_top.setContentsMargins(0, 0, 0, 0)
        self.text_title = QLabel(self.bg_gray)
        self.text_title.setObjectName(u"text_title")
        self.text_title.setStyleSheet(u"    font-size: 9pt;\n"
"    font-family: \"\u5fae\u8f6f\u96c5\u9ed1\";\n"
"    color: #333;\n"
"font-weight: bold;")

        self.window_top.addWidget(self.text_title)

        self.h_spacer = QSpacerItem(40, 20, QSizePolicy.Expanding, QSizePolicy.Minimum)

        self.window_top.addItem(self.h_spacer)

        self.btn_min = QPushButton(self.bg_gray)
        self.btn_min.setObjectName(u"btn_min")
        sizePolicy = QSizePolicy(QSizePolicy.Minimum, QSizePolicy.Fixed)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(self.btn_min.sizePolicy().hasHeightForWidth())
        self.btn_min.setSizePolicy(sizePolicy)
        self.btn_min.setMaximumSize(QSize(10, 10))
        self.btn_min.setStyleSheet(u"QPushButton {\n"
"    background-color: #07BB2C;\n"
"    border: 2px solid #07BB2C;\n"
"    color: #3498db;\n"
"    padding: 1px;\n"
"    border-radius: 5px;\n"
"}\n"
" \n"
"QPushButton:hover {\n"
"    background-color: #09ED3A;\n"
"    color: #ffffff;\n"
"}")

        self.window_top.addWidget(self.btn_min)

        self.btn_max = QPushButton(self.bg_gray)
        self.btn_max.setObjectName(u"btn_max")
        self.btn_max.setMaximumSize(QSize(10, 10))
        self.btn_max.setStyleSheet(u"QPushButton {\n"
"    background-color: #FFB206;\n"
"    border: 2px solid #FFB206;\n"
"    color: #3498db;\n"
"    padding: 1px;\n"
"    border-radius: 5px;\n"
"}\n"
" \n"
"QPushButton:hover {\n"
"    background-color: #FFC033;\n"
"    color: #ffffff;\n"
"}")

        self.window_top.addWidget(self.btn_max)

        self.btn_stop = QPushButton(self.bg_gray)
        self.btn_stop.setObjectName(u"btn_stop")

        self.btn_stop.clicked.connect(self.hide)  # 关联关闭窗口事件

        self.btn_stop.setMaximumSize(QSize(10, 10))
        self.btn_stop.setStyleSheet(u"\n"
"\n"
"QPushButton {\n"
"    background-color: #EE514A;\n"
"    border: 2px solid #EE514A;\n"
"    color: #3498db;\n"
"    padding: 1px;\n"
"    border-radius: 5;\n"
"}\n"
" \n"
"QPushButton:hover {\n"
"    background-color: #F1756F;\n"
"    color: #ffffff;\n"
"}")

        self.window_top.addWidget(self.btn_stop)


        self.verticalLayout_2.addLayout(self.window_top)

        self.horizontalLayout = QHBoxLayout()
        self.horizontalLayout.setObjectName(u"horizontalLayout")
        self.lineEdit = QLineEdit(self.bg_gray)
        self.lineEdit.setObjectName(u"lineEdit")

        self.horizontalLayout.addWidget(self.lineEdit)

        self.b_submit = QPushButton(self.bg_gray)

        self.b_submit.clicked.connect(self.emitSignal)  # 点击按钮时连接到发射信号的方法

        self.b_submit.setObjectName(u"b_submit")
        self.b_submit.setMinimumSize(QSize(0, 0))
        self.b_submit.setStyleSheet(u"            QPushButton {\n"
"                border-style: solid;\n"
"                border-width: 2px;\n"
"                border-radius: 15px;\n"
"                border-color: rgb(88, 180, 107);\n"
"                font-size: 7pt;\n"
"                font-weight: bold;\n"
"                padding: 2px;\n"
"                background-color: rgb(88, 180, 107);\n"
"                color: rgb(255, 255, 255);\n"
"            }\n"
"            QPushButton:hover {\n"
"                border-color: rgb(100, 100, 100);\n"
"                background-color: rgb(183, 255, 189);\n"
"				color: rgb(88, 180, 107);\n"
"            }\n"
"            QPushButton:pressed {\n"
"                border-color: rgb(42, 42, 42);\n"
"                background-color: rgb(160, 255, 163);\n"
"				color: rgb(88, 180, 107);\n"
"            }")

        self.horizontalLayout.addWidget(self.b_submit)


        self.verticalLayout_2.addLayout(self.horizontalLayout)


        self.verticalLayout_3.addLayout(self.verticalLayout_2)


        self.retranslateUi(Form)

        QMetaObject.connectSlotsByName(Form)
    # setupUi

    @Slot()
    def emitSignal(self):
        text = self.lineEdit.text()
        self.textEntered.emit(text)  # 发射信号,并传递lineEdit中的文本

    def retranslateUi(self, Form):
        Form.setWindowTitle(QCoreApplication.translate("Form", u"Form", None))
        self.text_title.setText(QCoreApplication.translate("Form", u"\u8bf7\u8f93\u5165\u8272\u53f7", None))
        self.btn_min.setText("")
        self.btn_max.setText("")
        self.btn_stop.setText("")
        self.lineEdit.setPlaceholderText(QCoreApplication.translate("Form", u"255,255,255", None))
        self.b_submit.setText(QCoreApplication.translate("Form", u"\u786e\u8ba4", None))
    # retranslateUi
    def mousePressEvent(self, event):
        if event.button() == Qt.LeftButton:
            self.drag_position = event.globalPosition().toPoint() - self.frameGeometry().topLeft()
            event.accept()

    def mouseMoveEvent(self, event):
        if event.buttons() == Qt.LeftButton and self.drag_position:
            self.move(event.globalPosition().toPoint() - self.drag_position)
            event.accept()

    def mouseReleaseEvent(self, event):
        if event.button() == Qt.LeftButton:
            self.drag_position = None
            event.accept()


# 摄像头检测类
class Camera:
    def __init__(self, cam_preset_num=5):
        self.cam_preset_num = cam_preset_num

    def get_cam_num(self):
        cnt = 0
        devices = []
        for device in range(0, self.cam_preset_num):
            stream = cv2.VideoCapture(device, cv2.CAP_DSHOW)
            grabbed = stream.grab()
            stream.release()
            if not grabbed:
                continue
            else:
                cnt = cnt + 1
                devices.append(device)
        return cnt, devices

# 摄像头线程
class CameraThread(QThread):
    change_pixmap_signal = Signal(np.ndarray)

    def __init__(self, device_id=0):
        super().__init__()
        self.device_id = device_id
        self.is_paused = False
        self.mutex = QMutex()
        self.exiting = False
        self.cap = None

    def run(self):
        self.cap = cv2.VideoCapture(self.device_id)
        while not self.exiting:
            self.mutex.lock()
            if not self.is_paused:
                ret, frame = self.cap.read()
                if ret:
                    self.change_pixmap_signal.emit(frame)
                else:
                    break
            self.mutex.unlock()

        self.cap.release()
        self.cap = None

    def set_device_id(self, device_id):
        self.device_id = device_id

    def pause(self):
        self.mutex.lock()
        self.is_paused = True
        self.mutex.unlock()

    def resume(self):
        self.mutex.lock()
        self.is_paused = False
        self.mutex.unlock()

    def stop(self):
        self.exiting = True
        self.wait()

    def set_device_id(self, device_id):
        self.device_id = device_id

    def stop(self):
        self.exiting = True

# 主窗口
class MyWindow(QWidget):

    def __init__(
            self,
            text: str,
            parent: QWidget = None,
    ):
        super().__init__(parent)
        # 设置窗口属性
        self.setWindowFlags(Qt.FramelessWindowHint | Qt.WindowStaysOnTopHint)
        self.setAttribute(Qt.WA_TranslucentBackground, True)

        # 窗口大小
        self.size = 200
        self.color = "255,255,255"

        self.window_shape = 0  # 0是圆

        # 子线程
        self.camera_thread = CameraThread()
        self.camera_thread.change_pixmap_signal.connect(self.image_data_slot)
        self.camera_thread.start()

        self.select_camera = False
        self.input_color_window = None

        # 创建标签并设置样式
        self.label = QLabel(self)
        self.label.setText(text)
        self.reset_style()  # 样式刷新
        self.label.setAlignment(Qt.AlignCenter)
        # 设置标签尺寸
        self.label.setAlignment(Qt.AlignCenter)
        self.label.setFixedSize(self.size, self.size)  # 设置标签的宽度和高度

        # 设置窗口位置
        self.setGeometry(*self.calculatePosition(self.label.sizeHint()))

        self.fadeIn()

    def fadeIn(self):
        # 创建并设置淡入动画
        fadeInAnimation = QPropertyAnimation(self, b"windowOpacity", self)
        fadeInAnimation.setStartValue(0)
        fadeInAnimation.setEndValue(1)
        fadeInAnimation.setDuration(500)
        fadeInAnimation.finished.connect(lambda: print('窗口 加载成功'))
        # 启动淡入动画
        fadeInAnimation.start()

    # 出现在屏幕居中的位置
    def calculatePosition(self, sizeHint):
        desktopRect = QApplication.primaryScreen().availableGeometry()
        x = (desktopRect.width() - sizeHint.width()) // 2
        y = (desktopRect.height() - sizeHint.height()) // 2
        return x, y, sizeHint.width(), sizeHint.height()

    def paintEvent(self, event):
        painter = QPainter(self)
        painter.fillRect(self.rect(), QColor(0, 0, 0, 0))

    def image_data_slot(self, image_data):

        if self.select_camera is True:
            self.label.clear()
            self.label.setText('请重新选择摄像头')
            return

        self.image = cv2.cvtColor(image_data, cv2.COLOR_BGR2RGB)
        height, width, channel = self.image.shape
        bytesPerLine = 3 * width
        image = QImage(self.image.data, width, height, bytesPerLine, QImage.Format_RGB888)

        # 将图片先裁剪为正方形
        width = image.width()
        height = image.height()
        size = min(width, height)
        square_image = image.copy((width - size) // 2, (height - size) // 2, size, size)

        # 计算缩放比例
        new_size = self.size - 10
        label_size = self.label.sizeHint()
        scaled_image = square_image.scaled(new_size, new_size, Qt.KeepAspectRatio)

        # 将 QImage 转换为 QPixmap
        pixmap = QPixmap.fromImage(scaled_image)

        # 创建一个圆形路径
        path = QPainterPath()
        path.addEllipse(0, 0, new_size, new_size)

        # 创建一个与 scaled_image 大小相同的的 QPixmap
        result_pixmap = QPixmap(new_size, new_size)
        result_pixmap.fill(Qt.transparent)

        # 在 result_pixmap 上绘制圆形图像
        painter = QPainter(result_pixmap)
        if self.window_shape == 0:
            painter.setClipPath(path)  # 设置裁剪路径
        painter.setRenderHint(QPainter.Antialiasing)  # 设置抗锯齿
        painter.drawPixmap(0, 0, pixmap)  # 绘制原始图像

        painter.end()
        # 在 label 上显示圆形图像
        self.label.setPixmap(result_pixmap)

    def reset_style(self, flag=1):
        try:
            if flag == 0:
                r = 0
            else:
                r = self.size / 2
            self.label.setStyleSheet(f"""
            font-family: Arial, sans-serif; /* 设置字体 */
            font-size: 12pt; /* 设置字体大小 */

            background-color: rgb({self.color}); /* 设置背景颜色为红色 */
            padding: 0px; 
            border-radius: {r}; /* 设置圆角大小为宽度的一半 */
                    """)
        except Exception as e:
            print(e)


    def mousePressEvent(self, event):
        if event.button() == Qt.LeftButton:
            self.drag_position = event.globalPosition().toPoint() - self.frameGeometry().topLeft()
            event.accept()

        # 右键 打开菜单
        if event.button() == Qt.RightButton:

            menu = QMenu(self)
            set_color_action = menu.addAction("设置边框色")
            set_camera_action = menu.addAction("选择摄像头")
            set_camera_shape = menu.addAction('圆形窗口') if self.window_shape == 1 else menu.addAction('正方形窗口')
            set_hide_action = menu.addAction("隐藏")
            set_quit_action = menu.addAction("退出")
            # 修改 exec_ 弃用警告
            action = menu.exec(self.mapToGlobal(event.position().toPoint()))


            if action == set_color_action:
                # 打开窗口 Ui_InputColor
                self.open_input_color_window()
            # 获取目前所有摄像头的设备号,然后把设备号弄成一个菜单,让用户选择
            if action == set_camera_action:
                self.select_camera = True

                # 如果有摄像头在运行
                if self.camera_thread.cap is not None:
                    # 这里给我绘制一个标签,等待2s再消失
                    self.toast = Toast("正在关闭摄像头中", 1000, self)
                    self.toast.show()
                    time.sleep(1)
                    self.camera_thread.stop()  # 停止摄像头播放
                    return

                # 检测摄像头可用设备,把设备号弄成一个菜单,让用户选择
                # 获取本地摄像头数量
                _, cams = Camera().get_cam_num()
                popMenu = QMenu()
                popMenu.setFixedWidth(110)
                popMenu.setStyleSheet('''
                    QMenu {
                    font-size: 9px;
                    font-family: "Microsoft YaHei UI";
                    font-weight: light;
                    color:white;
                    padding-left: 5px;
                    padding-right: 5px;
                    padding-top: 4px;
                    padding-bottom: 4px;
                    border-style: solid;
                    border-width: 0px;
                    border-color: rgba(255, 212, 255, 255);
                    border-radius: 3px;
                    background-color: rgba(16,155,226,50);
                    }''')
                for cam in cams:
                    action = QAction(f'{cam} 号摄像头')
                    popMenu.addAction(action)
                pos = QCursor.pos()
                action = popMenu.exec(pos)

                # 设置摄像头来源
                if action:
                    str_temp = ''
                    selected_stream_source = str_temp.join(filter(str.isdigit, action.text()))  # 获取摄像头号,去除非数字字符
                    self.toast = Toast(f"摄像头设备是:{selected_stream_source}", 1000, self)
                    self.toast.show()
                    self.select_camera = False

                    self.camera_thread = CameraThread()
                    self.camera_thread.device_id = int(selected_stream_source)
                    self.camera_thread.change_pixmap_signal.connect(self.image_data_slot)
                    self.camera_thread.start()

            # 切换窗口
            if action == set_camera_shape:
                #
                if self.window_shape == 1:
                    self.window_shape = 0 # 切换为圆形
                    self.reset_style()  # 切换为圆形


                else:
                    self.window_shape = 1
                    self.reset_style(flag=0)  # 背景 变成正方形
            # 隐藏
            if action == set_hide_action:
                self.hide()

            # 退出
            if action == set_quit_action:
                self.close()


    # 颜色设置
    def colorEntered(self, text):
        print(1)
        # TODO 数据处理
        self.color = text
        self.reset_style()
        self.input_color_window.hide()

    #  打开窗口 Ui_InputColor
    def open_input_color_window(self):
        if self.input_color_window is None:  # 只有当窗口对象尚未创建时才创建它
            self.input_color_window = Ui_InputColor()
            self.input_color_window.setupUi(self.input_color_window)
            self.input_color_window.setWindowFlag(Qt.FramelessWindowHint)  # 设置窗口标志:隐藏窗口边框
            self.input_color_window.setWindowFlags(Qt.FramelessWindowHint | Qt.WindowStaysOnTopHint)  # 设置窗口标志位

            self.input_color_window.textEntered.connect(self.colorEntered)  # 连接子窗口的信号和父窗口的槽

        # 窗口显示在父窗口的中心
        self.input_color_window.move(
            self.x() + (self.width() - self.input_color_window.width()) / 2,
            self.y() + (self.height() - self.input_color_window.height()) / 2
        )
        self.input_color_window.show()

    def mouseMoveEvent(self, event):

        # 左键 移动创建
        if event.buttons() == Qt.LeftButton:
            self.move(event.globalPosition().toPoint() - self.drag_position)
            event.accept()

    def mouseReleaseEvent(self, event):
        self.drag_position = None

    # 窗口大小变换
    def row_event(self, up=0, down=0):
        self.size = self.size + up
        self.size = self.size - down
        if self.window_shape == 1:
            self.reset_style(flag=0)  # 背景 变成正方形
        else:
            self.reset_style()  # 切换为圆形

        self.label.setFixedSize(self.size, self.size)  # 设置标签的宽度和高度
        self.setFixedSize(self.size, self.size)

    def event(self, event):
        if event.type() == QWheelEvent.Wheel:
            # 阻止默认的滚动行为
            event.ignore()

            # 获取滚动方向和距离
            delta = event.angleDelta().y() / 120

            # 根据滚动方向和距离执行相应操作
            if delta < 0:
                # 向下滚动(触发两次 因为背景上有bug
                self.row_event(down=1)
                self.row_event(down=1)
            else:
                # 向上滚动(触发两次 因为背景上有bug
                self.row_event(up=1)
                self.row_event(up=1)

            return True
        return super().event(event)


if __name__ == "__main__":
    app = QApplication([])

    # 创建系统托盘图标
    tray_icon = QSystemTrayIcon(QIcon("logo.jpg"), parent=app)
    tray_icon.setToolTip("Camera By Pan")

    # 创建并设置托盘图标的右键菜单
    menu = QMenu()
    show_action = menu.addAction("出现")     # 让window窗口出现
    hide_action = menu.addAction("隐藏")     # 让window窗口隐藏
    exit_action = menu.addAction("退出")
    tray_icon.setContextMenu(menu)
    # 显示托盘图标
    tray_icon.show()

    window = MyWindow("Camera Software By Pan")
    # 使窗口不在任务栏出现
    window.setWindowFlags(window.windowFlags() | Qt.Tool)  # 或者使用 Qt.SubWindow,根据你的需求和测试结果选择
    # 注意:
    # 使用Qt.Tool标志会使得窗口不在任务栏显示,这对于某些辅助工具或临时窗口是有用的。
    # 然而,这种改变也可能影响窗口的关闭行为和资源管理,尤其是在与系统托盘图标交互的上下文中。
    # 这导致我在关闭子窗口的时候,会导致程序崩溃!!!
    # 这导致我在关闭子窗口的时候,会导致程序崩溃!!!
    # 这导致我在关闭子窗口的时候,会导致程序崩溃!!!

    window.show()

    # 连接信号到槽函数
    exit_action.triggered.connect(app.quit)
    show_action.triggered.connect(window.show)
    hide_action.triggered.connect(window.hide)

    app.exec()


五、结语

  • 如果你有任何问题,欢迎在评论区留言,我会尽快回复。
  • 很久没有碰pyside6,而且学的很浅显,写了屎山代码
  • 目前只能保证功能实现,里面还有一些小bug
  • 但是不影响正常使用,就这样吧~

PS:其实我只是想自己拿来用用

  • 12
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Pan_peter

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值