class AllKeysDialog(QDialog): def __init__( self, parent=None, ): super(AllKeysDialog, self).__init__(parent) layout = QVBoxLayout(self) label = QLabel("Below you can see a list with all the supported keys.") self.list = QListWidget() self.listAllKeys() layout.addWidget(label) layout.setAlignment(label, Qt.Alignment.AlignTop) layout.addWidget(self.list) self.setLayout(layout) self.window().setMaximumWidth(300) # TODO: list all supported keys def listAllKeys(self): self.list.addItems([x for x in SUPPORTED_KEYS]) # static method to create the dialog and return (date, time, accepted) @staticmethod def getDialog(parent=None): dialog = AllKeysDialog(parent) result = dialog.exec() return result == QDialog.DialogCode.Accepted
def __init__(self, parent=None): super(MainWidget, self).__init__(parent) self.setWindowTitle("QThread Demo") self.thread = Worker() self.listFile = QListWidget() self.buttonStart = QPushButton("开始") layout = QGridLayout(self) layout.addWidget(self.listFile, 0, 0, 1, 2) layout.addWidget(self.buttonStart, 1, 1) self.buttonStart.clicked.connect(self.slotStart) self.thread.sinOut.connect(self.slodAdd)
def __init__( self, parent=None, ): super(AllKeysDialog, self).__init__(parent) layout = QVBoxLayout(self) label = QLabel("Below you can see a list with all the supported keys.") self.list = QListWidget() self.listAllKeys() layout.addWidget(label) layout.setAlignment(label, Qt.Alignment.AlignTop) layout.addWidget(self.list) self.setLayout(layout) self.window().setMaximumWidth(300)
def questionPlayPageUI(self): layout = QFormLayout() self.questionPlayPage.titleDisplay = QLabel() layout.addRow(self.questionPlayPage.titleDisplay) self.questionPlayPage.contentDisplay = QLabel() layout.addRow(self.questionPlayPage.contentDisplay) self.questionPlayPage.choiceList = QListWidget() self.questionPlayPage.playerScores = QLabel() layout.addRow(self.questionPlayPage.choiceList, self.questionPlayPage.playerScores) self.questionPlayPage.chooseButton = QPushButton("&Submit") self.questionPlayPage.chooseButton.clicked.connect( self.submitPlayQuestion) layout.addRow(self.questionPlayPage.chooseButton) self.questionPlayPage.collapseButton = QPushButton("Collapse!") self.questionPlayPage.collapseButton.clicked.connect( self.goTo_CollapsePage) self.questionPlayPage.abortButton = QPushButton("Abort") self.questionPlayPage.abortButton.clicked.connect( self.abortGameInProgress) layout.addRow(self.questionPlayPage.collapseButton, self.questionPlayPage.abortButton) self.questionPlayPage.setLayout(layout)
def playerAdmissionsPageUI(self): layout = QFormLayout() self.playerAdmissionsPage.createAnAccountButton = QPushButton( "&Create New Account!") self.playerAdmissionsPage.createAnAccountButton.clicked.connect( self.goTo_AccountCreationPage) layout.addRow(self.playerAdmissionsPage.createAnAccountButton) self.playerAdmissionsPage.proceedToLoginButton = QPushButton("&Login") self.playerAdmissionsPage.proceedToLoginButton.clicked.connect( self.goTo_LoginPage) layout.addRow(self.playerAdmissionsPage.proceedToLoginButton) self.playerAdmissionsPage.readyList = QListWidget() layout.addRow(self.playerAdmissionsPage.readyList) self.playerAdmissionsPage.removePlayerButton = QPushButton( "&Remove Selected Players") self.playerAdmissionsPage.removePlayerButton.clicked.connect( self.removePlayerFromPlayerAdmissionsPageList) layout.addRow(self.playerAdmissionsPage.removePlayerButton) self.playerAdmissionsPage.startGameButton = QPushButton("&Start Game!") self.playerAdmissionsPage.startGameButton.clicked.connect( self.startNewGame) layout.addRow(self.playerAdmissionsPage.startGameButton) self.playerAdmissionsPage.proceedToFacilAuthPageButton = QPushButton( "&Faciliator Page") self.playerAdmissionsPage.proceedToFacilAuthPageButton.clicked.connect( self.goTo_FacilAuthPage) layout.addRow(self.playerAdmissionsPage.proceedToFacilAuthPageButton) self.playerAdmissionsPage.setLayout(layout)
def setup_ui(self): self.l = l = QVBoxLayout(self) self.splitter = s = QSplitter(self) l.addWidget(s) self.ab = b = self.bb.addButton(_('Add new account'), QDialogButtonBox.ButtonRole.ActionRole) b.clicked.connect(self.add_account) l.addWidget(self.bb) self.accounts = a = QListWidget(self) a.setDragDropMode(QAbstractItemView.DragDropMode.InternalMove) self.edit_account = e = EditAccount(self) e.changed.connect(self.data_changed) e.delete_requested.connect(self.delete_requested) s.addWidget(a), s.addWidget(e) for n, account in enumerate(self.db[self.key]['accounts']): if n == 0: e.data = account i = QListWidgetItem(account['username'], a) i.setData(Qt.ItemDataRole.UserRole, account) if a.count() < 1: na = {'username': '', 'password': '', 'notes': ''} i = QListWidgetItem('', a) i.setData(Qt.ItemDataRole.UserRole, na) a.setCurrentRow(0) a.currentItemChanged.connect(self.current_item_changed)
def setup_layout(self): lay = QtWidgets.QHBoxLayout(self) selectedLayout = QVBoxLayout() self.mInput = QListWidget() selectedLayout.addWidget(QLabel("Selected:")) selectedLayout.addWidget(self.mInput) availableLayout = QVBoxLayout() self.mOuput = QListWidget() availableLayout.addWidget(QLabel("Available")) availableLayout.addWidget(self.mOuput) self.mButtonToSelected = QtWidgets.QPushButton(">>") self.mBtnMoveToAvailable = QtWidgets.QPushButton(">") self.mBtnMoveToSelected = QtWidgets.QPushButton("<") self.mButtonToAvailable = QtWidgets.QPushButton("<<") vlay = QtWidgets.QVBoxLayout() vlay.addStretch() vlay.addWidget(self.mButtonToSelected) vlay.addWidget(self.mBtnMoveToAvailable) vlay.addWidget(self.mBtnMoveToSelected) vlay.addWidget(self.mButtonToAvailable) vlay.addStretch() self.mBtnUp = QtWidgets.QPushButton("Up") self.mBtnDown = QtWidgets.QPushButton("Down") vlay2 = QtWidgets.QVBoxLayout() vlay2.addStretch() vlay2.addWidget(self.mBtnUp) vlay2.addWidget(self.mBtnDown) vlay2.addStretch() lay.addLayout(selectedLayout) lay.addLayout(vlay) lay.addLayout(availableLayout) lay.addLayout(vlay2) self.update_buttons_status() self.connections()
class MainWidget(QWidget): def __init__(self, parent=None): super(MainWidget, self).__init__(parent) self.setWindowTitle("QThread Demo") self.thread = Worker() self.listFile = QListWidget() self.buttonStart = QPushButton("开始") layout = QGridLayout(self) layout.addWidget(self.listFile, 0, 0, 1, 2) layout.addWidget(self.buttonStart, 1, 1) self.buttonStart.clicked.connect(self.slotStart) self.thread.sinOut.connect(self.slodAdd) def slodAdd(self, file_inf): self.listFile.addItem(file_inf) def slotStart(self): self.buttonStart.setEnabled(False) self.thread.start()
def setupUi(self, TrainPanel): self.parent = TrainPanel self.mainLayout = QHBoxLayout(TrainPanel) self.bigFont = QLabel().font() self.bigFont.setPointSize(13) self.actionsLayout = QHBoxLayout(TrainPanel) # self.checkRecording = QCheckBox(TrainPanel) self.calibrateButton = QPushButton("Calibrate", parent=TrainPanel) self.calibrateButton.setFont(self.bigFont) self.calibrateButton.setStyleSheet(CustomQStyles.buttonStyle) self.calibrateButton.setMinimumHeight(50) self.calibrateButton.setMaximumWidth(170) self.calibrateButton.setMinimumWidth(120) self.sessionButton = QPushButton("Session", parent=TrainPanel) self.sessionButton.setFont(self.bigFont) self.sessionButton.setStyleSheet(CustomQStyles.outlineButtonStyle) self.sessionButton.setMinimumHeight(50) self.sessionButton.setMaximumWidth(170) self.sessionButton.setMinimumWidth(120) self.listFiles = QListWidget(TrainPanel) self.listFiles.setFont(self.bigFont) self.label = QLabel('or select', parent=TrainPanel) self.subjectLayout = QVBoxLayout(TrainPanel) print("init") self.box1 = QGroupBox(parent=TrainPanel) self.box2 = QGroupBox(parent=TrainPanel) self.wizard = CalibrateWizard(parent=TrainPanel) self.setPatientsBox(TrainPanel) # right panel self.setActionsBox(TrainPanel) # left panel self.mainLayout.addWidget(self.box1, stretch=2) self.mainLayout.addWidget(self.box2, stretch=3)
def add_platform(self, platform: Platform, widget_list: QListWidget) -> None: self.__platforms_to_save.append(platform) class PlatformListEntry(QWidget): def __init__(self, parent: QWidget = None, p_name: str = '', p_type: Platform.WarningType = Platform.WarningType( Platform.WarningType.UNKNOWN)): super(QWidget, self).__init__(parent) self.__p_name = p_name self.__p_type = p_type self.__platform_name_label = QLabel(p_name, self) self.__platform_type_label = QLabel(f'Type : {p_type}', self) self.setLayout(QHBoxLayout()) self.layout().addWidget(self.__platform_name_label) self.layout().addWidget(self.__platform_type_label) def to_platform(self) -> Platform: return Platform(warning_type=self.__p_type.value, platform_name=self.__p_name) container: QListWidgetItem = QListWidgetItem(widget_list) item: PlatformListEntry = PlatformListEntry( p_name=platform.platform_name, p_type=platform.warning_type, parent=self) container.setSizeHint(item.sizeHint()) widget_list.setItemWidget(container, item) self.apply_button.setEnabled(self.apply_possible())
def remove_selected(window: PlatformWindow, list_widget: QListWidget) -> None: platform_to_remove = list_widget.itemWidget( list_widget.item(list_widget.currentRow())).to_platform() index_of_item = -1 for i in range(len(window.__platforms_to_save)): if window.__platforms_to_save[ i].platform_name == platform_to_remove.platform_name: index_of_item = i if index_of_item != -1: window.__platforms_to_save.remove( window.__platforms_to_save[index_of_item]) list_widget.takeItem(list_widget.currentRow()) window.apply_button.setEnabled(window.apply_possible())
def __init__(self, parent=None): super(WinForm, self).__init__(parent) self.setWindowTitle("QTimer demo") self.listFile = QListWidget() self.label = QLabel("显示当前时间") self.startButton = QPushButton("开始") self.endButton = QPushButton("结束") layout = QGridLayout(self) # 初始化定时器 self.timer = QTimer(self) # 显示时间 self.timer.timeout.connect( self.showTime) # timeout 信号连接到特定的槽,当定时器超时,发出 timeout 信号 layout.addWidget(self.label, 0, 0, 1, 2) layout.addWidget(self.startButton, 1, 0) layout.addWidget(self.endButton, 1, 1) self.startButton.clicked.connect(self.start_timer) self.endButton.clicked.connect(self.end_timer) self.setLayout(layout)
class MainWindow(QMainWindow): def __init__(self): super().__init__() self.setWindowTitle("📸 Random Image Tools V1.2 🔨") self.image_list = [] # ToDo: Add a "rename?" flag. Like rename image files # to store the directory path for later use self.directory_path_name = "/" # Set up the layouts layer_one = QHBoxLayout() # Select a folder, selected directory layer_one_and_a_half = QHBoxLayout() # Selected directory contents layer_two = QHBoxLayout() # Second line of buttons layer_two_vertical_one = QVBoxLayout() # Store the first column w/checkbox and "Convert" layer_two_vertical_two = QVBoxLayout() # Store the second column w/checkbox and "Open in File Browser" layer_three = QHBoxLayout() # Conversion process state vertical_layout_parent = QVBoxLayout() # Parent widget widget = QWidget() # Displays selected directory self.directory_label = QLabel() self.directory_label.setText("Directory to be worked on will show here ") self.directory_label.show() # Displays "Select folder" button self.select_a_folder_button = QPushButton() self.select_a_folder_button.setText("Select a folder:") self.select_a_folder_button.clicked.connect(self.select_folder_prompt) self.select_a_folder_button.show() # Displays the image contents of the selected folder self.image_paths_list_widget = QListWidget() self.image_paths_list_widget.show() # Displays button to initiate image conversion self.convert_to_png_button = QPushButton() self.convert_to_png_button.setText("Convert to PNG") self.convert_to_png_button.clicked.connect(self.convert_folder_to_png) self.convert_to_png_button.show() # Check boxes for "Create new folder for PNGs" and "Delete original files after converting" self.create_new_folder_checkbox = QCheckBox() self.create_new_folder_checkbox.setText("Create new folder to store converted PNG's?") self.create_new_folder_checkbox.show() self.delete_original_files_checkbox = QCheckBox() self.delete_original_files_checkbox.setText("Delete original files after converting them to PNG?") self.create_new_folder_checkbox.show() # Displays button to open selected directory in the file browser self.show_folder_button = QPushButton() self.show_folder_button.setText("Open selected folder in file browser") self.show_folder_button.clicked.connect(self.open_folder) self.show_folder_button.show() # Displays label when conversion is finished, and the corresponding progress bar self.conversion_finished_or_error_label = QLabel() self.conversion_finished_or_error_label.setText("👀 waiting for you to press \"Convert to PNG\" ") # Put the find folder button and folder selected button together layer_one.addWidget(self.select_a_folder_button) layer_one.addWidget(self.directory_label) # Image paths of selected folder layer_one_and_a_half.addWidget(self.image_paths_list_widget) # Put the convert button and open-in-finder button together layer_two_vertical_one.addWidget(self.convert_to_png_button) layer_two_vertical_one.addWidget(self.delete_original_files_checkbox) layer_two.addLayout(layer_two_vertical_one) layer_two_vertical_two.addWidget(self.show_folder_button) layer_two_vertical_two.addWidget(self.create_new_folder_checkbox) layer_two.addLayout(layer_two_vertical_two) # Label and progress bar layer_three.addWidget(self.conversion_finished_or_error_label) layer_three.setAlignment(Qt.AlignmentFlag.AlignHCenter) # Put the "convert to png" button beneath vertical_layout_parent.addLayout(layer_one) vertical_layout_parent.addLayout(layer_one_and_a_half) vertical_layout_parent.addLayout(layer_two) vertical_layout_parent.addLayout(layer_three) widget.setLayout(vertical_layout_parent) self.setCentralWidget(widget) # Prompts user to select a folder, stores the given folder path and displays chosen path to user def select_folder_prompt(self): # Clear self.image_list and QListWidget to prepare for newly selected folder. self.image_list.clear() self.image_paths_list_widget.clear() # Append a "/" otherwise it will mix the folder name and containing image file together directory = str(QFileDialog.getExistingDirectory(self, "Select Directory")) + "/" # Update QLabel to new directory, and store it in self for future use self.directory_label.setText(directory) self.directory_path_name = directory # Update self.image_list field image_list = self.scan_for_jpg_file_paths() self.image_list = image_list # Populated the QListWindow() with the update self.image_list field self.image_paths_list_widget.addItems(self.image_list) # Given a path name, will open it in the Folder browser app def open_folder(self): subprocess.call(["open", "-R", self.directory_path_name]) # Given the current state of the directory_path_name folder, will scan for image files in that folder def scan_for_jpg_file_paths(self): image_list = [] for root, dirs, files in os.walk(self.directory_path_name, topdown=True): for filename in files: if '.jpeg' or '.jpg' or '.webp' or '.gif' or '.icns' in filename: if '.png' not in filename: absolute_path = self.directory_path_name + filename # Avoid adding duplicates if absolute_path not in image_list: image_list.append(absolute_path) return image_list # Given a non-empty folder path, converts all jpg images in it to png. # Todo: Store png images in a new folder? # ToDo: Add a "Delete images after converting?" # ToDo: Add functionality for checkboxes # Ok so that the QListWidget can update, I'm going to have to get the image_list before calling this function. # In other words, image_list is a field in the MainWindow subclass, and is update after selecting the folder, and # called before calling this function. def convert_folder_to_png(self): self.conversion_finished_or_error_label.setText("Converting") # Progress bar depends on independent variable, length of image list = x if len(self.image_list) > 0: self.convert_images_to_png() self.conversion_finished_or_error_label.setText("Conversion finished") if len(self.image_list) <= 0: self.conversion_finished_or_error_label.setText("There are no image files in this folder") # This will be called after a folder has been selected and the "Convert to PNG" button has been pressed def convert_images_to_png(self): self.conversion_finished_or_error_label.setText("...") # Convert images # ToDo : Put the checkbox logic here # Check if user wanted images stored in a new folder # Check if user wanted to delete original images after conversion # Placeholder for converted_PNG folder user_wanted_png_in_new_folder = self.create_new_folder_checkbox.isChecked() user_wanted_unconverted_image_deleted = self.delete_original_files_checkbox.isChecked() converted_png_folder_name = "" # Create folder if user wanted converted images stored in a new folder if user_wanted_png_in_new_folder: converted_png_folder_name = self.directory_path_name + "Converted PNG Files/" os.mkdir(converted_png_folder_name) for image_path in self.image_list: # Get absolute path absolute_image_path = os.path.abspath(image_path) if ".DS_Store" not in absolute_image_path: # Mac adds .DS_Store, just a way to ignore these pesky files unconverted_image = Image.open(absolute_image_path) # Image object if user_wanted_png_in_new_folder: # Get just the image name and extension name_and_extension_of_image = extract_image_name_and_extension(absolute_image_path) # Append image name and extension to the converted image folder path image_path_stored_in_converted_png_folder = converted_png_folder_name + name_and_extension_of_image # Store in converted image folder path unconverted_image.save(rename_image_path_to_png(image_path_stored_in_converted_png_folder)) else: unconverted_image.save(rename_image_path_to_png(absolute_image_path)) if user_wanted_unconverted_image_deleted: os.remove(absolute_image_path)
def __init__(self, parent: QWidget = None, platforms: List[Platform] = None): super(QWidget, self).__init__(parent) self.__platforms = platforms.copy() self.__platforms_to_save = [] self.setLayout(QVBoxLayout()) mid_section: QLayout = QHBoxLayout() mid_section_labels: QLayout = QVBoxLayout() platform_name_label: QLabel = QLabel("""Platform Name""", self) platform_warning_suppress_label: QLabel = QLabel( """Warning Suppression Type""", self) mid_section_labels.addWidget(platform_name_label) mid_section_labels.addWidget(platform_warning_suppress_label) mid_section_labels.setAlignment(platform_name_label, Qt.AlignmentFlag.AlignBottom) mid_section_labels.setAlignment(platform_warning_suppress_label, Qt.AlignmentFlag.AlignTop) mid_section_edits: QLayout = QVBoxLayout() platform_name_input: QLineEdit = QLineEdit(self) platform_warning_suppress_input: QComboBox = QComboBox(self) for item in all_platform_warning_types(): platform_warning_suppress_input.addItem(str(item), item) mid_section_edits.addWidget(platform_name_input) mid_section_edits.addWidget(platform_warning_suppress_input) mid_section_edits.setAlignment(platform_name_input, Qt.AlignmentFlag.AlignBottom) mid_section_edits.setAlignment(platform_warning_suppress_input, Qt.AlignmentFlag.AlignTop) mid_section_buttons: QLayout = QVBoxLayout() mid_section.addItem(mid_section_labels) mid_section.addItem(mid_section_edits) mid_section.addItem(mid_section_buttons) add_button: QPushButton = QPushButton("Add", self) add_button.setDisabled(True) remove_button: QPushButton = QPushButton("Remove", self) remove_button.setDisabled(True) mid_section_buttons.addWidget(add_button) mid_section_buttons.addItem( QSpacerItem(0, 20, QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Minimum)) mid_section_buttons.addWidget(remove_button) mid_section_buttons.setAlignment(add_button, Qt.AlignmentFlag.AlignBottom) mid_section_buttons.setAlignment(remove_button, Qt.AlignmentFlag.AlignTop) platform_list: QListWidget = QListWidget(self) mid_section.addWidget(platform_list) buttons_section: QLayout = QHBoxLayout() self.__ok_button: QPushButton = QPushButton('Ok', self) self.__cancel_button: QPushButton = QPushButton('Cancel', self) self.__apply_button: QPushButton = QPushButton('Apply', self) buttons_section.addWidget(self.ok_button) buttons_section.addWidget(self.cancel_button) buttons_section.addWidget(self.apply_button) self.ok_button.clicked.connect(lambda: self.ok()) self.apply_button.clicked.connect(lambda: self.apply()) self.cancel_button.clicked.connect(lambda: self.cancel()) self.layout().addWidget(QLabel('Platforms', self)) self.layout().addItem(mid_section) self.layout().addItem(buttons_section) platform_name_input.textChanged.connect( lambda content: add_button.setEnabled(len(content) > 0)) def reset_inputs() -> None: platform_name_input.clear() platform_warning_suppress_input.setCurrentIndex(0) add_button.clicked.connect(lambda: self.add_platform( Platform(platform_warning_suppress_input.currentData().value, platform_name_input.text()), platform_list)) add_button.clicked.connect(lambda: reset_inputs()) for platform in self.platforms: self.add_platform(platform, platform_list) platform_list.setSelectionMode( QAbstractItemView.SelectionMode.SingleSelection) platform_list.itemSelectionChanged.connect( lambda: remove_button.setEnabled(True)) self.apply_button.setDisabled(True) def remove_selected(window: PlatformWindow, list_widget: QListWidget) -> None: platform_to_remove = list_widget.itemWidget( list_widget.item(list_widget.currentRow())).to_platform() index_of_item = -1 for i in range(len(window.__platforms_to_save)): if window.__platforms_to_save[ i].platform_name == platform_to_remove.platform_name: index_of_item = i if index_of_item != -1: window.__platforms_to_save.remove( window.__platforms_to_save[index_of_item]) list_widget.takeItem(list_widget.currentRow()) window.apply_button.setEnabled(window.apply_possible()) remove_button.clicked.connect( lambda: remove_selected(self, platform_list))
class TwoListSelection(QtWidgets.QWidget): def __init__(self, parent=None): super(TwoListSelection, self).__init__(parent) self.setup_layout() def setup_layout(self): lay = QtWidgets.QHBoxLayout(self) selectedLayout = QVBoxLayout() self.mInput = QListWidget() selectedLayout.addWidget(QLabel("Selected:")) selectedLayout.addWidget(self.mInput) availableLayout = QVBoxLayout() self.mOuput = QListWidget() availableLayout.addWidget(QLabel("Available")) availableLayout.addWidget(self.mOuput) self.mButtonToSelected = QtWidgets.QPushButton(">>") self.mBtnMoveToAvailable = QtWidgets.QPushButton(">") self.mBtnMoveToSelected = QtWidgets.QPushButton("<") self.mButtonToAvailable = QtWidgets.QPushButton("<<") vlay = QtWidgets.QVBoxLayout() vlay.addStretch() vlay.addWidget(self.mButtonToSelected) vlay.addWidget(self.mBtnMoveToAvailable) vlay.addWidget(self.mBtnMoveToSelected) vlay.addWidget(self.mButtonToAvailable) vlay.addStretch() self.mBtnUp = QtWidgets.QPushButton("Up") self.mBtnDown = QtWidgets.QPushButton("Down") vlay2 = QtWidgets.QVBoxLayout() vlay2.addStretch() vlay2.addWidget(self.mBtnUp) vlay2.addWidget(self.mBtnDown) vlay2.addStretch() lay.addLayout(selectedLayout) lay.addLayout(vlay) lay.addLayout(availableLayout) lay.addLayout(vlay2) self.update_buttons_status() self.connections() @QtCore.pyqtSlot() def update_buttons_status(self): self.mBtnUp.setDisabled(not bool(self.mOuput.selectedItems()) or self.mOuput.currentRow() == 0) self.mBtnDown.setDisabled( not bool(self.mOuput.selectedItems()) or self.mOuput.currentRow() == (self.mOuput.count() - 1)) self.mBtnMoveToAvailable.setDisabled( not bool(self.mInput.selectedItems()) or self.mOuput.currentRow() == 0) self.mBtnMoveToSelected.setDisabled( not bool(self.mOuput.selectedItems())) def connections(self): self.mInput.itemSelectionChanged.connect(self.update_buttons_status) self.mOuput.itemSelectionChanged.connect(self.update_buttons_status) self.mBtnMoveToAvailable.clicked.connect( self.on_mBtnMoveToAvailable_clicked) self.mBtnMoveToSelected.clicked.connect( self.on_mBtnMoveToSelected_clicked) self.mButtonToAvailable.clicked.connect( self.on_mButtonToAvailable_clicked) self.mButtonToSelected.clicked.connect( self.on_mButtonToSelected_clicked) self.mBtnUp.clicked.connect(self.on_mBtnUp_clicked) self.mBtnDown.clicked.connect(self.on_mBtnDown_clicked) @QtCore.pyqtSlot() def on_mBtnMoveToAvailable_clicked(self): self.mOuput.addItem(self.mInput.takeItem(self.mInput.currentRow())) @QtCore.pyqtSlot() def on_mBtnMoveToSelected_clicked(self): self.mInput.addItem(self.mOuput.takeItem(self.mOuput.currentRow())) @QtCore.pyqtSlot() def on_mButtonToAvailable_clicked(self): while self.mOuput.count() > 0: self.mInput.addItem(self.mOuput.takeItem(0)) @QtCore.pyqtSlot() def on_mButtonToSelected_clicked(self): while self.mInput.count() > 0: self.mOuput.addItem(self.mInput.takeItem(0)) @QtCore.pyqtSlot() def on_mBtnUp_clicked(self): row = self.mOuput.currentRow() currentItem = self.mOuput.takeItem(row) self.mOuput.insertItem(row - 1, currentItem) self.mOuput.setCurrentRow(row - 1) @QtCore.pyqtSlot() def on_mBtnDown_clicked(self): row = self.mOuput.currentRow() currentItem = self.mOuput.takeItem(row) self.mOuput.insertItem(row + 1, currentItem) self.mOuput.setCurrentRow(row + 1) def addAvailableItems(self, items): self.mInput.addItems(items) def get_left_elements(self): r = [] for i in range(self.mInput.count()): it = self.mInput.item(i) r.append(it.text()) return r def get_right_elements(self): r = [] for i in range(self.mOuput.count()): it = self.mOuput.item(i) r.append(it.text()) return r
def __init__(self): super().__init__() self.setFixedSize(800, 410) self.setWindowTitle("PyLX16A Servo Testing Software") self.port_selection_box = QComboBox(self) self.port_selection_box.setFixedSize(200, 27) self.port_selection_box.move(30, 65) port_selection_box_label = QLabel("Select Port:", self) port_selection_box_label.move(30, 35) self.port_selection_box_refresh_button = QPushButton("Refresh", self) self.port_selection_box_refresh_button.setFixedSize(60, 23) self.port_selection_box_refresh_button.move(170, 38) self.id_selection_box = QListWidget(self) self.id_selection_box.setFixedSize(200, 200) self.id_selection_box.move(30, 135) id_selection_box_label = QLabel("Connected Servos:", self) id_selection_box_label.setFixedWidth(200) id_selection_box_label.move(30, 105) self.id_selection_box_refresh_button = QPushButton("Refresh", self) self.id_selection_box_refresh_button.setFixedSize(60, 23) self.id_selection_box_refresh_button.move(170, 108) self.set_id_line_edit = QLineEdit(self) self.set_id_line_edit.setFixedSize(50, 27) self.set_id_line_edit.move(80, 355) set_id_line_edit_label = QLabel("Set ID:", self) set_id_line_edit_label.move(30, 355) set_id_line_edit_label.setFixedSize(50, 27) self.set_id_button = QPushButton("Change ID!", self) self.set_id_button.setFixedSize(85, 27) self.set_id_button.move(145, 355) self.position_slider = QSlider(Qt.Orientation.Horizontal, self) self.position_slider.setMinimum(0) self.position_slider.setMaximum(240) self.position_slider.setFixedWidth(200) self.position_slider.move(300, 55) self.position_slider_readout = QLabel("0.00°", self) self.position_slider_readout.setFixedWidth(50) self.position_slider_readout.move(450, 30) self.position_slider_readout.setAlignment( Qt.AlignmentFlag.AlignRight | Qt.AlignmentFlag.AlignVCenter) position_slider_label = QLabel("Angle (degrees):", self) position_slider_label.move(300, 30) self.position_offset_slider = QSlider(Qt.Orientation.Horizontal, self) self.position_offset_slider.setMinimum(-30) self.position_offset_slider.setMaximum(30) self.position_offset_slider.setFixedWidth(200) self.position_offset_slider.move(300, 125) self.position_offset_slider_readout = QLabel("0.00°", self) self.position_offset_slider_readout.setFixedWidth(50) self.position_offset_slider_readout.move(450, 100) self.position_offset_slider_readout.setAlignment( Qt.AlignmentFlag.AlignRight | Qt.AlignmentFlag.AlignVCenter) position_offset_slider_label = QLabel("Angle offset (degrees):", self) position_offset_slider_label.setFixedWidth(200) position_offset_slider_label.move(300, 100) self.angle_lower_limit_textentry = QLineEdit(self) self.angle_lower_limit_textentry.setFixedWidth(50) self.angle_lower_limit_textentry.move(450, 175) self.angle_lower_limit_textentry.setValidator( QIntValidator(0, 240, self)) self.angle_upper_limit_textentry = QLineEdit(self) self.angle_upper_limit_textentry.setFixedWidth(50) self.angle_upper_limit_textentry.move(450, 210) self.angle_upper_limit_textentry.setValidator( QIntValidator(0, 240, self)) self.angle_lower_limit_textentry_label = QLabel( "Lower Limit (degrees):", self) self.angle_lower_limit_textentry_label.move(300, 175) self.angle_lower_limit_textentry_label.setFixedWidth(150) self.angle_upper_limit_textentry_label = QLabel( "Upper Limit (degrees):", self) self.angle_upper_limit_textentry_label.move(300, 210) self.angle_upper_limit_textentry_label.setFixedWidth(150) self.vin_lower_limit_textentry = QLineEdit(self) self.vin_lower_limit_textentry.setFixedWidth(50) self.vin_lower_limit_textentry.move(450, 265) self.vin_lower_limit_textentry.setValidator( QIntValidator(4500, 12000, self)) self.vin_upper_limit_textentry = QLineEdit(self) self.vin_upper_limit_textentry.setFixedWidth(50) self.vin_upper_limit_textentry.move(450, 300) self.vin_upper_limit_textentry.setValidator( QIntValidator(4500, 12000, self)) self.vin_lower_limit_textentry_label = QLabel( "Voltage Lower Limit (mV):", self) self.vin_lower_limit_textentry_label.move(300, 265) self.vin_lower_limit_textentry_label.setFixedWidth(150) self.vin_upper_limit_textentry_label = QLabel( "Voltage Upper Limit (mV):", self) self.vin_upper_limit_textentry_label.move(300, 300) self.vin_upper_limit_textentry_label.setFixedWidth(150) self.temp_limit_textentry = QLineEdit(self) self.temp_limit_textentry.setFixedWidth(50) self.temp_limit_textentry.move(450, 355) self.temp_limit_textentry.setValidator(QIntValidator(50, 100, self)) self.temp_limit_textentry_label = QLabel("Temp Limit (°C):", self) self.temp_limit_textentry_label.move(300, 355) self.temp_limit_textentry_label.setFixedWidth(150) self.servo_mode_radio_button = QRadioButton("Servo Mode", self) self.servo_mode_radio_button.move(565, 50) self.motor_mode_radio_button = QRadioButton("Motor Mode", self) self.motor_mode_radio_button.move(565, 75) self.motor_speed_slider = QSlider(Qt.Orientation.Horizontal, self) self.motor_speed_slider.setMinimum(-1000) self.motor_speed_slider.setMaximum(1000) self.motor_speed_slider.setFixedWidth(200) self.motor_speed_slider.move(565, 125) motor_speed_slider_label = QLabel("Motor Speed:", self) motor_speed_slider_label.move(565, 100) self.torque_enabled_checkbox = QCheckBox("Torque Enabled", self) self.torque_enabled_checkbox.move(565, 175) self.torque_enabled_checkbox.setFixedWidth(200) self.led_enabled_checkbox = QCheckBox("LED Enabled", self) self.led_enabled_checkbox.move(565, 210) self.led_enabled_checkbox.setFixedWidth(200) self.led_over_temp_checkbox = QCheckBox("LED Over Temperature", self) self.led_over_temp_checkbox.move(565, 258) self.led_over_temp_checkbox.setFixedWidth(200) self.led_over_voltage_checkbox = QCheckBox("LED Over Voltage", self) self.led_over_voltage_checkbox.move(565, 283) self.led_over_voltage_checkbox.setFixedWidth(200) self.led_rotor_locked_checkbox = QCheckBox("LED Rotor Locked", self) self.led_rotor_locked_checkbox.move(565, 308) self.led_rotor_locked_checkbox.setFixedWidth(200) self.physical_position_readout = QLabel("--°", self) self.physical_position_readout.move(565, 367) self.physical_position_readout.setFixedWidth(200) self.physical_position_readout_label = QLabel("Position", self) self.physical_position_readout_label.move(565, 347) self.temperature_readout = QLabel("-- °C", self) self.temperature_readout.move(635, 367) self.temperature_readout.setFixedWidth(200) self.temperature_readout_label = QLabel("Temperature", self) self.temperature_readout_label.move(635, 347) self.voltage_readout = QLabel("-- V", self) self.voltage_readout.move(730, 367) self.voltage_readout.setFixedWidth(200) self.voltage_readout_label = QLabel("Voltage", self) self.voltage_readout_label.move(730, 347) self.readout_update_timer = QTimer(self) self.readout_update_timer.timeout.connect(self.update_readouts) self.readout_update_timer.start(250) self.active_servo: LX16A = None self.position_slider.setValue(0) self.position_offset_slider.setValue(0) self.motor_speed_slider.setValue(0) self.id_selection_box_refresh_button.setEnabled(False) self.disable_widgets() self.port_selection_box.currentTextChanged.connect( self.port_selection_box_changed) self.port_selection_box_refresh_button.clicked.connect( self.port_refresh_button_clicked) self.id_selection_box.currentTextChanged.connect( self.id_selection_box_changed) self.id_selection_box_refresh_button.clicked.connect( self.id_refresh_button_clicked) self.set_id_button.pressed.connect(self.id_updated) self.position_slider.sliderMoved.connect(self.position_slider_updated) self.position_offset_slider.sliderMoved.connect( self.position_offset_slider_updated) self.angle_lower_limit_textentry.textChanged.connect( self.angle_lower_limit_updated) self.angle_upper_limit_textentry.textChanged.connect( self.angle_upper_limit_updated) self.vin_lower_limit_textentry.textChanged.connect( self.vin_lower_limit_updated) self.vin_upper_limit_textentry.textChanged.connect( self.vin_upper_limit_updated) self.temp_limit_textentry.textChanged.connect(self.temp_limit_updated) self.servo_mode_radio_button.toggled.connect( self.servo_mode_radio_button_toggled) self.motor_mode_radio_button.toggled.connect( self.motor_mode_radio_button_toggled) self.motor_speed_slider.valueChanged.connect( self.motor_speed_slider_updated) self.torque_enabled_checkbox.stateChanged.connect( self.torque_enabled_checkbox_toggled) self.led_enabled_checkbox.stateChanged.connect( self.led_enabled_checkbox_toggled) self.led_over_temp_checkbox.stateChanged.connect( self.led_error_triggers_checkbox_toggled) self.led_over_voltage_checkbox.stateChanged.connect( self.led_error_triggers_checkbox_toggled) self.led_rotor_locked_checkbox.stateChanged.connect( self.led_error_triggers_checkbox_toggled) self.scan_for_ports()
class MainWindow(QMainWindow): def __init__(self): super().__init__() self.setFixedSize(800, 410) self.setWindowTitle("PyLX16A Servo Testing Software") self.port_selection_box = QComboBox(self) self.port_selection_box.setFixedSize(200, 27) self.port_selection_box.move(30, 65) port_selection_box_label = QLabel("Select Port:", self) port_selection_box_label.move(30, 35) self.port_selection_box_refresh_button = QPushButton("Refresh", self) self.port_selection_box_refresh_button.setFixedSize(60, 23) self.port_selection_box_refresh_button.move(170, 38) self.id_selection_box = QListWidget(self) self.id_selection_box.setFixedSize(200, 200) self.id_selection_box.move(30, 135) id_selection_box_label = QLabel("Connected Servos:", self) id_selection_box_label.setFixedWidth(200) id_selection_box_label.move(30, 105) self.id_selection_box_refresh_button = QPushButton("Refresh", self) self.id_selection_box_refresh_button.setFixedSize(60, 23) self.id_selection_box_refresh_button.move(170, 108) self.set_id_line_edit = QLineEdit(self) self.set_id_line_edit.setFixedSize(50, 27) self.set_id_line_edit.move(80, 355) set_id_line_edit_label = QLabel("Set ID:", self) set_id_line_edit_label.move(30, 355) set_id_line_edit_label.setFixedSize(50, 27) self.set_id_button = QPushButton("Change ID!", self) self.set_id_button.setFixedSize(85, 27) self.set_id_button.move(145, 355) self.position_slider = QSlider(Qt.Orientation.Horizontal, self) self.position_slider.setMinimum(0) self.position_slider.setMaximum(240) self.position_slider.setFixedWidth(200) self.position_slider.move(300, 55) self.position_slider_readout = QLabel("0.00°", self) self.position_slider_readout.setFixedWidth(50) self.position_slider_readout.move(450, 30) self.position_slider_readout.setAlignment( Qt.AlignmentFlag.AlignRight | Qt.AlignmentFlag.AlignVCenter) position_slider_label = QLabel("Angle (degrees):", self) position_slider_label.move(300, 30) self.position_offset_slider = QSlider(Qt.Orientation.Horizontal, self) self.position_offset_slider.setMinimum(-30) self.position_offset_slider.setMaximum(30) self.position_offset_slider.setFixedWidth(200) self.position_offset_slider.move(300, 125) self.position_offset_slider_readout = QLabel("0.00°", self) self.position_offset_slider_readout.setFixedWidth(50) self.position_offset_slider_readout.move(450, 100) self.position_offset_slider_readout.setAlignment( Qt.AlignmentFlag.AlignRight | Qt.AlignmentFlag.AlignVCenter) position_offset_slider_label = QLabel("Angle offset (degrees):", self) position_offset_slider_label.setFixedWidth(200) position_offset_slider_label.move(300, 100) self.angle_lower_limit_textentry = QLineEdit(self) self.angle_lower_limit_textentry.setFixedWidth(50) self.angle_lower_limit_textentry.move(450, 175) self.angle_lower_limit_textentry.setValidator( QIntValidator(0, 240, self)) self.angle_upper_limit_textentry = QLineEdit(self) self.angle_upper_limit_textentry.setFixedWidth(50) self.angle_upper_limit_textentry.move(450, 210) self.angle_upper_limit_textentry.setValidator( QIntValidator(0, 240, self)) self.angle_lower_limit_textentry_label = QLabel( "Lower Limit (degrees):", self) self.angle_lower_limit_textentry_label.move(300, 175) self.angle_lower_limit_textentry_label.setFixedWidth(150) self.angle_upper_limit_textentry_label = QLabel( "Upper Limit (degrees):", self) self.angle_upper_limit_textentry_label.move(300, 210) self.angle_upper_limit_textentry_label.setFixedWidth(150) self.vin_lower_limit_textentry = QLineEdit(self) self.vin_lower_limit_textentry.setFixedWidth(50) self.vin_lower_limit_textentry.move(450, 265) self.vin_lower_limit_textentry.setValidator( QIntValidator(4500, 12000, self)) self.vin_upper_limit_textentry = QLineEdit(self) self.vin_upper_limit_textentry.setFixedWidth(50) self.vin_upper_limit_textentry.move(450, 300) self.vin_upper_limit_textentry.setValidator( QIntValidator(4500, 12000, self)) self.vin_lower_limit_textentry_label = QLabel( "Voltage Lower Limit (mV):", self) self.vin_lower_limit_textentry_label.move(300, 265) self.vin_lower_limit_textentry_label.setFixedWidth(150) self.vin_upper_limit_textentry_label = QLabel( "Voltage Upper Limit (mV):", self) self.vin_upper_limit_textentry_label.move(300, 300) self.vin_upper_limit_textentry_label.setFixedWidth(150) self.temp_limit_textentry = QLineEdit(self) self.temp_limit_textentry.setFixedWidth(50) self.temp_limit_textentry.move(450, 355) self.temp_limit_textentry.setValidator(QIntValidator(50, 100, self)) self.temp_limit_textentry_label = QLabel("Temp Limit (°C):", self) self.temp_limit_textentry_label.move(300, 355) self.temp_limit_textentry_label.setFixedWidth(150) self.servo_mode_radio_button = QRadioButton("Servo Mode", self) self.servo_mode_radio_button.move(565, 50) self.motor_mode_radio_button = QRadioButton("Motor Mode", self) self.motor_mode_radio_button.move(565, 75) self.motor_speed_slider = QSlider(Qt.Orientation.Horizontal, self) self.motor_speed_slider.setMinimum(-1000) self.motor_speed_slider.setMaximum(1000) self.motor_speed_slider.setFixedWidth(200) self.motor_speed_slider.move(565, 125) motor_speed_slider_label = QLabel("Motor Speed:", self) motor_speed_slider_label.move(565, 100) self.torque_enabled_checkbox = QCheckBox("Torque Enabled", self) self.torque_enabled_checkbox.move(565, 175) self.torque_enabled_checkbox.setFixedWidth(200) self.led_enabled_checkbox = QCheckBox("LED Enabled", self) self.led_enabled_checkbox.move(565, 210) self.led_enabled_checkbox.setFixedWidth(200) self.led_over_temp_checkbox = QCheckBox("LED Over Temperature", self) self.led_over_temp_checkbox.move(565, 258) self.led_over_temp_checkbox.setFixedWidth(200) self.led_over_voltage_checkbox = QCheckBox("LED Over Voltage", self) self.led_over_voltage_checkbox.move(565, 283) self.led_over_voltage_checkbox.setFixedWidth(200) self.led_rotor_locked_checkbox = QCheckBox("LED Rotor Locked", self) self.led_rotor_locked_checkbox.move(565, 308) self.led_rotor_locked_checkbox.setFixedWidth(200) self.physical_position_readout = QLabel("--°", self) self.physical_position_readout.move(565, 367) self.physical_position_readout.setFixedWidth(200) self.physical_position_readout_label = QLabel("Position", self) self.physical_position_readout_label.move(565, 347) self.temperature_readout = QLabel("-- °C", self) self.temperature_readout.move(635, 367) self.temperature_readout.setFixedWidth(200) self.temperature_readout_label = QLabel("Temperature", self) self.temperature_readout_label.move(635, 347) self.voltage_readout = QLabel("-- V", self) self.voltage_readout.move(730, 367) self.voltage_readout.setFixedWidth(200) self.voltage_readout_label = QLabel("Voltage", self) self.voltage_readout_label.move(730, 347) self.readout_update_timer = QTimer(self) self.readout_update_timer.timeout.connect(self.update_readouts) self.readout_update_timer.start(250) self.active_servo: LX16A = None self.position_slider.setValue(0) self.position_offset_slider.setValue(0) self.motor_speed_slider.setValue(0) self.id_selection_box_refresh_button.setEnabled(False) self.disable_widgets() self.port_selection_box.currentTextChanged.connect( self.port_selection_box_changed) self.port_selection_box_refresh_button.clicked.connect( self.port_refresh_button_clicked) self.id_selection_box.currentTextChanged.connect( self.id_selection_box_changed) self.id_selection_box_refresh_button.clicked.connect( self.id_refresh_button_clicked) self.set_id_button.pressed.connect(self.id_updated) self.position_slider.sliderMoved.connect(self.position_slider_updated) self.position_offset_slider.sliderMoved.connect( self.position_offset_slider_updated) self.angle_lower_limit_textentry.textChanged.connect( self.angle_lower_limit_updated) self.angle_upper_limit_textentry.textChanged.connect( self.angle_upper_limit_updated) self.vin_lower_limit_textentry.textChanged.connect( self.vin_lower_limit_updated) self.vin_upper_limit_textentry.textChanged.connect( self.vin_upper_limit_updated) self.temp_limit_textentry.textChanged.connect(self.temp_limit_updated) self.servo_mode_radio_button.toggled.connect( self.servo_mode_radio_button_toggled) self.motor_mode_radio_button.toggled.connect( self.motor_mode_radio_button_toggled) self.motor_speed_slider.valueChanged.connect( self.motor_speed_slider_updated) self.torque_enabled_checkbox.stateChanged.connect( self.torque_enabled_checkbox_toggled) self.led_enabled_checkbox.stateChanged.connect( self.led_enabled_checkbox_toggled) self.led_over_temp_checkbox.stateChanged.connect( self.led_error_triggers_checkbox_toggled) self.led_over_voltage_checkbox.stateChanged.connect( self.led_error_triggers_checkbox_toggled) self.led_rotor_locked_checkbox.stateChanged.connect( self.led_error_triggers_checkbox_toggled) self.scan_for_ports() def disable_widgets(self): self.set_id_line_edit.setEnabled(False) self.position_slider.setEnabled(False) self.position_offset_slider.setEnabled(False) self.angle_lower_limit_textentry.setEnabled(False) self.angle_upper_limit_textentry.setEnabled(False) self.vin_lower_limit_textentry.setEnabled(False) self.vin_upper_limit_textentry.setEnabled(False) self.temp_limit_textentry.setEnabled(False) self.servo_mode_radio_button.setEnabled(False) self.motor_mode_radio_button.setEnabled(False) self.motor_speed_slider.setEnabled(False) self.torque_enabled_checkbox.setEnabled(False) self.led_enabled_checkbox.setEnabled(False) self.led_over_temp_checkbox.setEnabled(False) self.led_over_voltage_checkbox.setEnabled(False) self.led_rotor_locked_checkbox.setEnabled(False) def enable_widgets(self): self.set_id_line_edit.setEnabled(True) self.position_slider.setEnabled(True) self.position_offset_slider.setEnabled(True) self.angle_lower_limit_textentry.setEnabled(True) self.angle_upper_limit_textentry.setEnabled(True) self.vin_lower_limit_textentry.setEnabled(True) self.vin_upper_limit_textentry.setEnabled(True) self.temp_limit_textentry.setEnabled(True) self.servo_mode_radio_button.setEnabled(True) self.motor_mode_radio_button.setEnabled(True) self.motor_speed_slider.setEnabled(True) self.torque_enabled_checkbox.setEnabled(True) self.led_enabled_checkbox.setEnabled(True) self.led_over_temp_checkbox.setEnabled(True) self.led_over_voltage_checkbox.setEnabled(True) self.led_rotor_locked_checkbox.setEnabled(True) def clear_servo(self): self.active_servo = None @catch_disconnection def set_servo_id(self, id_): if not id_.isdigit(): return self.active_servo = LX16A(int(id_)) self.active_servo.enable_torque() self.position_slider.setValue( int(self.active_servo.get_physical_angle())) self.position_slider_readout.setText( f"{int(self.active_servo.get_physical_angle() * 25 / 6) * 6 / 25:0.2f}°" ) self.position_offset_slider.setValue( int(self.active_servo.get_angle_offset())) self.position_offset_slider_readout.setText( f"{int(self.active_servo.get_angle_offset() * 25 / 6) * 6 / 25:0.2f}°" ) self.angle_lower_limit_textentry.setText( str(int(self.active_servo.get_angle_limits()[0]))) self.angle_upper_limit_textentry.setText( str(int(self.active_servo.get_angle_limits()[1]))) self.vin_lower_limit_textentry.setText( str(self.active_servo.get_vin_limits()[0])) self.vin_upper_limit_textentry.setText( str(self.active_servo.get_vin_limits()[1])) self.temp_limit_textentry.setText( str(self.active_servo.get_temp_limit())) self.motor_speed_slider.setValue(self.active_servo.get_motor_speed( ) if self.active_servo.is_motor_mode() else 0) if self.active_servo.is_motor_mode(): self.motor_mode_radio_button.setChecked(True) else: self.servo_mode_radio_button.setChecked(True) self.motor_speed_slider.setEnabled(self.active_servo.is_motor_mode()) self.torque_enabled_checkbox.setChecked( self.active_servo.is_torque_enabled()) self.led_enabled_checkbox.setChecked( self.active_servo.is_led_power_on()) self.led_over_temp_checkbox.setChecked( self.active_servo.get_led_error_triggers()[0]) self.led_over_voltage_checkbox.setChecked( self.active_servo.get_led_error_triggers()[1]) self.led_rotor_locked_checkbox.setChecked( self.active_servo.get_led_error_triggers()[2]) @catch_disconnection def scan_for_servos(self, port): self.setCursor(Qt.CursorShape.WaitCursor) LX16A.initialize(port) self.id_selection_box.clear() for i in range(0, 254): try: servo = LX16A(i) self.id_selection_box.addItem(str(i)) except: pass self.setCursor(Qt.CursorShape.ArrowCursor) @catch_disconnection def scan_for_ports(self): ports = serial.tools.list_ports.comports() for port in ports: self.port_selection_box.addItem(port.device) @catch_disconnection def update_readouts(self): if self.active_servo is None: return try: self.physical_position_readout.setText( f"{self.active_servo.get_physical_angle():0.2f}°") self.temperature_readout.setText( f"{self.active_servo.get_temp()} °C") self.voltage_readout.setText( f"{self.active_servo.get_vin() / 1000} V") except (ServoTimeoutError, ServoChecksumError): pass @catch_disconnection def id_updated(self): new_id = self.set_id_line_edit.text() try: servo = LX16A(int(new_id)) except ServoTimeoutError: # Meaning this ID is not taken self.active_servo.set_id(int(new_id)) self.id_selection_box.item( self.id_selection_box.currentRow()).setText(new_id) return QMessageBox.warning(None, "Error", "ID already taken") @catch_disconnection def position_slider_updated(self, pos): if float(self.voltage_readout.text()[:-2]) < 5: QMessageBox.warning( None, "Error", "The voltage going through the servo is too low. Is your battery powered on?", ) return self.active_servo.move(pos) self.position_slider_readout.setText( f"{int(pos * 25 / 6) * 6 / 25:0.2f}°") @catch_disconnection def position_offset_slider_updated(self, pos): self.active_servo.set_angle_offset(pos) self.position_offset_slider_readout.setText( f"{int(pos * 25 / 6) * 6 / 25:0.2f}°") @catch_disconnection def angle_lower_limit_updated(self, text): if (QIntValidator(0, 240, self).validate(text, 0) != QIntValidator.State.Acceptable): return if int(text) > int(self.angle_upper_limit_textentry.text()): return self.active_servo.set_angle_limits( int(text), int(self.angle_upper_limit_textentry.text())) @catch_disconnection def angle_upper_limit_updated(self, text): if (QIntValidator(0, 240, self).validate(text, 0) != QIntValidator.State.Acceptable): return if int(text) < int(self.angle_lower_limit_textentry.text()): return self.active_servo.set_angle_limits( int(self.angle_lower_limit_textentry.text()), int(text)) @catch_disconnection def vin_lower_limit_updated(self, text): if (QIntValidator(4500, 12000, self).validate(text, 0) != QIntValidator.State.Acceptable): return if int(text) > int(self.vin_upper_limit_textentry.text()): return self.active_servo.set_vin_limits( int(text), int(self.vin_upper_limit_textentry.text())) @catch_disconnection def vin_upper_limit_updated(self, text): if (QIntValidator(4500, 12000, self).validate(text, 0) != QIntValidator.State.Acceptable): return if int(text) < int(self.vin_lower_limit_textentry.text()): return self.active_servo.set_vin_limits( int(self.vin_lower_limit_textentry.text()), int(text)) @catch_disconnection def temp_limit_updated(self, text): if (QIntValidator(50, 100, self).validate(text, 0) != QIntValidator.State.Acceptable): return self.active_servo.set_temp_limit(int(text)) @catch_disconnection def servo_mode_radio_button_toggled(self, checked): if checked: self.active_servo.servo_mode() self.motor_speed_slider.setEnabled(False) self.position_slider.setEnabled(True) self.position_offset_slider.setEnabled(True) else: self.active_servo.motor_mode(int(self.motor_speed_slider.value())) self.motor_speed_slider.setEnabled(True) self.position_slider.setEnabled(False) self.position_offset_slider.setEnabled(False) @catch_disconnection def motor_mode_radio_button_toggled(self, checked): if checked: self.active_servo.motor_mode(int(self.motor_speed_slider.value())) self.motor_speed_slider.setEnabled(True) self.position_slider.setEnabled(False) self.position_offset_slider.setEnabled(False) else: self.active_servo.servo_mode() self.motor_speed_slider.setEnabled(False) self.position_slider.setEnabled(True) self.position_offset_slider.setEnabled(True) @catch_disconnection def motor_speed_slider_updated(self, pos): self.active_servo.motor_mode(pos) @catch_disconnection def torque_enabled_checkbox_toggled(self, checked): if checked: self.active_servo.enable_torque() else: self.active_servo.disable_torque() self.position_slider.setEnabled(checked) self.position_offset_slider.setEnabled(checked) self.servo_mode_radio_button.setEnabled(checked) self.motor_mode_radio_button.setEnabled(checked) self.motor_speed_slider.setEnabled(checked) @catch_disconnection def led_enabled_checkbox_toggled(self, checked): if checked: self.active_servo.led_power_on() else: self.active_servo.led_power_off() @catch_disconnection def led_error_triggers_checkbox_toggled(self): self.active_servo.set_led_error_triggers( self.led_over_voltage_checkbox.isChecked(), self.led_over_temp_checkbox.isChecked(), self.led_rotor_locked_checkbox.isChecked(), ) @catch_disconnection def port_refresh_button_clicked(self, value): self.id_selection_box_refresh_button.setEnabled(False) self.disable_widgets() self.port_selection_box.clear() self.id_selection_box.clear() self.scan_for_ports() @catch_disconnection def id_refresh_button_clicked(self, value): self.disable_widgets() self.id_selection_box.clear() self.scan_for_servos(self.port_selection_box.currentText()) @catch_disconnection def port_selection_box_changed(self, text): if text == "": return self.id_selection_box_refresh_button.setEnabled(True) self.disable_widgets() self.id_selection_box.clear() self.clear_servo() self.scan_for_servos(text) @catch_disconnection def id_selection_box_changed(self, text): if text == "": return self.enable_widgets() self.set_servo_id(text)
def questionBankPageUI(self): layout = QFormLayout() subLayout = QHBoxLayout() self.questionBankPage.questionList = QListWidget() self.questionBankPage.questionList.currentRowChanged.connect( self.displayQuestionOnQuestionBankPage) self.questionBankPage.questionTextDisplay = QLabel() self.questionBankPage.questionTextDisplay.setFixedSize(500, 100) self.questionBankPage.questionAnswersList = QListWidget() self.questionBankPage.definedCorrectAnswerDisplay = QLabel() self.questionBankPage.definedCorrectAnswerDisplay.setFixedSize(50, 10) self.questionBankPage.questionCodeParserDisplay = QLabel() self.questionBankPage.questionCodeParserDisplay.setFixedSize(100, 50) subLayout.addWidget(self.questionBankPage.questionList) subLayout.addWidget(self.questionBankPage.questionTextDisplay) subLayout.addWidget(self.questionBankPage.questionAnswersList) subLayout.addWidget(self.questionBankPage.definedCorrectAnswerDisplay) subLayout.addWidget(self.questionBankPage.questionCodeParserDisplay) layout.addRow(subLayout) self.questionBankPage.newQuestionTitle = QLineEdit() self.questionBankPage.newQuestionContent = QPlainTextEdit() layout.addRow(self.questionBankPage.newQuestionTitle, self.questionBankPage.newQuestionContent) self.questionBankPage.newQuestionAnswerInput = QLineEdit() self.questionBankPage.newQuestionAnswerList = QListWidget() layout.addRow(self.questionBankPage.newQuestionAnswerInput, self.questionBankPage.newQuestionAnswerList) colorLayout = QFormLayout() colorButtonGroup = QButtonGroup(self.questionBankPage) self.questionBankPage.yellowRadio = QRadioButton() self.questionBankPage.blueRadio = QRadioButton() self.questionBankPage.redRadio = QRadioButton() self.questionBankPage.yellowRadio.toggled.connect( self.colorRadioToggle) self.questionBankPage.blueRadio.toggled.connect(self.colorRadioToggle) self.questionBankPage.redRadio.toggled.connect(self.colorRadioToggle) colorButtonGroup.addButton(self.questionBankPage.yellowRadio) colorButtonGroup.addButton(self.questionBankPage.blueRadio) colorButtonGroup.addButton(self.questionBankPage.redRadio) colorLayout.addRow("Yellow", self.questionBankPage.yellowRadio) colorLayout.addRow("Blue", self.questionBankPage.blueRadio) colorLayout.addRow("Red", self.questionBankPage.redRadio) combLayout = QHBoxLayout() combLayout.addLayout(colorLayout) layout.addRow(combLayout) self.questionBankPage.definedNewCorrectAnswerDisplay = QLabel() layout.addRow(self.questionBankPage.definedNewCorrectAnswerDisplay) self.questionBankPage.defineCorrectAnswerButton = QPushButton( "&Define Correct Answer") self.questionBankPage.defineCorrectAnswerButton.clicked.connect( self.defineCorrectAnswer) self.questionBankPage.submitNewAnswerButton = QPushButton( "Submit &Answer") self.questionBankPage.submitNewAnswerButton.clicked.connect( self.submitNewAnswer) layout.addRow(self.questionBankPage.defineCorrectAnswerButton, self.questionBankPage.submitNewAnswerButton) self.questionBankPage.submitNewQuestionButton = QPushButton( "Submit New &Question") self.questionBankPage.submitNewQuestionButton.clicked.connect( self.submitNewQuestion) layout.addRow(self.questionBankPage.submitNewQuestionButton) self.questionBankPage.backButton = QPushButton("&Back") self.questionBankPage.backButton.clicked.connect( self.goTo_FacilStartPage) self.questionBankPage.refreshButton = QPushButton("&Refresh") self.questionBankPage.refreshButton.clicked.connect( self.goTo_QuestionBankPage) layout.addRow(self.questionBankPage.backButton, self.questionBankPage.refreshButton) self.questionBankPage.setLayout(layout)
def __init__(self): super().__init__() self.setWindowTitle("📸 Random Image Tools V1.2 🔨") self.image_list = [] # ToDo: Add a "rename?" flag. Like rename image files # to store the directory path for later use self.directory_path_name = "/" # Set up the layouts layer_one = QHBoxLayout() # Select a folder, selected directory layer_one_and_a_half = QHBoxLayout() # Selected directory contents layer_two = QHBoxLayout() # Second line of buttons layer_two_vertical_one = QVBoxLayout() # Store the first column w/checkbox and "Convert" layer_two_vertical_two = QVBoxLayout() # Store the second column w/checkbox and "Open in File Browser" layer_three = QHBoxLayout() # Conversion process state vertical_layout_parent = QVBoxLayout() # Parent widget widget = QWidget() # Displays selected directory self.directory_label = QLabel() self.directory_label.setText("Directory to be worked on will show here ") self.directory_label.show() # Displays "Select folder" button self.select_a_folder_button = QPushButton() self.select_a_folder_button.setText("Select a folder:") self.select_a_folder_button.clicked.connect(self.select_folder_prompt) self.select_a_folder_button.show() # Displays the image contents of the selected folder self.image_paths_list_widget = QListWidget() self.image_paths_list_widget.show() # Displays button to initiate image conversion self.convert_to_png_button = QPushButton() self.convert_to_png_button.setText("Convert to PNG") self.convert_to_png_button.clicked.connect(self.convert_folder_to_png) self.convert_to_png_button.show() # Check boxes for "Create new folder for PNGs" and "Delete original files after converting" self.create_new_folder_checkbox = QCheckBox() self.create_new_folder_checkbox.setText("Create new folder to store converted PNG's?") self.create_new_folder_checkbox.show() self.delete_original_files_checkbox = QCheckBox() self.delete_original_files_checkbox.setText("Delete original files after converting them to PNG?") self.create_new_folder_checkbox.show() # Displays button to open selected directory in the file browser self.show_folder_button = QPushButton() self.show_folder_button.setText("Open selected folder in file browser") self.show_folder_button.clicked.connect(self.open_folder) self.show_folder_button.show() # Displays label when conversion is finished, and the corresponding progress bar self.conversion_finished_or_error_label = QLabel() self.conversion_finished_or_error_label.setText("👀 waiting for you to press \"Convert to PNG\" ") # Put the find folder button and folder selected button together layer_one.addWidget(self.select_a_folder_button) layer_one.addWidget(self.directory_label) # Image paths of selected folder layer_one_and_a_half.addWidget(self.image_paths_list_widget) # Put the convert button and open-in-finder button together layer_two_vertical_one.addWidget(self.convert_to_png_button) layer_two_vertical_one.addWidget(self.delete_original_files_checkbox) layer_two.addLayout(layer_two_vertical_one) layer_two_vertical_two.addWidget(self.show_folder_button) layer_two_vertical_two.addWidget(self.create_new_folder_checkbox) layer_two.addLayout(layer_two_vertical_two) # Label and progress bar layer_three.addWidget(self.conversion_finished_or_error_label) layer_three.setAlignment(Qt.AlignmentFlag.AlignHCenter) # Put the "convert to png" button beneath vertical_layout_parent.addLayout(layer_one) vertical_layout_parent.addLayout(layer_one_and_a_half) vertical_layout_parent.addLayout(layer_two) vertical_layout_parent.addLayout(layer_three) widget.setLayout(vertical_layout_parent) self.setCentralWidget(widget)
class Ui_TrainPanel(object): def setupUi(self, TrainPanel): self.parent = TrainPanel self.mainLayout = QHBoxLayout(TrainPanel) self.bigFont = QLabel().font() self.bigFont.setPointSize(13) self.actionsLayout = QHBoxLayout(TrainPanel) # self.checkRecording = QCheckBox(TrainPanel) self.calibrateButton = QPushButton("Calibrate", parent=TrainPanel) self.calibrateButton.setFont(self.bigFont) self.calibrateButton.setStyleSheet(CustomQStyles.buttonStyle) self.calibrateButton.setMinimumHeight(50) self.calibrateButton.setMaximumWidth(170) self.calibrateButton.setMinimumWidth(120) self.sessionButton = QPushButton("Session", parent=TrainPanel) self.sessionButton.setFont(self.bigFont) self.sessionButton.setStyleSheet(CustomQStyles.outlineButtonStyle) self.sessionButton.setMinimumHeight(50) self.sessionButton.setMaximumWidth(170) self.sessionButton.setMinimumWidth(120) self.listFiles = QListWidget(TrainPanel) self.listFiles.setFont(self.bigFont) self.label = QLabel('or select', parent=TrainPanel) self.subjectLayout = QVBoxLayout(TrainPanel) print("init") self.box1 = QGroupBox(parent=TrainPanel) self.box2 = QGroupBox(parent=TrainPanel) self.wizard = CalibrateWizard(parent=TrainPanel) self.setPatientsBox(TrainPanel) # right panel self.setActionsBox(TrainPanel) # left panel self.mainLayout.addWidget(self.box1, stretch=2) self.mainLayout.addWidget(self.box2, stretch=3) # self.mainLayout.setAlignment(self.box2, Qt.Alignment.AlignCenter) # Display progress bar, checkbox - to record new gestures or not, start train def setActionsBox(self, TrainPanel): hLayout = QVBoxLayout() hLayout.addWidget(self.calibrateButton) hLayout.addWidget(self.sessionButton) hLayout.setAlignment(self.calibrateButton, Qt.Alignment.AlignCenter) hLayout.setAlignment(self.sessionButton, Qt.Alignment.AlignCenter) self.box2.setLayout(hLayout) # Display list of subjects, or new subject def setPatientsBox(self, TrainPanel): # Button to create new patient self.addPatient = QPushButton('Create Patient') self.addPatient.setFixedSize(120, 35) self.addPatient.setStyleSheet(CustomQStyles.outlineButtonStyle) self.label.setSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Expanding) self.label.setAlignment(QtCore.Qt.Alignment.AlignCenter) self.loadPatientList() self.listFiles.setStyleSheet(CustomQStyles.listStyle) self.listFiles.setFocusPolicy(Qt.FocusPolicy.NoFocus) self.subjectLayout.addWidget(self.addPatient) self.subjectLayout.setAlignment(self.addPatient, Qt.Alignment.AlignCenter) self.subjectLayout.addWidget(self.label) self.subjectLayout.addWidget(self.listFiles) self.box1.setLayout(self.subjectLayout) def loadPatientList(self): self.listFiles.clear() self.parent.patients.clear() files = [ f for f in listdir(PATIENTS_PATH) if isfile(join(PATIENTS_PATH, f)) ] for x, ind in zip(files, range(0, len(files))): item = QListWidgetItem(x.split('.')[0]) item.setTextAlignment(Qt.Alignment.AlignHCenter) self.listFiles.addItem(item) with open(PATIENTS_PATH + x, 'r') as f: person_dict = json.load(f) patient = Patient(person_dict['Name'], person_dict['Age'], person_dict['Exercises']) self.parent.patients.append(patient) print(self.parent.patients) def deleteItemsOfLayout(self, layout): if layout is not None: while layout.count(): item = layout.takeAt(0) widget = item.widget() if widget is not None: widget.setParent(None) else: self.deleteItemsOfLayout(item.layout())