def removeRows(self, row, count, parent_index): parent_node = parent_index.internalPointer() if not isinstance( row, int): MessageBox("Behavior Tree Model removeRows 'row' must be of type 'int', is of type: ", type(row)) return False if not isinstance(count, int): MessageBox("Behavior Tree Model removeRows 'count' must be of type 'int', is of type: ", type(count)) return False if row < 0: MessageBox("Behavior Tree Model removeRows 'row' must be >= 0, is: ", row) return False if count <= 0: MessageBox("Behavior Tree Model removeRows 'count' must be > 0, is: ", count) return False self.beginRemoveRows(parent_index, row, row+count-1) for i in list(range(count)): parent_node.removeChild(row) self.endRemoveRows()
def insertChild(self, parent_index, child_type, insert_row = None): parent_node = parent_index.internalPointer() if insert_row is None: insert_row = parent_index.internalPointer().childCount() if insert_row is not False: self.beginInsertRows(parent_index, insert_row, insert_row) if child_type == typ.SEQUENCE_NODE : parent_node.insertChild(insert_row, SequenceNode()) elif child_type == typ.SELECTOR_NODE : parent_node.insertChild(insert_row, SelectorNode()) elif child_type == typ.WHILE_NODE : parent_node.insertChild(insert_row, WhileNode()) elif child_type == typ.SET_NODE : parent_node.insertChild(insert_row, SetNode()) elif child_type == typ.WAIT_TIME_NODE : parent_node.insertChild(insert_row, WaitTimeNode()) elif child_type == typ.SUCCESS_NODE : parent_node.insertChild(insert_row, SuccessNode()) elif child_type == typ.FAILURE_NODE : parent_node.insertChild(insert_row, FailureNode()) else: MessageBox('Attempting to insert unknown node of type', child_type) self.endInsertRows() new_child_index = self.index(insert_row, 0, parent_index) #Behavior tree to d_out link if child_type == typ.SET_NODE: for node in self._tool_nodes: if node.typeInfo() in [typ.D_OUT_NODE]: new_child_index.internalPointer().addNode(node) return new_child_index
def test_DeviceIconEditor(qtbot, open_window, tool_model): editor1 = open_window(DeviceIconEditor) editor2 = open_window(DeviceIconEditor) editor1.setModel(tool_model) editor2.setModel(tool_model) for index in tool_model.indexesOfType(typ.DEVICE_ICON_NODE): node = index.internalPointer() editor1.setSelection(index) editor2.setSelection(index) assert editor1.isVisible() assert editor2.isVisible() assert node.x == editor1.ui_x.value() assert node.y == editor1.ui_y.value() assert node.scale == editor1.ui_scale.value() assert node.rotation == editor1.ui_rotation.value() assert node.hasText == editor1.ui_has_text.isChecked() assert node.textX == editor1.ui_text_x.value() assert node.textY == editor1.ui_text_y.value() assert node.fontSize == editor1.ui_font_size.value() if TestingFlags.ENABLE_MANUAL_TESTING: MessageBox("Device Icon Editor Testing") qtbot.stopForInteraction()
def test_ToolEditor(qtbot, open_window, tool_model): editor = open_window(ToolEditor) editor.setModel(tool_model) editor.resize(1000,600) if TestingFlags.ENABLE_MANUAL_TESTING: MessageBox("Tool Editor Testing") qtbot.stopForInteraction()
def loadAttrs(self, data): try: #Get all the attributes of the node attrs = iter(self.attrs().items()) for key, value in attrs: if key in data: setattr(self, key, data[key]) except Exception as e: MessageBox("Error setting attribute", e, key, value)
def test_addRemoveBits(qtbot, open_window, good_data): table_model = DigitalStateTableModel(allow_is_used=True) table_model.setHalPins(good_data[0]) table_model.setStates(good_data[1]) table_model.setIsUsed(good_data[2]) table_view = open_window(DigitalStateTableView) table_view.setWindowTitle("Digital State Table View") table_view.setModel(table_model) table_view.resize(table_view.sizeHint() * 2) assert table_view.isVisible() starting_rows = table_model.rowCount() #Add One table_view.addBit() qtbot.wait(TestingFlags.TEST_WAIT_SHORT) assert starting_rows << 1 == table_model.rowCount() #Remove One table_view.removeBit() qtbot.wait(TestingFlags.TEST_WAIT_SHORT) assert starting_rows == table_model.rowCount() #Remove Another table_view.removeBit() qtbot.wait(TestingFlags.TEST_WAIT_SHORT) assert starting_rows >> 1 == table_model.rowCount() #Remove One Too Many! with pytest.raises(ValueError): table_view.removeBit() qtbot.wait(TestingFlags.TEST_WAIT_SHORT) #Add One table_view.addBit() qtbot.wait(TestingFlags.TEST_WAIT_SHORT) assert starting_rows == table_model.rowCount() table_model.setAllowedHalPins( ['None', 'pin_1', 'pin_2', 'pin_33', 'pin_4']) table_view.setHalPin(0, 'pin_1') table_view.setHalPin(1, 'pin_2') menu = table_view.generateContextMenu() assert isinstance(menu, QtWidgets.QMenu) if TestingFlags.ENABLE_MANUAL_TESTING: MessageBox( "Digital State Table Manual Testing", "Test that the GUI Name and is Used can be edited\n Row 0 is used must be True\n Right click add and remove bits" ) qtbot.stopForInteraction()
def loadJSON(self, json): try: if json['type_info'] == 'root': self._root_index = self.createIndex(0, 0, self._root_node) self._root_index.internalPointer().loadAttrs(json) for child in json['children']: index = self.insertChild(self._root_index, child['type_info']) index.internalPointer().loadAttrs(child) self._recurseJSON(index, child) except Exception as e: MessageBox("Failed to behavior from JSON", e) return False
def setData(self, index, value, role = QtCore.Qt.EditRole): if role == QtCore.Qt.EditRole: row = index.row() col = index.column() num_rows = len(self._data) if col == self.greaterThanColumn(): if row == 0: MessageBox("Row 0 greater_than must be 'None'", 'Attempting to set to: ', value) return False if row < num_rows-1 and row > 0: if value >= self._data[row+1][col]: MessageBox('Greater than value must be less than next index','Next index: ', self._data[row+1][col]) return False if row > 1: if value <= self._data[row-1][col]: MessageBox('Greater than value must be more than previous index','Previous index: ', self._data[row-1][col]) return False self._data[row][col] = float(value) self.dataChanged.emit(index, index) return True if col == self.nameColumn(): self._data[row][col] = str(value) self.dataChanged.emit(index, index) return True MessageBox("Failed editing analog state table data.", 'Attempted to set index: ', index, '\nto: ', value) return False
def test_selectDevice(qtbot, open_window, tool_model): device_indexes = tool_model.indexesOfType(typ.DEVICE_NODE) wid = open_window(SystemManualView) wid.setModel(tool_model) wid.setSelection(device_indexes[0]) assert wid.isVisible() for index in device_indexes: wid.setSelection(index) qtbot.wait(TestingFlags.TEST_WAIT_LONG) if TestingFlags.ENABLE_MANUAL_TESTING: MessageBox("Should have selected the devices for this tool.") qtbot.stopForInteraction()
def test_DeviceEditor(qtbot, open_window, tool_model): editor1 = open_window(DeviceEditor) editor2 = open_window(DeviceEditor) editor1.setModel(tool_model) editor2.setModel(tool_model) for index in tool_model.indexesOfType(typ.DEVICE_NODE): editor1.setSelection(index) editor2.setSelection(index) assert editor1.isVisible() assert editor2.isVisible() if TestingFlags.ENABLE_MANUAL_TESTING: MessageBox("Device Editor Testing") qtbot.stopForInteraction()
def setNumberOfStates(self, num_states): if not num_states in [1,2,3,4]: MessageBox('Invalid number of states, must be 1,2,3 or 4', num_states) return False if num_states == self.numberOfStates(): return True current_greater_than_col = [inner[self.greaterThanColumn()] for inner in self._data] current_name_col = [inner[self.nameColumn()] for inner in self._data] current_max = 0.0 self.beginResetModel() if num_states == 1: new_tbl = [[0]] elif num_states == 2: new_tbl = [[0],[1]] elif num_states == 3: new_tbl = [[0],[1],[2]] elif num_states == 4: new_tbl = [[0],[1],[2],[3]] #Add the name and is used column from the old data if it exits for i, row in enumerate(new_tbl): if i == 0: row.append(None) row.append(current_name_col[i]) elif i < len(current_name_col): current_max = current_greater_than_col[i] row.append(current_greater_than_col[i]) row.append(current_name_col[i]) else: current_max += 1.0 row.append(current_max) row.append('GUI Name') self._data = new_tbl self._number_of_states = num_states self.endResetModel() return True
def test_selectSystem(qtbot, open_window, tool_model): system_indexes = tool_model.indexesOfType(typ.SYSTEM_NODE) wid = open_window(SystemManualView) wid.setModel(tool_model) wid.setSelection(system_indexes[0]) assert wid.isVisible() for index in system_indexes: wid.setSelection(index) assert wid.isVisible() qtbot.wait(TestingFlags.TEST_WAIT_LONG) if TestingFlags.ENABLE_MANUAL_TESTING: MessageBox("For each tool it should cycle through each system.") qtbot.stopForInteraction()
def test_noIsUsed(qtbot, open_window, good_data): table_model = DigitalStateTableModel(allow_is_used=False) table_model.setHalPins(good_data[0]) table_model.setStates(good_data[1]) table_model.setAllowedHalPins( ['None', 'pin_1', 'pin_2', 'pin_33', 'pin_4']) table_view = open_window(DigitalStateTableView) table_view.setWindowTitle("Digital State Table View") table_view.setModel(table_model) table_view.resize(table_view.sizeHint() * 2) assert table_view.isVisible() if TestingFlags.ENABLE_MANUAL_TESTING: MessageBox("Digital State Table Manual Testing", "No is used column") qtbot.stopForInteraction()
def test_twoOpen(qtbot, open_window, tool_model): wid1 = open_window(DeviceManualView) wid2 = open_window(DeviceManualView) wid1.setModel(tool_model) wid2.setModel(tool_model) indexes = tool_model.indexesOfType(typ.DEVICE_NODE) index = indexes[0] wid1.setSelection(index) wid2.setSelection(index) assert wid1.isVisible() assert wid2.isVisible() indexes = tool_model.indexesOfType(typ.D_IN_NODE) d_in = indexes[0] indexes = tool_model.indexesOfType(typ.A_IN_NODE) a_in = indexes[0] indexes = tool_model.indexesOfType(typ.BOOL_VAR_NODE) bool_var = indexes[0] qtbot.wait(TestingFlags.TEST_WAIT_LONG) tool_model.setData(d_in.siblingAtColumn(col.HAL_VALUE), True) tool_model.setData(a_in.siblingAtColumn(col.HAL_VALUE), .11) qtbot.wait(TestingFlags.TEST_WAIT_LONG) tool_model.setData(d_in.siblingAtColumn(col.HAL_VALUE), False) tool_model.setData(a_in.siblingAtColumn(col.HAL_VALUE), .22) qtbot.wait(TestingFlags.TEST_WAIT_LONG) tool_model.setData(d_in.siblingAtColumn(col.HAL_VALUE), True) tool_model.setData(a_in.siblingAtColumn(col.HAL_VALUE), .33) qtbot.wait(TestingFlags.TEST_WAIT_LONG) tool_model.setData(bool_var.siblingAtColumn(col.VALUE), False) qtbot.wait(TestingFlags.TEST_WAIT_LONG) tool_model.setData(bool_var.siblingAtColumn(col.OFF_ENABLE), False) qtbot.wait(TestingFlags.TEST_WAIT_LONG) tool_model.setData(bool_var.siblingAtColumn(col.OFF_ENABLE), True) qtbot.wait(TestingFlags.TEST_WAIT_LONG) tool_model.setData(bool_var.siblingAtColumn(col.ENABLE_MANUAL), False) if TestingFlags.ENABLE_MANUAL_TESTING is True: MessageBox("Test with two windows open") qtbot.stopForInteraction()
def test_SystemEditor(qtbot, open_window, tool_model): editor1 = open_window(SystemEditor) editor2 = open_window(SystemEditor) editor1.setModel(tool_model) editor2.setModel(tool_model) for index in tool_model.indexesOfType(typ.SYSTEM_NODE): node = index.internalPointer() editor1.setSelection(index) editor2.setSelection(index) qtbot.mouseClick(editor1.ui_background_svg, QtCore.Qt.LeftButton) assert editor1.isVisible() assert editor2.isVisible() assert node.backgroundSVG == editor1.ui_background_svg.text() if TestingFlags.ENABLE_MANUAL_TESTING: MessageBox("System Editor Manual Testing") qtbot.stopForInteraction()
def test_BoolVarEditor(qtbot, open_window, tool_model): editor1 = open_window(BoolVarEditor) editor2 = open_window(BoolVarEditor) editor1.setModel(tool_model) editor2.setModel(tool_model) for index in tool_model.indexesOfType(typ.BOOL_VAR_NODE): editor1.setSelection(index) editor2.setSelection(index) assert editor1.isVisible() assert editor2.isVisible() assert index.internalPointer().offName == editor1.ui_off_name.text() assert index.internalPointer().onName == editor1.ui_on_name.text() assert index.internalPointer().enableManual == editor1.ui_enable_manual.isChecked() assert index.internalPointer().viewOnly == editor1.ui_view_only.isChecked() if TestingFlags.ENABLE_MANUAL_TESTING: MessageBox("Bool Var Editor Testing") qtbot.stopForInteraction()
def test_NodeEditor(qtbot, open_window, tool_model): editor1 = open_window(NodeEditor) editor2 = open_window(NodeEditor) editor1.setModel(tool_model) editor2.setModel(tool_model) for index in tool_model.indexesOfType(typ.DEVICE_NODE): editor1.setSelection(index) editor2.setSelection(index) qtbot.mouseClick(editor1.ui_name, QtCore.Qt.LeftButton) qtbot.mouseClick(editor1.ui_description, QtCore.Qt.LeftButton) assert editor1.isVisible() assert editor2.isVisible() assert index.internalPointer().typeInfo() == editor1.ui_type.text() assert index.internalPointer().name == editor1.ui_name.text() assert index.internalPointer().description == editor1.ui_description.text() if TestingFlags.ENABLE_MANUAL_TESTING: MessageBox("Node Editor Manual Testing") qtbot.stopForInteraction()
def test_DigitalOutputEditor(qtbot, open_window, tool_model): editor1 = open_window(DigitalOutputEditor) editor2 = open_window(DigitalOutputEditor) editor1.setModel(tool_model) editor2.setModel(tool_model) for index in tool_model.indexesOfType(typ.D_OUT_NODE): node = index.internalPointer() editor1.setSelection(index) editor2.setSelection(index) assert editor1.isVisible() assert editor2.isVisible() assert node.halPin == editor1.ui_hal_pin.currentText() assert node.offName == editor1.ui_off_name.text() assert node.onName == editor1.ui_on_name.text() assert node.value() == editor1.ui_value.isEnabled() if TestingFlags.ENABLE_MANUAL_TESTING: MessageBox("Digital Output Editor Testing") qtbot.stopForInteraction()
def test_AnalogInputEditor(qtbot, open_window, tool_model): editor1 = open_window(AnalogInputEditor) editor2 = open_window(AnalogInputEditor) editor1.setModel(tool_model) editor2.setModel(tool_model) for index in tool_model.indexesOfType(typ.A_IN_NODE): editor1.setSelection(index) editor2.setSelection(index) assert editor1.isVisible() assert editor2.isVisible() tool_model.setData(index.siblingAtColumn(col.HAL_PIN), 1) assert index.internalPointer().halPin == editor1.ui_hal_pin.currentText() assert index.internalPointer().value() == editor1.ui_value.value() assert index.internalPointer().units == editor1.ui_units.text() assert index.internalPointer().displayDigits == editor1.ui_display_digits.value() assert index.internalPointer().displayScientific == editor1.ui_display_scientific.isChecked() if TestingFlags.ENABLE_MANUAL_TESTING: MessageBox("Analog Input Editor Testing") qtbot.stopForInteraction()
def test_setLayer(qtbot, open_window, tool_model): device_indexes = tool_model.indexesOfType(typ.DEVICE_NODE) icon_indexes = tool_model.indexesOfType(typ.DEVICE_ICON_NODE) wid = open_window(SystemManualView) wid.setModel(tool_model) assert wid.isVisible() for i, icon_index in enumerate(icon_indexes): node = icon_index.internalPointer() wid.setSelection(icon_index.parent()) for layer in node.layers().names: tool_model.setData(icon_index.siblingAtColumn(col.LAYER), layer) assert tool_model.data(icon_index.siblingAtColumn(col.LAYER), QtCore.Qt.DisplayRole) == layer qtbot.wait(TestingFlags.TEST_WAIT_SHORT) if TestingFlags.ENABLE_MANUAL_TESTING: MessageBox( "For each device it should have cycled through the icon layers.") qtbot.stopForInteraction()
def test_FloatVarEditor(qtbot, open_window, tool_model): editor1 = open_window(FloatVarEditor) editor2 = open_window(FloatVarEditor) editor1.setModel(tool_model) editor2.setModel(tool_model) for index in tool_model.indexesOfType(typ.FLOAT_VAR_NODE): editor1.setSelection(index) editor2.setSelection(index) assert editor1.isVisible() assert editor2.isVisible() assert index.internalPointer().min == editor1.ui_min.value() assert index.internalPointer().max == editor1.ui_max.value() assert index.internalPointer().units == editor1.ui_units.text() assert index.internalPointer().displayDigits == editor1.ui_display_digits.value() assert index.internalPointer().displayScientific == editor1.ui_display_scientific.isChecked() assert index.internalPointer().enableManual == editor1.ui_enable_manual.isChecked() assert index.internalPointer().viewOnly == editor1.ui_view_only.isChecked() if TestingFlags.ENABLE_MANUAL_TESTING: MessageBox("Float Var Editor Testing") qtbot.stopForInteraction()
def excepthook(exc_type, exc_value, exc_tb): tb = "".join(traceback.format_exception(exc_type, exc_value, exc_tb)) MessageBox(tb)
def setDataArray(self, data): ''' in format [ ['state', 'greater_than', 'gui_name' ], [ 0 , None, 'name_a'], [ 1 , 1.11, 'name_b'], [ 2 , 2.34, 'name_c'], [ 3 , 9.99, 'name_d']] ''' data_main = [] #Data validation first try: if data[0] == ['state', 'greater_than','gui_name']: data_main = data[1:] else: MessageBox("Invalid analog state table data, first row must be ['state', 'greater_than', 'gui_name'].", "Row 0:", data[0]) return False num_rows = len(data_main) #Array must be length 2,4,8 or 16 if num_rows <= 0: MessageBox('Invalid number of rows in state data, must have at least 1', 'Analog State Table:', data) return False if num_rows > 4: MessageBox('Invalid number of rows in state data, must have 1-4', 'Analog State Table:', data) return False for i, row in enumerate(data_main): if not len(row) == 3: MessageBox('Must have 3 columns state_index, grater_than, gui_name', row) return False if not row[0] == i: MessageBox('Index column must be 0 or 0,1 or 0,1,2 or 0,1,2,3', row[0]) return False #greater_than column checks if i == 0 and row[self.greaterThanColumn()] != None: MessageBox('State data greater_than row 0 must be None', 'Analog State Table:', data) return False if i == 1: prev_greater_than = row[self.greaterThanColumn()] if i > 1 and prev_greater_than >= row[self.greaterThanColumn()]: MessageBox('State data greater_than must be sequential:', row[self.greaterThanColumn()], 'is not larger then:', prev_greater_than) return False if i > 0 and not isinstance(row[self.greaterThanColumn()], float): MessageBox('State data greater_than must be of type float', row[self.greaterThanColumn()], 'is of type:', type(row[self.greaterThanColumn()])) return False #name column checks if not isinstance(row[self.nameColumn()], str): MessageBox('State data GUI Name must be of type string', row[self.nameColumn()], 'is of type: ', type(row[self.nameColumn()])) return False except Exception as e: MesssageBox('State table data array testing failed', 'Analog State Table: ', data, '\n', e) return False self.setNumberOfStates(num_rows) #Set the data now self.beginResetModel() for i, row in enumerate(data_main): data_main[i][0] = int(row[0]) if i > 0: data_main[i][1] = float(row[1]) data_main[i][2] = str(row[2]) self._data = copy.deepcopy(data_main) self.endResetModel() return True
def insertChild(self, parent_index, child_type, insert_row=None): parent_node = parent_index.internalPointer() #allowed_rows = self.allowedInsertRows(parent_index, child_type) if insert_row is None: insert_row = parent_index.internalPointer().childCount() #if not allowed_rows: # msg = "Child of type " + child_type + " cannot be inserted into " + parent_node.typeInfo() # MessageBox(msg) # return False #if preferred_row is None: # insert_row = allowed_rows[-1] #elif preferred_row in allowed_rows: # insert_row = preferred_row #else: # MessageBox("Attempting to insert child in tool model at bad row", "row: ", preferred_row, "allowed rows: ", allowed_rows) # return False if insert_row is not False: self.beginInsertRows(parent_index, insert_row, insert_row) if child_type == typ.TOOL_NODE: parent_node.insertChild(insert_row, ToolNode()) elif child_type == typ.SYSTEM_NODE: parent_node.insertChild(insert_row, SystemNode()) elif child_type == typ.DEVICE_NODE: parent_node.insertChild(insert_row, DeviceNode()) elif child_type == typ.DEVICE_ICON_NODE: parent_node.insertChild(insert_row, DeviceIconNode()) elif child_type == typ.D_IN_NODE: parent_node.insertChild(insert_row, DigitalInputNode()) elif child_type == typ.D_OUT_NODE: parent_node.insertChild(insert_row, DigitalOutputNode()) elif child_type == typ.A_IN_NODE: parent_node.insertChild(insert_row, AnalogInputNode()) elif child_type == typ.A_OUT_NODE: parent_node.insertChild(insert_row, AnalogOutputNode()) elif child_type == typ.BOOL_VAR_NODE: parent_node.insertChild(insert_row, BoolVarNode()) elif child_type == typ.FLOAT_VAR_NODE: parent_node.insertChild(insert_row, FloatVarNode()) else: MessageBox('Attempting to insert unknown node of type', child_type) ''' Add code here to add said child to the behavior tree ''' self.endInsertRows() new_child_index = self.index(insert_row, 0, parent_index) #Add the node to the behavior tree try: device_bt_model = new_child_index.internalPointer().parent( ).behaviorTreeModel() device_bt_model.addNode(new_child_index.internalPointer()) except: pass #for set_index in device_bt_model.indexesOfType(typ.SET_NODE): # print("hmmm - ", new_child_index) # set_index.internalPointer().addNode(new_child_index.internalPointer()) return new_child_index
def fset(self, value): try: self.calibrationTableModel().setDataArray(value) self.updateScaleFactor() except Exception as e: MessageBox("Malformed calibration table data", e, value)