from PyQt5.QtWidgets import QWidget, QVBoxLayout, QHBoxLayout, QLabel, QPushButton, QListWidget, QListWidgetItem, QFrame, QGridLayout, QSizePolicy from PyQt5.QtSvg import QSvgWidget from PyQt5.QtCore import Qt, QSize, QMargins from PyQt5.QtGui import QPixmap, QIcon, QColor import os from src.config import SECONDARY_COLOR, BUTTON_STYLE, UXUI_ASSETS, DongleIconMap def create_device_popup(parent, device_controller): """Create a popup window for device connection management""" try: # Device connection popup window popup = QWidget(parent) popup_width = int(parent.width() * 0.67) popup_height = int(parent.height() * 0.67) popup.setFixedSize(popup_width, popup_height) popup.setStyleSheet(f""" QWidget {{ background-color: {SECONDARY_COLOR}; border-radius: 20px; padding: 20px; }} QLabel {{ color: white; }} QListWidget {{ background-color: rgba(255, 255, 255, 0.1); border-radius: 10px; padding: 5px; color: white; }} QListWidget::item {{ border-radius: 5px; background-color: rgba(255, 255, 255, 0.1); margin-bottom: 5px; }} QListWidget::item:selected {{ background-color: rgba(52, 152, 219, 0.5); }} QFrame.device-info {{ background-color: rgba(255, 255, 255, 0.1); border-radius: 10px; padding: 10px; margin-top: 15px; }} """) popup_layout = QVBoxLayout(popup) popup_layout.setContentsMargins(20, 20, 20, 20) popup_layout.setSpacing(15) # Title row title_layout = QHBoxLayout() title_layout.setAlignment(Qt.AlignCenter) title_container = QWidget() container_layout = QHBoxLayout(title_container) container_layout.setSpacing(10) device_icon = QSvgWidget(os.path.join(UXUI_ASSETS, "Assets_svg/ic_window_device.svg")) device_icon.setFixedSize(35, 35) container_layout.addWidget(device_icon) popup_label = QLabel("Device Connection") popup_label.setStyleSheet("color: white; font-size: 32px; font-weight: bold;") container_layout.addWidget(popup_label) container_layout.setAlignment(Qt.AlignCenter) title_layout.addWidget(title_container) popup_layout.addLayout(title_layout) # Device list section - 設置為可捲動 list_section = QFrame(popup) list_section.setStyleSheet("border: none; background: transparent;") list_layout = QVBoxLayout(list_section) list_layout.setContentsMargins(0, 0, 0, 0) # Device list - 設置為可捲動的列表 device_list_widget_popup = QListWidget(popup) device_list_widget_popup.setMinimumHeight(250) # 增加整個列表的高度 # 啟用垂直捲動條 device_list_widget_popup.setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded) # 設置列表項高度和圖示大小 device_list_widget_popup.setIconSize(QSize(15, 15)) # 增大圖示 list_layout.addWidget(device_list_widget_popup) # Store reference to this list widget for later use parent.device_list_widget_popup = device_list_widget_popup # Comment out the device details section """ # Device details section (initially hidden) device_details = QFrame(popup) device_details.setObjectName("device-details") device_details.setProperty("class", "device-info") device_details.setVisible(False) # Initially hidden details_layout = QGridLayout(device_details) details_layout.setColumnStretch(1, 1) # 增加行間距 details_layout.setVerticalSpacing(2) # Device Type device_type_label_title = QLabel("Device Type:") device_type_label_title.setStyleSheet("font-size: 14px;") details_layout.addWidget(device_type_label_title, 0, 0) device_type_label = QLabel("-") device_type_label.setObjectName("device-type") device_type_label.setStyleSheet("font-size: 14px;") details_layout.addWidget(device_type_label, 0, 1) # Port ID port_id_label_title = QLabel("Port ID:") port_id_label_title.setStyleSheet("font-size: 14px;") details_layout.addWidget(port_id_label_title, 1, 0) port_id_label = QLabel("-") port_id_label.setObjectName("port-id") port_id_label.setStyleSheet("font-size: 14px;") details_layout.addWidget(port_id_label, 1, 1) # KN Number kn_number_label_title = QLabel("KN Number:") kn_number_label_title.setStyleSheet("font-size: 14px;") details_layout.addWidget(kn_number_label_title, 2, 0) kn_number_label = QLabel("-") kn_number_label.setObjectName("kn-number") kn_number_label.setStyleSheet("font-size: 14px;") details_layout.addWidget(kn_number_label, 2, 1) # Status status_label_title = QLabel("Status:") status_label_title.setStyleSheet("font-size: 14px;") details_layout.addWidget(status_label_title, 3, 0) status_label = QLabel("-") status_label.setObjectName("status") status_label.setStyleSheet("font-size: 14px;") details_layout.addWidget(status_label, 3, 1) # Store references to labels parent.device_detail_labels = { "device-type": device_type_label, "port-id": port_id_label, "kn-number": kn_number_label, "status": status_label, "frame": device_details } # Connect item selection to show details device_list_widget_popup.itemClicked.connect(lambda item: show_device_details(parent, item)) list_layout.addWidget(device_details) """ popup_layout.addWidget(list_section) # Button area button_layout = QHBoxLayout() button_layout.setAlignment(Qt.AlignCenter) refresh_button = QPushButton("Refresh") refresh_button.clicked.connect(lambda: refresh_devices(parent, device_controller)) refresh_button.setFixedSize(150, 45) refresh_button.setStyleSheet(BUTTON_STYLE) button_layout.addWidget(refresh_button) done_button = QPushButton("Done") done_button.setStyleSheet(BUTTON_STYLE) done_button.setFixedSize(150, 45) done_button.clicked.connect(parent.hide_device_popup) button_layout.addWidget(done_button) button_layout.setSpacing(20) # 減少底部間距,讓按鈕更靠近底部 popup_layout.addSpacing(5) popup_layout.addLayout(button_layout) return popup except Exception as e: print(f"Error in create_device_popup: {e}") return QWidget(parent) # Also need to comment out the show_device_details function since it's no longer used # def show_device_details(parent, item): # """Show details for the selected device""" # try: # # Get the device data from the item # device_data = item.data(Qt.UserRole) # print("device_data", device_data) # if not device_data: # return # # Update the detail labels # labels = parent.device_detail_labels # # Set values # labels["device-type"].setText(device_data.get("dongle", "-")) # labels["port-id"].setText(str(device_data.get("usb_port_id", "-"))) # labels["kn-number"].setText(str(device_data.get("kn_number", "-"))) # labels["status"].setText("Connected" if device_data.get("is_connectable", True) else "Not Available") # # Show the details frame # labels["frame"].setVisible(True) # except Exception as e: # print(f"Error showing device details: {e}") def refresh_devices(parent, device_controller): """Refresh the device list and update the UI""" try: # Call the refresh method from device controller device_controller.refresh_devices() # Clear the list parent.device_list_widget_popup.clear() # Comment out the details frame visibility setting """ # Hide details frame if hasattr(parent, "device_detail_labels") and "frame" in parent.device_detail_labels: parent.device_detail_labels["frame"].setVisible(False) """ # Track unique device models to avoid duplicates seen_models = set() # Add devices to the list for device in device_controller.connected_devices: try: item = QListWidgetItem() # Store the device data item.setData(Qt.UserRole, device) # 使用自定義 widget 來顯示設備信息 widget = QWidget() widget.setFixedHeight(60) # 固定高度 # 使用水平佈局 main_layout = QHBoxLayout(widget) # 減少內邊距保持足夠空間 main_layout.setContentsMargins(8, 4, 8, 4) main_layout.setSpacing(5) # 左側圖示容器(帶有背景色) icon_container = QFrame() icon_container.setFixedSize(30, 30) icon_container.setStyleSheet("background-color: #182D4B; border-radius: 5px;") icon_layout = QVBoxLayout(icon_container) icon_layout.setContentsMargins(0, 0, 0, 0) icon_layout.setAlignment(Qt.AlignCenter) # 獲取設備圖示 product_id = hex(device.get("product_id", 0)).strip().lower() icon_path = os.path.join(UXUI_ASSETS, "Assets_png", DongleIconMap.get(product_id, "unknown_dongle.png")) if os.path.exists(icon_path): icon_label = QLabel() pixmap = QPixmap(icon_path) # 確保圖標大小適中 scaled_pixmap = pixmap.scaled(30, 30, Qt.KeepAspectRatio, Qt.SmoothTransformation) icon_label.setPixmap(scaled_pixmap) icon_layout.addWidget(icon_label) main_layout.addWidget(icon_container) # 右側信息區域 info_container = QWidget() info_layout = QVBoxLayout(info_container) info_layout.setContentsMargins(0, 0, 0, 0) # info_layout.setSpacing(2) # 設備名稱和型號 dongle_name = device.get("dongle", "Unknown Device") kn_number = device.get("kn_number", "Unknown") status = "Connected" if device.get("is_connectable", True) else "Not Available" # 只顯示型號名稱,避免重複 device_model_key = f"{dongle_name}_{product_id}" if device_model_key in seen_models: # 只顯示狀態 device_label_text = "" else: seen_models.add(device_model_key) device_label_text = f"{dongle_name}" device_label = QLabel(device_label_text) device_label.setStyleSheet("color: white; font-weight: bold; font-size: 16px;") info_layout.addWidget(device_label) # KN 號碼 kn_label = QLabel(f"KN: {kn_number}") kn_label.setStyleSheet("color: white; font-size: 14px;") info_layout.addWidget(kn_label) # 將信息容器添加到主佈局 main_layout.addWidget(info_container, 1) # 設置伸展因子為1 # 狀態標籤(右側) status_label = QLabel(status) status_label.setStyleSheet("color: white; font-size: 12px;") main_layout.addWidget(status_label, 0, Qt.AlignRight | Qt.AlignVCenter) # 右對齊 # 設置自定義 widget 為列表項的 widget parent.device_list_widget_popup.addItem(item) parent.device_list_widget_popup.setItemWidget(item, widget) # 設置項目大小 item.setSizeHint(widget.sizeHint()) except Exception as e: print(f"Error adding device to list: {e}") except Exception as e: print(f"Error refreshing devices: {e}")