Source code for preferences

import re
import subprocess
import time
from serial import serial_for_url
from serial.tools import list_ports
from PyQt5.QtWidgets import (
    QDialog,
    QFormLayout,
    QDialogButtonBox,
    QLabel,
    QComboBox,
    QPushButton,
)
from PyQt5.QtCore import QSettings


[docs]class Preferences(QDialog): """Represents the dialog containg the application settings :param parent: Parent widget, defaults to None :type parent: QWidget, optional """ def __init__(self, parent=None): super().__init__(parent) self.setWindowTitle("Preferences") self.prefs = QSettings() self.cpu_port = None self.gpu_port = None self.actions = QDialogButtonBox( QDialogButtonBox.Ok | QDialogButtonBox.Apply | QDialogButtonBox.Cancel ) self.actions.clicked.connect(self.handlePrefsBtns) settings_form = QFormLayout() com_ports = [ port.__dict__["device"] for port in list(list_ports.comports()) ] self.cpu_port_combo_box = QComboBox() self.cpu_port_combo_box.addItems(com_ports) self.gpu_port_combo_box = QComboBox() self.gpu_port_combo_box.addItems(com_ports) self.prefs.beginGroup("ports") if self.prefs.contains("cpu_port"): self.cpu_port = self.prefs.value("cpu_port") self.cpu_port_combo_box.setCurrentText(self.cpu_port) if self.prefs.contains("gpu_port"): self.gpu_port = self.prefs.value("gpu_port") self.gpu_port_combo_box.setCurrentText(self.gpu_port) self.prefs.endGroup() self.cpu_port_combo_box.currentTextChanged.connect(self.setCpuPort) self.gpu_port_combo_box.currentTextChanged.connect(self.setGpuPort) auto_ident = QPushButton("Auto-Identify CPU/GPU") auto_ident.clicked.connect(self.idUcs) settings_form.addRow(QLabel("Propeller Ports")) settings_form.addRow("CPU Port:", self.cpu_port_combo_box) settings_form.addRow("GPU Port:", self.gpu_port_combo_box) settings_form.addRow(auto_ident) settings_form.addWidget(self.actions) self.setLayout(settings_form)
[docs] def idUcs(self): """Executes the serial routines necessary to identify which COM ports the GPU and CPU are on """ new_cpu_port = None new_gpu_port = None for port in list(list_ports.comports()): result = subprocess.getoutput( [ "propellent.exe", "/id", "/port", port.__dict__["device"], "/gui", "off", ] ) prop_ports = re.search( r"Propeller chip version 1 found on (COM[0-9]+)", result ) if prop_ports: port = prop_ports.group(1) ser = serial_for_url(port, 19200, timeout=0, do_not_open=True) ser.open() response = None start = time.time() timeout = 5 while not response and time.time() < start + timeout: ser.write(b"\x59") response = ser.read(3) ser.close() if response == b"CPU": new_cpu_port = port elif response == b"GPU": new_gpu_port = port if not new_cpu_port or not new_gpu_port: # Error dialog return self.setCpuPort(new_cpu_port) self.setGpuPort(new_gpu_port) self.cpu_port_combo_box.setCurrentText(self.cpu_port) self.gpu_port_combo_box.setCurrentText(self.gpu_port)
[docs] def setCpuPort(self, port): """Sets the GPU COM port in preferences :param port: COM port hosting the CPU :type port: str """ self.cpu_port = port
[docs] def setGpuPort(self, port): """Sets the GPU COM port in preferences :param port: COM port hosting the GPU :type port: str """ self.gpu_port = port
[docs] def handlePrefsBtns(self, button): """Handles Ok/Apply/Cancel preferences buttons :param button: Button which triggered the actions :type button: QPushButton """ if button is self.actions.button(QDialogButtonBox.Cancel): self.reject() self.prefs.beginGroup("ports") self.prefs.setValue("cpu_port", self.cpu_port) self.prefs.setValue("gpu_port", self.gpu_port) self.prefs.endGroup() if button is self.actions.button(QDialogButtonBox.Ok): self.accept()