LED Player ICON完成

本文讨论了使用Photoshop制作PNG图标时遇到的尺寸问题。作者发现官方推荐尺寸为80X80的图标在上传时会报错尺寸过大,而78X78的图标则可以正常上传。此外,90X90的图标同样没有问题,这表明问题可能不在于具体的像素尺寸,而是PNG文件的整体大小。

LED Player

 

用PS做一个78X78的PNG图标,官方网上写的建议尺寸是80X80尺寸.

期间发生奇怪的问题,我从网上下的PNG图标80X80时候说尺寸太大.到78X78的时候才不报错.

自己用PS重新做了一个90X90都能用,怀疑80X80不是必要尺寸,而是看整体PNG的大小.

在下图的图标处设置一下路径即可.

 

LED Player

import sys import os import cv2 import traceback from datetime import datetime from PyQt5.QtCore import Qt, QThread, pyqtSignal, QUrl from PyQt5.QtWidgets import (QApplication, QMainWindow, QLabel, QVBoxLayout, QWidget, QPushButton, QHBoxLayout, QMessageBox, QFileDialog, QGroupBox, QStatusBar, QTextEdit, QTabWidget, QTableWidget, QTableWidgetItem, QHeaderView, QComboBox, QScrollArea, QTabBar, QSizePolicy, QCheckBox) from PyQt5.QtGui import QImage, QPixmap, QIcon, QFont, QColor from PyQt5.QtMultimedia import QMediaPlayer, QMediaContent from ultralytics import YOLO # ================= 现代专业样式表 ================= STYLE_SHEET = """ QMainWindow { background-color: #F8F9FA; font-family: 'Segoe UI'; } QGroupBox { border: 2px solid #E9ECEF; border-radius: 8px; margin-top: 1ex; padding: 15px; background-color: white; } QGroupBox::title { subcontrol-origin: margin; left: 10px; padding: 0 8px; color: #212529; font-weight: 600; font-size: 14px; } QPushButton { background-color: #4A90E2; color: white; border: none; padding: 10px 20px; border-radius: 6px; min-width: 120px; font-size: 13px; } QPushButton:hover { background-color: #357ABD; } QPushButton:disabled { background-color: #CED4DA; } QLabel { font-size: 13px; color: #495057; } QStatusBar { background-color: #E9ECEF; color: #6C757D; font-size: 12px; } QTabWidget { background: white; } QTabBar::tab { background: #E9ECEF; border: 1px solid #DEE2E6; padding: 10px 20px; font-size: 13px; color: #6C757D; min-width: 120px; } QTabBar::tab:selected { background: #4A90E2; color: white; border-color: #4A90E2; } QTableWidget { alternate-background-color: #F8F9FA; font-size: 12px; selection-background-color: #B9D6F3; } QScrollArea { border: none; background: transparent; } QComboBox { padding: 8px; border: 1px solid #CED4DA; border-radius: 4px; min-width: 200px; background: white; } """ class DetectionThread(QThread): detection_finished = pyqtSignal(dict) error_occurred = pyqtSignal(str) def __init__(self, model, image_path, model_name): super().__init__() self.model = model self.image_path = image_path self.model_name = model_name def run(self): try: image = cv2.imread(self.image_path) if image is None: raise ValueError("无法读取图片文件") start_time = datetime.now() results = self.model.predict(image) elapsed = (datetime.now() - start_time).total_seconds() detection_data = { "model": self.model_name, "time": elapsed, "image_path": self.image_path, "annotated": results[0].plot(), "results": [] } for box in results[0].boxes: class_id = int(box.cls) detection_data["results"].append({ "class": self.model.names[class_id].lower(), # 统一转为小写 "confidence": float(box.conf) }) self.detection_finished.emit(detection_data) except Exception as e: self.error_occurred.emit(f"检测错误: {str(e)}\n{traceback.format_exc()}") class ResultTabWidget(QWidget): def __init__(self, parent=None): super().__init__(parent) self.layout = QVBoxLayout(self) # 图像显示区域 self.image_label = QLabel() self.image_label.setAlignment(Qt.AlignCenter) self.image_label.setMinimumSize(800, 600) self.image_label.setStyleSheet("background-color: white; border-radius: 8px;") # 摘要信息 self.summary_text = QTextEdit() self.summary_text.setReadOnly(True) self.summary_text.setStyleSheet("font-family: Consolas; font-size: 13px;") self.layout.addWidget(self.image_label, stretch=3) self.layout.addWidget(self.summary_text, stretch=1) class MainWindow(QMainWindow): def __init__(self): super().__init__() self.models = {} self.current_image_path = None self.results = {} self.danger_classes = ['knife', 'gun', 'explosive'] # 统一使用小写 self.alarm_player = QMediaPlayer() self.alarm_enabled = True # 报警声音默认开启 self.init_ui() self.init_status_bar() self.init_alarm_system() def init_alarm_system(self): """初始化报警音频系统""" self.alarm_player.setMedia(QMediaContent(QUrl.fromLocalFile("alarm.wav"))) self.alarm_player.setVolume(80) self.alarm_player.stateChanged.connect(self.handle_alarm_state) def init_ui(self): self.setWindowTitle("安检管制物品检测系统") self.setWindowIcon(QIcon("icon.png")) self.setGeometry(100, 100, 1600, 900) self.setStyleSheet(STYLE_SHEET) # 主布局 main_widget = QWidget() self.main_layout = QHBoxLayout(main_widget) self.main_layout.setContentsMargins(15, 15, 15, 15) self.main_layout.setSpacing(20) # 左侧控制面板 (30%) self.control_panel = self.create_control_panel() self.main_layout.addWidget(self.control_panel, stretch=3) # 右侧显示区域 (70%) self.display_area = self.create_display_area() self.main_layout.addWidget(self.display_area, stretch=7) self.setCentralWidget(main_widget) def create_control_panel(self): panel = QScrollArea() panel.setWidgetResizable(True) content = QWidget() layout = QVBoxLayout(content) layout.setContentsMargins(12, 12, 12, 12) layout.setSpacing(15) # 图片管理组 image_group = QGroupBox("文件管理") image_layout = QVBoxLayout() self.image_label = QLabel("当前图片:未选择") self.select_image_btn = QPushButton("📁 选择图片") self.select_image_btn.clicked.connect(self.select_image) image_layout.addWidget(self.image_label) image_layout.addWidget(self.select_image_btn) image_group.setLayout(image_layout) layout.addWidget(image_group) # 模型管理组 model_group = QGroupBox("模型管理") model_layout = QVBoxLayout() self.model_combo = QComboBox() self.load_model_btn = QPushButton("🔄 加载模型") self.load_model_btn.clicked.connect(self.load_model) self.detect_btn = QPushButton("🔍 开始检测") self.detect_btn.clicked.connect(self.start_detection) self.detect_btn.setEnabled(False) model_layout.addWidget(QLabel("已加载模型列表:")) model_layout.addWidget(self.model_combo) model_layout.addWidget(self.load_model_btn) model_layout.addWidget(self.detect_btn) model_group.setLayout(model_layout) layout.addWidget(model_group) # 系统信息组 info_group = QGroupBox("系统状态") info_layout = QVBoxLayout() # 报警状态指示 self.alert_layout = QHBoxLayout() self.led_label = QLabel() self.led_label.setFixedSize(20, 20) self.led_label.setStyleSheet("background-color: green; border-radius: 10px; border: 1px solid #666;") self.alert_status_label = QLabel("状态:正常") self.alert_status_label.setStyleSheet("color: green; font-weight: bold;") self.alert_layout.addWidget(self.led_label) self.alert_layout.addWidget(self.alert_status_label) self.alert_layout.addStretch() # 报警声音控制 self.alarm_control = QCheckBox("启用报警声音") self.alarm_control.setChecked(True) self.alarm_control.stateChanged.connect(self.toggle_alarm_sound) self.model_count_label = QLabel("▪ 加载模型数: 0") self.detect_count_label = QLabel("▪ 完成检测数: 0") info_layout.addLayout(self.alert_layout) info_layout.addWidget(self.alarm_control) info_layout.addWidget(self.model_count_label) info_layout.addWidget(self.detect_count_label) info_group.setLayout(info_layout) layout.addWidget(info_group) layout.addStretch() panel.setWidget(content) return panel def create_display_area(self): tab_widget = QTabWidget() tab_widget.setTabPosition(QTabWidget.North) tab_widget.setStyleSheet("QTabBar::tab { height: 32px; }") # 原始图像标签页 self.original_tab = ResultTabWidget() tab_widget.addTab(self.original_tab, "原始图像") # 检测结果标签页 self.result_tabs = QTabWidget() self.result_tabs.setTabsClosable(True) self.result_tabs.tabCloseRequested.connect(self.close_result_tab) tab_widget.addTab(self.result_tabs, "检测结果") # 对比分析标签页 self.compare_tab = QWidget() compare_layout = QVBoxLayout() self.compare_table = QTableWidget() self.compare_table.setColumnCount(5) self.compare_table.setHorizontalHeaderLabels(["模型", "检测数", "平均置信度", "最大置信度", "耗时(s)"]) self.compare_table.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch) compare_layout.addWidget(self.compare_table) self.compare_tab.setLayout(compare_layout) tab_widget.addTab(self.compare_tab, "对比分析") return tab_widget def init_status_bar(self): self.status_bar = QStatusBar() self.setStatusBar(self.status_bar) self.status_bar.showMessage("就绪") def update_status(self, message, success=True): color = "#27AE60" if success else "#E74C3C" self.status_bar.setStyleSheet(f"color: {color};") self.status_bar.showMessage(f"▸ {message}") def select_image(self): path, _ = QFileDialog.getOpenFileName( self, "选择图片", "", "图片文件 (*.jpg *.jpeg *.png);;所有文件 (*)" ) if path: self.current_image_path = path try: image = cv2.imread(path) if image is not None: rgb_image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB) self.display_image(rgb_image, self.original_tab.image_label) self.image_label.setText(f"当前图片: {os.path.basename(path)}") self.detect_btn.setEnabled(True) self.update_status("图片加载成功") self.clear_results() else: raise ValueError("无法读取图片文件") except Exception as e: self.update_status(f"图片加载失败: {str(e)}", False) self.current_image_path = None self.detect_btn.setEnabled(False) def load_model(self): try: path, _ = QFileDialog.getOpenFileName(self, "选择模型文件", "", "模型文件 (*.pt)") if path: model_name = os.path.basename(path) if model_name not in self.models: self.models[model_name] = YOLO(path) self.model_combo.addItem(model_name) self.model_count_label.setText(f"▪ 加载模型数: {len(self.models)}") self.update_status(f"模型 {model_name} 加载成功") except Exception as e: self.update_status(f"模型加载失败: {str(e)}", False) def start_detection(self): if not self.current_image_path: self.update_status("请先选择图片", False) return if self.model_combo.count() == 0: self.update_status("请先加载模型", False) return model_name = self.model_combo.currentText() self.detect_thread = DetectionThread(self.models[model_name], self.current_image_path, model_name) self.detect_thread.detection_finished.connect(self.handle_detection_result) self.detect_thread.error_occurred.connect(self.handle_detection_error) self.detect_thread.start() self.update_status(f"开始使用 {model_name} 进行检测...") def handle_detection_result(self, data): model_name = data["model"] self.results[model_name] = data # 创建新的结果标签页 tab = ResultTabWidget() self.display_image(data["annotated"], tab.image_label) tab.summary_text.setText(self.generate_single_summary(data)) # 添加到结果标签页 self.result_tabs.addTab(tab, f"{model_name}") self.result_tabs.setCurrentIndex(self.result_tabs.count() - 1) # 更新对比分析 self.update_compare_table() # 更新检测计数 self.detect_count_label.setText(f"▪ 完成检测数: {len(self.results)}") self.update_status(f"{model_name} 检测完成,耗时 {data['time']:.2f}s") # 检查危险状态 self.check_danger_status() def update_compare_table(self): self.compare_table.setRowCount(len(self.results)) for row, (model_name, data) in enumerate(self.results.items()): confidences = [d["confidence"] for d in data["results"]] avg_conf = sum(confidences) / len(confidences) if confidences else 0 max_conf = max(confidences) if confidences else 0 items = [ QTableWidgetItem(model_name), QTableWidgetItem(str(len(data["results"]))), QTableWidgetItem(f"{avg_conf:.2%}"), QTableWidgetItem(f"{max_conf:.2%}"), QTableWidgetItem(f"{data['time']:.2f}") ] for col, item in enumerate(items): self.compare_table.setItem(row, col, item) def generate_single_summary(self, data): summary = {} for item in data["results"]: class_name = item["class"] if class_name not in summary: summary[class_name] = {"count": 0, "confidences": []} summary[class_name]["count"] += 1 summary[class_name]["confidences"].append(item["confidence"]) text = "======== 检测报告 ========\n" text += f"▪ 模型名称: {data['model']}\n" text += f"▪ 检测时间: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}\n" text += f"▪ 总检测数: {len(data['results'])}\n" text += f"▪ 处理耗时: {data['time']:.2f}s\n\n" text += "======== 类别详情 ========\n" for idx, (class_name, info) in enumerate(summary.items(), 1): avg = sum(info["confidences"]) / len(info["confidences"]) text += (f"{idx}. {class_name}\n" f" → 数量: {info['count']}\n" f" → 平均置信度: {avg:.2%}\n" f" → 最大置信度: {max(info['confidences']):.2%}\n\n") return text def display_image(self, image_data, label_widget): try: if image_data is None: raise ValueError("空图像数据") h, w, ch = image_data.shape bytes_per_line = ch * w q_img = QImage(image_data.data, w, h, bytes_per_line, QImage.Format_RGB888) pixmap = QPixmap.fromImage(q_img).scaled( label_widget.width(), label_widget.height(), Qt.KeepAspectRatio, Qt.SmoothTransformation ) label_widget.setPixmap(pixmap) except Exception as e: self.update_status(f"图像显示失败: {str(e)}", False) def close_result_tab(self, index): if index > 0: # 保留第一个默认标签页 widget = self.result_tabs.widget(index) model_name = self.result_tabs.tabText(index) del self.results[model_name] widget.deleteLater() self.result_tabs.removeTab(index) self.update_compare_table() self.check_danger_status() def clear_results(self): while self.result_tabs.count() > 1: self.result_tabs.removeTab(1) self.results.clear() self.compare_table.setRowCount(0) self.check_danger_status() def handle_detection_error(self, error_msg): self.update_status(error_msg.split("\n")[0], False) QMessageBox.critical(self, "检测错误", error_msg) def check_danger_status(self): """检查所有检测结果中是否存在危险物品""" danger_detected = False for model_data in self.results.values(): for item in model_data["results"]: if item["class"].lower() in self.danger_classes: # 统一转为小写比较 danger_detected = True break if danger_detected: break self.update_alert_status(danger_detected) def update_alert_status(self, danger_detected): """更新报警状态显示""" if danger_detected: # 更新视觉状态 self.led_label.setStyleSheet("background-color: red; border-radius: 10px; border: 1px solid #666;") self.alert_status_label.setText("状态:报警") self.alert_status_label.setStyleSheet("color: red; font-weight: bold;") # 播放报警音 if self.alarm_enabled and self.alarm_player.state() != QMediaPlayer.PlayingState: self.alarm_player.play() else: # 更新视觉状态 self.led_label.setStyleSheet("background-color: green; border-radius: 10px; border: 1px solid #666;") self.alert_status_label.setText("状态:正常") self.alert_status_label.setStyleSheet("color: green; font-weight: bold;") # 停止报警音 if self.alarm_player.state() == QMediaPlayer.PlayingState: self.alarm_player.stop() def toggle_alarm_sound(self, state): """切换报警声音开关""" self.alarm_enabled = (state == Qt.Checked) if not self.alarm_enabled and self.alarm_player.state() == QMediaPlayer.PlayingState: self.alarm_player.stop() def handle_alarm_state(self, state): """处理音频播放状态变化""" if state == QMediaPlayer.PlayingState: self.alarm_player.setPosition(0) # 循环播放 if __name__ == '__main__': app = QApplication(sys.argv) window = MainWindow() window.show() sys.exit(app.exec_()) 这是我的ui界面代码,我觉得它看起来太简陋了,我想给它增加一个背景图片,不影响到其他功能模块的使用,最后请给出修改后的完整的代码
05-11
代码下载地址: https://pan.quark.cn/s/b4a8e0160cfc 齿轮与轴系零件在机械设备中扮演着至关重要的角色,它们负责实现动力传输、调整运动形态以及承受工作载荷等核心功能。 在机械工程的设计实践中,齿轮和轴系的设计是一项关键的技术任务,其内容涵盖了材料选用、构造规划、承载能力分析等多个技术层面。 下面将系统性地介绍《齿轮及轴系零件结构设计指导书》中的核心知识点。 一、齿轮设计1. 齿轮种类:依据齿廓轮廓的不同,齿轮可划分为直齿齿轮、斜齿轮以及人字齿轮等类别,各类齿轮均具有特定的性能特点与适用工况,能够满足多样化的工作环境与载荷需求。 2. 齿轮规格参数:模数大小、压力角数值、齿数数量、分度圆尺寸等是齿轮设计的基础数据,这些参数直接决定了齿轮的物理尺寸与运行性能。 3. 齿轮材质选用:齿轮材料的确定需综合评估其耐磨损性能、硬度水平以及韧性表现,常用的材料包括铸铁、钢材、铝合金等。 4. 齿轮强度验证:需进行齿面接触应力分析与齿根弯曲应力分析,以确保齿轮在实际运行过程中不会出现过度磨损或结构破坏。 5. 齿轮加工工艺:涉及切削加工、滚齿加工、剃齿加工、淬火处理等工艺流程,工艺方案的选择将直接影响齿轮的加工精度与使用寿命。 二、轴设计1. 轴的分类方式:依据轴在机械装置中的功能定位与受力特点,可将轴划分为心轴、转轴以及传动轴等类型。 2. 轴的材料选择:通常采用钢材作为轴的材料,例如碳素结构钢或合金结构钢,特殊需求时可选用不锈钢材料或轻质合金材料。 3. 轴的构造规划:需详细考虑轴的轴向长度、截面直径、键槽布置、轴承安装位置等要素,以满足轴的强度要求、刚度要求以及稳定性要求。 4. 轴的强度验证:需进行轴的扭转强度分析与弯曲强度分析,以防止轴在运行过程中发生塑性变形...
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值