asp网站开发技术总结与收获,建设银行网站怎么登录密码忘了怎么办,有效果的网站排名,网站搭建运营目录
一、前言
二、桌面摄像头软件
2.1、下载项目
2.2、功能介绍
三、打包工具#xff08;nuitka#xff09; 四、项目文件复制#xff08;我全部合到一个文件里面了#xff09;
五、结语 一、前言 看见b站的向军大叔用electron制作了一个桌面摄像头软件 但是#x…目录
一、前言
二、桌面摄像头软件
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.py2.2、功能介绍 启动后会自动打开默认摄像头 基础操作 左键长按拖拽移动 滚轮上下滑动放大和缩小摄像头画面 右键设置操作 选择边框颜色rgb格式 选择摄像头自由切换 窗口变形正方形窗口和圆形窗口的切换 隐藏 退出 系统托盘可右键选择隐藏或出现以及退出 三、打包工具nuitka Python——Windows使用Nuitka2.0打包保姆级教程-CSDN博客 我的打包命令 nuitka --mingw64 --show-progress --standalone --disable-console --enable-pluginpyside6 --plugin-enablenumpy --onefile --remove-output --windows-icon-from-icologo.ico camera.py 四、项目文件复制我全部合到一个文件里面了 # -*- coding: utf-8 -*-
# Author : pan
import time
import cv2
import numpy as npfrom 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 durationlabel 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()/2y 10else:# 如果没有父窗口计算使Toast窗口相对于屏幕居中的位置desktopRect QApplication.primaryScreen().availableGeometry()x (desktopRect.width() - sizeHint.width()) // 2y (desktopRect.height() - sizeHint.height()) // 2return x, y, sizeHint.width(), sizeHint.height()def fadeIn(self):# 创建并设置淡入动画fadeInAnimation QPropertyAnimation(self, bwindowOpacity, 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, bwindowOpacity)self.opacityAnimation.setStartValue(1.0)self.opacityAnimation.setEndValue(0.0)self.opacityAnimation.setDuration(500)# 创建并设置位置动画self.yAnimation QPropertyAnimation(self, bgeometry)targetY self.y() - 10self.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 Nonedef 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(ubg_gray)self.bg_gray.setGeometry(QRect(0, 0, 200, 65))self.bg_gray.setStyleSheet(u.QFrame{\nbackground-color: rgb(234,236,243);\nborder-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(uverticalLayout_3)self.verticalLayout_3.setContentsMargins(10, 11, 4, 11)self.verticalLayout_2 QVBoxLayout()# 设置右侧边距为5pxself.verticalLayout_2.setContentsMargins(0, 0, 7, 0)self.verticalLayout_2.setObjectName(uverticalLayout_2)self.window_top QHBoxLayout()self.window_top.setSpacing(10)self.window_top.setObjectName(uwindow_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(utext_title)self.text_title.setStyleSheet(u font-size: 9pt;\nfont-family: \\u5fae\u8f6f\u96c5\u9ed1\;\ncolor: #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(ubtn_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(uQPushButton {\nbackground-color: #07BB2C;\nborder: 2px solid #07BB2C;\ncolor: #3498db;\npadding: 1px;\nborder-radius: 5px;\n
}\n\n
QPushButton:hover {\nbackground-color: #09ED3A;\ncolor: #ffffff;\n
})self.window_top.addWidget(self.btn_min)self.btn_max QPushButton(self.bg_gray)self.btn_max.setObjectName(ubtn_max)self.btn_max.setMaximumSize(QSize(10, 10))self.btn_max.setStyleSheet(uQPushButton {\nbackground-color: #FFB206;\nborder: 2px solid #FFB206;\ncolor: #3498db;\npadding: 1px;\nborder-radius: 5px;\n
}\n\n
QPushButton:hover {\nbackground-color: #FFC033;\ncolor: #ffffff;\n
})self.window_top.addWidget(self.btn_max)self.btn_stop QPushButton(self.bg_gray)self.btn_stop.setObjectName(ubtn_stop)self.btn_stop.clicked.connect(self.hide) # 关联关闭窗口事件self.btn_stop.setMaximumSize(QSize(10, 10))self.btn_stop.setStyleSheet(u\n
\n
QPushButton {\nbackground-color: #EE514A;\nborder: 2px solid #EE514A;\ncolor: #3498db;\npadding: 1px;\nborder-radius: 5;\n
}\n\n
QPushButton:hover {\nbackground-color: #F1756F;\ncolor: #ffffff;\n
})self.window_top.addWidget(self.btn_stop)self.verticalLayout_2.addLayout(self.window_top)self.horizontalLayout QHBoxLayout()self.horizontalLayout.setObjectName(uhorizontalLayout)self.lineEdit QLineEdit(self.bg_gray)self.lineEdit.setObjectName(ulineEdit)self.horizontalLayout.addWidget(self.lineEdit)self.b_submit QPushButton(self.bg_gray)self.b_submit.clicked.connect(self.emitSignal) # 点击按钮时连接到发射信号的方法self.b_submit.setObjectName(ub_submit)self.b_submit.setMinimumSize(QSize(0, 0))self.b_submit.setStyleSheet(u QPushButton {\nborder-style: solid;\nborder-width: 2px;\nborder-radius: 15px;\nborder-color: rgb(88, 180, 107);\nfont-size: 7pt;\nfont-weight: bold;\npadding: 2px;\nbackground-color: rgb(88, 180, 107);\ncolor: rgb(255, 255, 255);\n}\nQPushButton:hover {\nborder-color: rgb(100, 100, 100);\nbackground-color: rgb(183, 255, 189);\ncolor: rgb(88, 180, 107);\n}\nQPushButton:pressed {\nborder-color: rgb(42, 42, 42);\nbackground-color: rgb(160, 255, 163);\ncolor: 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)# setupUiSlot()def emitSignal(self):text self.lineEdit.text()self.textEntered.emit(text) # 发射信号并传递lineEdit中的文本def retranslateUi(self, Form):Form.setWindowTitle(QCoreApplication.translate(Form, uForm, 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, u255,255,255, None))self.b_submit.setText(QCoreApplication.translate(Form, u\u786e\u8ba4, None))# retranslateUidef 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 Noneevent.accept()# 摄像头检测类
class Camera:def __init__(self, cam_preset_num5):self.cam_preset_num cam_preset_numdef get_cam_num(self):cnt 0devices []for device in range(0, self.cam_preset_num):stream cv2.VideoCapture(device, cv2.CAP_DSHOW)grabbed stream.grab()stream.release()if not grabbed:continueelse:cnt cnt 1devices.append(device)return cnt, devices# 摄像头线程
class CameraThread(QThread):change_pixmap_signal Signal(np.ndarray)def __init__(self, device_id0):super().__init__()self.device_id device_idself.is_paused Falseself.mutex QMutex()self.exiting Falseself.cap Nonedef 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:breakself.mutex.unlock()self.cap.release()self.cap Nonedef set_device_id(self, device_id):self.device_id device_iddef pause(self):self.mutex.lock()self.is_paused Trueself.mutex.unlock()def resume(self):self.mutex.lock()self.is_paused Falseself.mutex.unlock()def stop(self):self.exiting Trueself.wait()def set_device_id(self, device_id):self.device_id device_iddef 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 200self.color 255,255,255self.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 Falseself.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, bwindowOpacity, 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()) // 2y (desktopRect.height() - sizeHint.height()) // 2return 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(请重新选择摄像头)returnself.image cv2.cvtColor(image_data, cv2.COLOR_BGR2RGB)height, width, channel self.image.shapebytesPerLine 3 * widthimage 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 - 10label_size self.label.sizeHint()scaled_image square_image.scaled(new_size, new_size, Qt.KeepAspectRatio)# 将 QImage 转换为 QPixmappixmap QPixmap.fromImage(scaled_image)# 创建一个圆形路径path QPainterPath()path.addEllipse(0, 0, new_size, new_size)# 创建一个与 scaled_image 大小相同的的 QPixmapresult_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, flag1):try:if flag 0:r 0else:r self.size / 2self.label.setStyleSheet(ffont-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_InputColorself.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 Falseself.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 1self.reset_style(flag0) # 背景 变成正方形# 隐藏if action set_hide_action:self.hide()# 退出if action set_quit_action:self.close()# 颜色设置def colorEntered(self, text):print(1)# TODO 数据处理self.color textself.reset_style()self.input_color_window.hide()# 打开窗口 Ui_InputColordef 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, up0, down0):self.size self.size upself.size self.size - downif self.window_shape 1:self.reset_style(flag0) # 背景 变成正方形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:# 向下滚动(触发两次 因为背景上有bugself.row_event(down1)self.row_event(down1)else:# 向上滚动(触发两次 因为背景上有bugself.row_event(up1)self.row_event(up1)return Truereturn super().event(event)if __name__ __main__:app QApplication([])# 创建系统托盘图标tray_icon QSystemTrayIcon(QIcon(logo.jpg), parentapp)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其实我只是想自己拿来用用