721 lines
26 KiB
Python
721 lines
26 KiB
Python
import kp
|
|
import cv2, os, shutil, sys
|
|
from enum import Enum
|
|
from PyQt5.QtWidgets import (QApplication, QWidget, QVBoxLayout, QLabel, QPushButton,
|
|
QComboBox, QFileDialog, QMessageBox, QHBoxLayout, QDialog, QListWidget,
|
|
QScrollArea, QFrame, QListWidgetItem, QTextEdit)
|
|
from PyQt5.QtSvg import QSvgWidget
|
|
from PyQt5.QtMultimedia import QCamera, QCameraImageCapture, QCameraInfo, QMediaRecorder, QAudioRecorder
|
|
from PyQt5.QtMultimediaWidgets import QVideoWidget
|
|
from PyQt5.QtGui import QPixmap, QMovie
|
|
from PyQt5.QtCore import Qt, QTimer, QUrl
|
|
|
|
# Global Constants
|
|
UXUI_ASSETS = "../../uxui/"
|
|
WINDOW_SIZE = (1200, 900)
|
|
BACKGROUND_COLOR = "#143058"
|
|
SECONDARY_COLOR = "#1260E6"
|
|
DEVICE_BOX_STYLE = f"background-color: {BACKGROUND_COLOR}; padding: 20px; border-radius: 20px; padding: 10px 20px;"
|
|
BUTTON_STYLE = """
|
|
QPushButton {
|
|
background: transparent;
|
|
color: white;
|
|
border: 1px solid white;
|
|
border-radius: 20px;
|
|
padding: 10px 20px;
|
|
}
|
|
QPushButton:hover {
|
|
background-color: rgba(255, 255, 255, 50);
|
|
}
|
|
QPushButton:pressed {
|
|
background-color: rgba(255, 255, 255, 100);
|
|
}
|
|
"""
|
|
SQUARE_BUTTON_STYLE = "background: transparent; color: white; border: 1px transparent; border-radius: 10px; "
|
|
POPUP_SIZE_RATIO = 0.67
|
|
NO_DEVICE_GIF = UXUI_ASSETS + "no_device_temp.gif"
|
|
|
|
|
|
class MainWindow(QWidget):
|
|
def __init__(self):
|
|
super().__init__()
|
|
self.init_ui()
|
|
self.model_buttons = [
|
|
('Face Detection', self.run_face_detection),
|
|
('Gender/Age Detection', self.run_gender_age_detection),
|
|
('Object Detection', self.run_object_detection),
|
|
('Mask Detection', self.run_mask_detection),
|
|
('Image Project', self.start_image_project),
|
|
('Upload Model', self.upload_model)
|
|
]
|
|
|
|
self.connected_devices = [
|
|
]
|
|
|
|
self.input_directory = ""
|
|
self.to_keep_directory = ""
|
|
self.to_delete_directory = ""
|
|
self.image_directory = ""
|
|
self.label_directory = ""
|
|
|
|
self.video_widget = QVideoWidget(self)
|
|
self.camera = QCamera(QCameraInfo.defaultCamera())
|
|
self.image_capture = QCameraImageCapture(self.camera)
|
|
self.media_recorder = QMediaRecorder(self.camera)
|
|
self.audio_recorder = QAudioRecorder(self)
|
|
self.camera.setViewfinder(self.video_widget)
|
|
|
|
self.right_layout = QVBoxLayout()
|
|
self.left_layout = QVBoxLayout()
|
|
|
|
|
|
# TODO: find the correct mapping of the values
|
|
class K_(Enum):
|
|
KL520 = 256
|
|
KL720 = 720
|
|
KL720_L = 512 #legacy
|
|
KL530 = 530
|
|
KL832 = 832
|
|
KL730 = 732
|
|
KL630 = 630
|
|
KL540 = 540
|
|
|
|
|
|
def init_ui(self):
|
|
self.setGeometry(100, 100, *WINDOW_SIZE)
|
|
self.setWindowTitle('Innovedus AI Playground')
|
|
self.setStyleSheet(f"background-color: {BACKGROUND_COLOR};")
|
|
self.layout = QVBoxLayout(self)
|
|
|
|
self.show_welcome_label()
|
|
QTimer.singleShot(5000, self.show_device_popup_and_main_page)
|
|
|
|
|
|
def show_welcome_label(self):
|
|
welcome_label = QLabel(self)
|
|
welcome_pixmap = QPixmap(UXUI_ASSETS + "kneron_logo.png")
|
|
welcome_label.setPixmap(welcome_pixmap)
|
|
welcome_label.setAlignment(Qt.AlignCenter)
|
|
self.layout.addWidget(welcome_label)
|
|
|
|
|
|
def close_connection_page(self):
|
|
print("closing device connection page")
|
|
device_descriptors = kp.core.scan_devices()
|
|
if device_descriptors.device_descriptor_number > 0:
|
|
for device in device_descriptors.device_descriptor_list:
|
|
self.parse_and_store_devices(device_descriptors.device_descriptor_list)
|
|
kp.core.connect_devices(usb_port_ids=[device.usb_port_id])
|
|
self.load_firmware()
|
|
self.popup_window.close()
|
|
|
|
|
|
def load_firmware(self):
|
|
print("loading firmware")
|
|
for device in self.connected_devices:
|
|
device_group = kp.core.connect_devices(usb_port_ids=[device.get["usb_port_id"]])
|
|
kp.core.set_timeout(device_group=device_group, milliseconds=5000)
|
|
SCPU_FW_PATH = f'../../external/res/firmware/{device.get["product_id"]}/fw_scpu.bin'
|
|
NCPU_FW_PATH = f'../../external/res/firmware/{device.get["product_id"]}/fw_ncpu.bin'
|
|
kp.core.load_firmware_from_file(device_group=device_group,
|
|
scpu_fw_path=SCPU_FW_PATH,
|
|
ncpu_fw_path=NCPU_FW_PATH)
|
|
|
|
|
|
def show_error_popup(self, message):
|
|
error_dialog = QMessageBox.critical(self, "Error", message)
|
|
|
|
|
|
def parse_and_store_devices(self, devices):
|
|
for device in devices:
|
|
new_device = {
|
|
'usb_port_id': device.usb_port_id,
|
|
'product_id': device.product_id,
|
|
'kn_number': device.kn_number
|
|
}
|
|
print(device)
|
|
existing_device_index = next((index for (index, d) in enumerate(self.connected_devices)
|
|
if d['usb_port_id'] == new_device['usb_port_id']), None)
|
|
|
|
if existing_device_index is not None:
|
|
self.connected_devices[existing_device_index] = new_device
|
|
else:
|
|
self.connected_devices.append(new_device)
|
|
|
|
|
|
def check_available_device(self):
|
|
print("checking available devices")
|
|
device_descriptors = kp.core.scan_devices()
|
|
self.clear_device_layout(self.device_layout)
|
|
|
|
if device_descriptors.device_descriptor_number > 0:
|
|
if device_descriptors.device_descriptor_number > 0:
|
|
self.parse_and_store_devices(device_descriptors.device_descriptor_list)
|
|
self.display_devices(device_descriptors.device_descriptor_list)
|
|
else:
|
|
self.show_no_device_gif()
|
|
|
|
|
|
def get_dongle_type(self, product_id):
|
|
for dongle_type in self.K_:
|
|
if dongle_type.value == product_id:
|
|
return dongle_type
|
|
return None
|
|
|
|
|
|
def display_devices(self, device_descriptor_list):
|
|
hbox_layout = QHBoxLayout()
|
|
hbox_layout.setAlignment(Qt.AlignCenter)
|
|
|
|
for device in device_descriptor_list:
|
|
device_layout = QVBoxLayout()
|
|
box_layout = QVBoxLayout()
|
|
|
|
icon = QLabel()
|
|
pixmap = QPixmap(UXUI_ASSETS + "kneron_logo.png")
|
|
icon.setPixmap(pixmap.scaled(50, 50, Qt.KeepAspectRatio, Qt.SmoothTransformation))
|
|
print(device.product_id)
|
|
usb_type_label = QLabel(f"Device: {self.get_dongle_type(device.product_id)}")
|
|
usb_type_label.setAlignment(Qt.AlignCenter)
|
|
usb_type_label.setStyleSheet("color: white")
|
|
|
|
box_layout.addWidget(icon, alignment=Qt.AlignCenter)
|
|
box_layout.addWidget(usb_type_label)
|
|
|
|
box_widget = QWidget()
|
|
box_widget.setLayout(box_layout)
|
|
|
|
box_size = 200
|
|
box_widget.setFixedSize(box_size, box_size)
|
|
box_widget.setStyleSheet(DEVICE_BOX_STYLE)
|
|
|
|
usb_port_label = QLabel(f"KN number:\n{device.kn_number}")
|
|
usb_port_label.setAlignment(Qt.AlignLeft)
|
|
usb_port_label.setStyleSheet("color: white;")
|
|
|
|
label_icon_layout = QHBoxLayout()
|
|
|
|
small_icon = QSvgWidget(UXUI_ASSETS + "./Assets_svg/btn_dialog_device_disconnect_normal.svg")
|
|
small_icon.setFixedSize(30, 30)
|
|
|
|
label_icon_layout.addWidget(usb_port_label)
|
|
label_icon_layout.addWidget(small_icon, alignment=Qt.AlignRight)
|
|
|
|
device_layout.addWidget(box_widget)
|
|
device_layout.addLayout(label_icon_layout)
|
|
|
|
device_widget = QWidget()
|
|
device_widget.setLayout(device_layout)
|
|
|
|
hbox_layout.addWidget(device_widget)
|
|
|
|
self.device_layout.addLayout(hbox_layout)
|
|
|
|
|
|
|
|
def show_no_device_gif(self):
|
|
no_device_label = QLabel(self)
|
|
no_device_movie = QMovie(NO_DEVICE_GIF)
|
|
no_device_label.setMovie(no_device_movie)
|
|
no_device_movie.start()
|
|
no_device_label.setAlignment(Qt.AlignCenter)
|
|
self.device_layout.addWidget(no_device_label)
|
|
|
|
|
|
def show_device_connection_popup(self):
|
|
self.popup_window = QDialog(self)
|
|
self.popup_window.setWindowTitle("Device Connection")
|
|
self.popup_window.setFocusPolicy(Qt.StrongFocus)
|
|
|
|
popup_width = int(self.width() * POPUP_SIZE_RATIO)
|
|
popup_height = int(self.height() * POPUP_SIZE_RATIO)
|
|
self.popup_window.setGeometry(100, 100, popup_width, popup_height)
|
|
self.popup_window.setStyleSheet(f"background-color: {SECONDARY_COLOR};")
|
|
|
|
popup_layout = QVBoxLayout()
|
|
|
|
self.device_layout = QVBoxLayout()
|
|
|
|
popup_title = QHBoxLayout()
|
|
small_icon = QSvgWidget(UXUI_ASSETS + "./Assets_svg/ic_window_device.svg")
|
|
small_icon.setFixedSize(30, 30)
|
|
popup_title.addWidget(small_icon)
|
|
device_popup_label = QLabel("Device Connection", self.popup_window)
|
|
device_popup_label.setAlignment(Qt.AlignCenter)
|
|
popup_title.addWidget(device_popup_label)
|
|
popup_layout.addLayout(self.device_layout)
|
|
|
|
button_layout = QHBoxLayout()
|
|
|
|
refresh_button = QPushButton('Refresh')
|
|
refresh_button.clicked.connect(self.check_available_device)
|
|
refresh_button.setStyleSheet(BUTTON_STYLE)
|
|
button_layout.addWidget(refresh_button)
|
|
|
|
done_button = QPushButton('Done')
|
|
done_button.setStyleSheet(BUTTON_STYLE)
|
|
#done_button.clicked.connect(self.close_connection_page)
|
|
done_button.clicked.connect(lambda: self.close_connection_page())
|
|
|
|
button_layout.addWidget(done_button)
|
|
|
|
popup_layout.addLayout(button_layout)
|
|
self.popup_window.setLayout(popup_layout)
|
|
|
|
self.popup_window.setModal(True)
|
|
self.setEnabled(False)
|
|
self.popup_window.finished.connect(lambda: self.setEnabled(True))
|
|
|
|
self.popup_window.show()
|
|
|
|
self.check_available_device()
|
|
|
|
|
|
def show_device_popup_and_main_page(self):
|
|
self.show_device_connection_popup()
|
|
self.popup_window.finished.connect(self.main_page)
|
|
|
|
|
|
|
|
def clear_device_layout(self, layout):
|
|
for i in reversed(range(layout.count())):
|
|
layout.itemAt(i).widget().deleteLater()
|
|
|
|
|
|
def clear_layout(self):
|
|
for i in reversed(range(self.device_layout.count())):
|
|
self.device_layout.itemAt(i).widget().deleteLater()
|
|
|
|
|
|
def create_frame(self, title, icon_path):
|
|
frame = QFrame(self)
|
|
frame.setStyleSheet(f"border: none; background: {SECONDARY_COLOR}; border-radius: 20px;")
|
|
layout = QVBoxLayout(frame)
|
|
|
|
title_layout = QHBoxLayout()
|
|
title_icon = QSvgWidget(icon_path)
|
|
title_icon.setFixedSize(40, 40)
|
|
title_layout.addWidget(title_icon)
|
|
title_label = QLabel(title)
|
|
title_label.setStyleSheet("color: white;")
|
|
title_layout.addWidget(title_label)
|
|
|
|
layout.addLayout(title_layout)
|
|
return frame
|
|
|
|
|
|
def add_model_buttons(self, layout):
|
|
for model_name, run_function in self.model_buttons:
|
|
button = QPushButton(model_name)
|
|
button.clicked.connect(run_function)
|
|
|
|
button.setStyleSheet("""
|
|
QPushButton {
|
|
color: white;
|
|
border: 2px solid white;
|
|
border-radius: 10px;
|
|
padding: 10px;
|
|
background-color: transparent;
|
|
}
|
|
QPushButton:hover {
|
|
background-color: rgba(255, 255, 255, 50);
|
|
}
|
|
QPushButton:pressed {
|
|
background-color: rgba(255, 255, 255, 100);
|
|
}
|
|
""")
|
|
layout.addWidget(button)
|
|
|
|
|
|
def start_camera(self):
|
|
print("opening camera")
|
|
self.right_layout.replaceWidget(self.canvas_label, self.video_widget)
|
|
self.canvas_label.hide()
|
|
self.camera.start()
|
|
|
|
|
|
def stop_camera(self):
|
|
self.camera.stop()
|
|
|
|
self.right_layout.replaceWidget(self.video_widget, self.canvas_label)
|
|
self.video_widget.hide()
|
|
self.canvas_label.show()
|
|
|
|
|
|
# TODO: implement these functions and add button state/style change
|
|
def record_video(self):
|
|
output_file = "output_video.mp4"
|
|
self.media_recorder.setOutputLocation(QUrl.fromLocalFile(os.path.abspath(output_file)))
|
|
self.media_recorder.record()
|
|
|
|
def stop_recording(self):
|
|
self.media_recorder.stop()
|
|
|
|
|
|
def record_audio(self):
|
|
audio_output_file = "output_audio.wav"
|
|
self.audio_recorder.setOutputLocation(QUrl.fromLocalFile(os.path.abspath(audio_output_file)))
|
|
self.audio_recorder.record()
|
|
|
|
|
|
def stop_audio(self):
|
|
self.audio_recorder.stop()
|
|
|
|
|
|
def take_screenshot(self):
|
|
self.image_capture.capture()
|
|
self.image_capture.imageCaptured.connect(self.process_capture)
|
|
|
|
|
|
def process_capture(self, requestId, image):
|
|
file_name = f"screenshot_{requestId}.png"
|
|
image.save(file_name)
|
|
print(f"Screenshot saved as {file_name}")
|
|
|
|
|
|
def run_face_detection(self):
|
|
self.start_camera()
|
|
print("Running Face Detection")
|
|
|
|
|
|
def run_gender_age_detection(self):
|
|
self.start_camera()
|
|
print("Running Gender/Age Detection")
|
|
|
|
|
|
def run_object_detection(self):
|
|
self.start_camera()
|
|
print("Running Object Detection")
|
|
|
|
|
|
def run_mask_detection(self):
|
|
self.start_camera()
|
|
print("Running Mask Detection")
|
|
|
|
|
|
def choose_folder(self):
|
|
self.input_directory = QFileDialog.getExistingDirectory(self, "Select Input Directory")
|
|
self.to_keep_directory = QFileDialog.getExistingDirectory(self, "Select 'To Keep' Directory")
|
|
self.to_delete_directory = QFileDialog.getExistingDirectory(self, "Select 'To Delete' Directory")
|
|
|
|
if self.input_directory and self.to_keep_directory and self.to_delete_directory:
|
|
print(f"Selected directories:\nInput: {self.input_directory}\nTo Keep: {self.to_keep_directory}\nTo Delete: {self.to_delete_directory}")
|
|
|
|
|
|
def create_folder_button(self):
|
|
folder_button_widget = QWidget()
|
|
folder_button_layout = QVBoxLayout()
|
|
|
|
text_label = QLabel("Image")
|
|
text_label.setAlignment(Qt.AlignCenter)
|
|
text_label.setStyleSheet("color: white;")
|
|
folder_button_layout.addWidget(text_label)
|
|
|
|
folder_button_widget.setLayout(folder_button_layout)
|
|
folder_button_widget.setStyleSheet(f"""
|
|
QWidget {{
|
|
background-color: {SECONDARY_COLOR};
|
|
border: 2px solid white;
|
|
border-radius: 10px;
|
|
padding: 10px;
|
|
min-width: 100px;
|
|
min-height: 100px;
|
|
}}
|
|
""")
|
|
|
|
return folder_button_widget
|
|
|
|
|
|
def process_image_project(self):
|
|
print("processing_image_project")
|
|
|
|
|
|
def start_image_project(self):
|
|
print("running image project")
|
|
|
|
self.popup_window = QDialog(self)
|
|
self.popup_window.setWindowTitle("Choose Folder")
|
|
|
|
popup_width = int(self.width() * POPUP_SIZE_RATIO)
|
|
popup_height = int(self.height() * POPUP_SIZE_RATIO)
|
|
self.popup_window.setGeometry(100, 100, popup_width, popup_height)
|
|
self.popup_window.setStyleSheet(f"background-color: {SECONDARY_COLOR};")
|
|
|
|
popup_layout = QVBoxLayout()
|
|
|
|
self.device_layout = QVBoxLayout()
|
|
cust_label = QLabel("Customization", self.popup_window)
|
|
cust_label.setAlignment(Qt.AlignCenter)
|
|
cust_label.setStyleSheet("color: white")
|
|
popup_layout.addWidget(cust_label)
|
|
popup_layout.addLayout(self.device_layout)
|
|
|
|
folder_icon = QSvgWidget(UXUI_ASSETS + "./Assets_svg/ic_customization_upload_folder.svg")
|
|
folder_icon.setFixedSize(100, 100)
|
|
|
|
upload_icon = QSvgWidget(UXUI_ASSETS + "./Assets_svg/bt_function_upload_normal.svg")
|
|
upload_icon.setFixedSize(40, 40)
|
|
|
|
folder_button_widget = QWidget()
|
|
folder_button_layout = QVBoxLayout()
|
|
|
|
text_label = QLabel("Image")
|
|
text_label.setAlignment(Qt.AlignCenter)
|
|
text_label.setStyleSheet("color: white; border: none")
|
|
|
|
folder_button_layout.addWidget(text_label)
|
|
folder_button_layout.addWidget(folder_icon)
|
|
|
|
description_label = QLabel("Upload or drag files")
|
|
description_label.setAlignment(Qt.AlignCenter)
|
|
description_label.setStyleSheet("color: white; border: none")
|
|
folder_button_layout.addWidget(description_label)
|
|
folder_button_layout.addWidget(upload_icon)
|
|
folder_button_layout.setAlignment(Qt.AlignCenter)
|
|
|
|
folder_button_widget.setLayout(folder_button_layout)
|
|
|
|
folder_frame = QFrame()
|
|
folder_frame.setStyleSheet(f"""
|
|
QFrame {{
|
|
border: 2px solid white;
|
|
border-radius: 10px;
|
|
padding: 10px;
|
|
background-color: {SECONDARY_COLOR};
|
|
}}
|
|
""")
|
|
folder_frame.setLayout(QVBoxLayout())
|
|
folder_frame.layout().addWidget(folder_button_widget)
|
|
|
|
folder_icon2 = QSvgWidget(UXUI_ASSETS + "./Assets_svg/ic_customization_upload_folder.svg")
|
|
folder_icon2.setFixedSize(100, 100)
|
|
upload_icon2 = QSvgWidget(UXUI_ASSETS + "./Assets_svg/bt_function_upload_normal.svg")
|
|
upload_icon2.setFixedSize(40, 40)
|
|
folder_button_widget2 = QWidget()
|
|
folder_button_layout2 = QVBoxLayout()
|
|
|
|
text_label2 = QLabel("Label")
|
|
text_label2.setAlignment(Qt.AlignCenter)
|
|
text_label2.setStyleSheet("color: white; border: none")
|
|
|
|
folder_button_layout2.addWidget(text_label2)
|
|
folder_button_layout2.addWidget(folder_icon2)
|
|
folder_button_layout2.setAlignment(Qt.AlignCenter)
|
|
|
|
description_label2 = QLabel("Upload or drag files")
|
|
description_label2.setAlignment(Qt.AlignCenter)
|
|
description_label2.setStyleSheet("color: white; border: none")
|
|
folder_button_layout2.addWidget(description_label2)
|
|
folder_button_layout2.addWidget(upload_icon2)
|
|
|
|
folder_button_widget2.setLayout(folder_button_layout2)
|
|
|
|
folder_frame2 = QFrame()
|
|
folder_frame2.setStyleSheet(f"""
|
|
QFrame {{
|
|
border: 2px solid white;
|
|
border-radius: 10px;
|
|
padding: 10px;
|
|
background-color: {SECONDARY_COLOR};
|
|
}}
|
|
""")
|
|
folder_frame2.setLayout(QVBoxLayout())
|
|
folder_frame2.layout().addWidget(folder_button_widget2)
|
|
|
|
folder_buttons_layout = QHBoxLayout()
|
|
folder_buttons_layout.addWidget(folder_frame)
|
|
folder_buttons_layout.addWidget(folder_frame2)
|
|
|
|
popup_layout.addLayout(folder_buttons_layout)
|
|
|
|
button_layout = QHBoxLayout()
|
|
self.cancel_button = QPushButton('Cancel', self.popup_window)
|
|
self.cancel_button.clicked.connect(self.popup_window.close)
|
|
self.cancel_button.setStyleSheet(BUTTON_STYLE)
|
|
button_layout.addWidget(self.cancel_button)
|
|
|
|
self.done_button = QPushButton('Done', self.popup_window)
|
|
self.done_button.setStyleSheet(BUTTON_STYLE)
|
|
self.done_button.clicked.connect(self.process_image_project)
|
|
button_layout.addWidget(self.done_button)
|
|
|
|
popup_layout.addLayout(button_layout)
|
|
|
|
self.popup_window.setLayout(popup_layout)
|
|
|
|
self.popup_window.setModal(True)
|
|
self.setEnabled(False)
|
|
self.popup_window.finished.connect(lambda: self.setEnabled(True))
|
|
|
|
self.popup_window.show()
|
|
|
|
|
|
def upload_model(self):
|
|
print("Uploading Model")
|
|
|
|
|
|
def main_page(self):
|
|
self.clear_device_layout(self.layout)
|
|
self.setWindowTitle('Innovedus AI Playground')
|
|
self.setGeometry(100, 100, *WINDOW_SIZE)
|
|
|
|
main_layout = QHBoxLayout()
|
|
top_nav = QHBoxLayout()
|
|
|
|
welcome_label = QLabel(self)
|
|
welcome_pixmap = QPixmap(UXUI_ASSETS + "kneron_logo.png").scaled(150, 150, Qt.KeepAspectRatio)
|
|
welcome_label.setPixmap(welcome_pixmap)
|
|
top_nav.addWidget(welcome_label, alignment=Qt.AlignLeft)
|
|
top_nav.addStretch()
|
|
|
|
settings_button = QPushButton("Settings", self)
|
|
settings_button.setStyleSheet(BUTTON_STYLE)
|
|
top_nav.addWidget(settings_button, alignment=Qt.AlignRight)
|
|
self.layout.addLayout(top_nav)
|
|
|
|
|
|
left_widget = QWidget()
|
|
left_widget.setLayout(self.left_layout)
|
|
left_widget.setFixedWidth(self.geometry().width() // 3)
|
|
|
|
right_widget = QWidget()
|
|
right_widget.setLayout(self.right_layout)
|
|
right_widget.setFixedWidth(self.geometry().width() * 2 // 3)
|
|
|
|
main_layout.addWidget(left_widget)
|
|
main_layout.addWidget(right_widget)
|
|
self.layout.addLayout(main_layout)
|
|
self.setLayout(self.layout)
|
|
|
|
self.create_device_layout()
|
|
self.create_right_layout()
|
|
|
|
|
|
def show_device_details(self):
|
|
print("show_device_details")
|
|
|
|
|
|
def create_device_layout(self):
|
|
devices_frame = self.create_frame("Device", UXUI_ASSETS + "./Assets_svg/ic_window_device.svg")
|
|
devices_frame_layout = QVBoxLayout()
|
|
self.device_list = QListWidget(self)
|
|
|
|
print(self.connected_devices)
|
|
|
|
for device in self.connected_devices:
|
|
usb_port_id = device.get("usb_port_id")
|
|
product_id = device.get("product_id")
|
|
kn_number = device.get("kn_number")
|
|
|
|
h_layout = QHBoxLayout()
|
|
icon = QSvgWidget(UXUI_ASSETS + "./Assets_svg/ic_window_device.svg")
|
|
icon.setFixedSize(40, 40)
|
|
h_layout.addWidget(icon)
|
|
|
|
text_layout = QVBoxLayout()
|
|
line1_label = QLabel(f"Dongle: {product_id}")
|
|
line1_label.setStyleSheet("font-weight: bold; color: white;")
|
|
text_layout.addWidget(line1_label)
|
|
|
|
line2_label = QLabel(f"KN number: {kn_number}")
|
|
line2_label.setStyleSheet("color: white;")
|
|
text_layout.addWidget(line2_label)
|
|
|
|
h_layout.addLayout(text_layout)
|
|
|
|
item_widget = QWidget()
|
|
item_widget.setLayout(h_layout)
|
|
list_item = QListWidgetItem()
|
|
list_item.setSizeHint(item_widget.sizeHint())
|
|
self.device_list.addItem(list_item)
|
|
self.device_list.setItemWidget(list_item, item_widget)
|
|
|
|
devices_frame_layout.addWidget(self.device_list)
|
|
|
|
detail_button = QPushButton("Details", self)
|
|
detail_button.clicked.connect(self.show_device_details)
|
|
devices_frame_layout.addWidget(detail_button)
|
|
|
|
devices_frame.setLayout(devices_frame_layout)
|
|
self.left_layout.addWidget(devices_frame)
|
|
|
|
self.models_frame = self.create_frame("AI Toolbox", UXUI_ASSETS + "./Assets_svg/ic_window_toolbox.svg")
|
|
models_layout = QVBoxLayout(self.models_frame)
|
|
self.models_frame.setLayout(models_layout)
|
|
|
|
self.add_model_buttons(self.models_frame.layout())
|
|
self.left_layout.addWidget(self.models_frame)
|
|
|
|
|
|
def create_right_layout(self):
|
|
self.canvas_label = QLabel("Canvas Area (Camera Screen)", self)
|
|
self.canvas_label.setAlignment(Qt.AlignCenter)
|
|
self.canvas_label.setStyleSheet("border: 1px transparent; background: gray; border-radius: 20px; ")
|
|
self.right_layout.addWidget(self.canvas_label)
|
|
|
|
button_overlay_layout = QVBoxLayout()
|
|
button_overlay_layout.setContentsMargins(0, 0, 0, 0)
|
|
|
|
self.create_square_buttons(button_overlay_layout)
|
|
|
|
button_overlay_widget = QWidget(self)
|
|
button_overlay_widget.setLayout(button_overlay_layout)
|
|
button_overlay_widget.setStyleSheet(f"background: {SECONDARY_COLOR}; border-radius: 20px; padding: 10px;")
|
|
|
|
button_overlay_widget.setFixedHeight(150)
|
|
self.right_layout.addWidget(button_overlay_widget, alignment=Qt.AlignBottom | Qt.AlignRight)
|
|
|
|
|
|
def create_square_buttons(self, layout):
|
|
square_buttons_info = [
|
|
('video', UXUI_ASSETS + "./Assets_svg/ic_recording_camera.svg"),
|
|
('voice', UXUI_ASSETS + "./Assets_svg/ic_recording_voice.svg"),
|
|
('screenshot', UXUI_ASSETS + "./Assets_svg/bt_function_screencapture_normal.svg"),
|
|
]
|
|
|
|
for button_name, icon_path in square_buttons_info:
|
|
button = QPushButton(self)
|
|
button.setFixedSize(50, 50)
|
|
button.setStyleSheet(SQUARE_BUTTON_STYLE)
|
|
button_layout = QHBoxLayout(button)
|
|
button_layout.setContentsMargins(0, 0, 0, 0)
|
|
icon = QSvgWidget(icon_path)
|
|
icon.setFixedSize(40, 40)
|
|
button_layout.addWidget(icon)
|
|
|
|
layout.addWidget(button)
|
|
|
|
|
|
def upload_model(self):
|
|
model_file, _ = QFileDialog.getOpenFileName(self, "Upload Model", "", "NEF Files (*.nef)")
|
|
if model_file:
|
|
if model_file.endswith('.nef'):
|
|
model_name = os.path.basename(model_file)
|
|
self.model_buttons.insert(-1, (model_name, self.run_uploaded_model))
|
|
print(f"Model uploaded: {model_name}")
|
|
self.refresh_model_buttons()
|
|
else:
|
|
self.show_error_popup("Invalid file format. Please upload a .nef file.")
|
|
|
|
|
|
def refresh_model_buttons(self):
|
|
layout = self.models_frame.layout()
|
|
|
|
for i in reversed(range(layout.count())):
|
|
widget_to_remove = layout.itemAt(i).widget()
|
|
if widget_to_remove is not None:
|
|
widget_to_remove.deleteLater()
|
|
|
|
self.add_model_buttons(layout)
|
|
|
|
|
|
def run_uploaded_model(self):
|
|
print("Running uploaded model")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
app = QApplication(sys.argv)
|
|
window = MainWindow()
|
|
window.show()
|
|
sys.exit(app.exec_())
|