def __init__(self): super().__init__('Dataset - additional parameters', '') g_layout = QGridLayout() self.layout.addLayout(g_layout) self.params = {'target_idx': 0, 'data_type': float, 'delimiter': ','} target_label = CustomLabel('Target index') target_edit = CustomTextBox() target_edit.setValidator(ArithmeticValidator.INT) target_edit.textChanged. \ connect(lambda: self.update_dict('target_idx', target_edit.text())) g_layout.addWidget(target_label, 0, 0) g_layout.addWidget(target_edit, 0, 1) data_type_label = CustomLabel('Data type') data_type_edit = CustomComboBox() data_type_edit.addItems(['float', 'int']) data_type_edit.activated. \ connect(lambda: self.update_dict('data_type', data_type_edit.currentText())) g_layout.addWidget(data_type_label, 1, 0) g_layout.addWidget(data_type_edit, 1, 1) delimiter_label = CustomLabel('Delimiter character') delimiter_edit = CustomTextBox(',') delimiter_edit.textChanged. \ connect(lambda: self.update_dict('delimiter', delimiter_edit.text())) g_layout.addWidget(delimiter_label, 2, 0) g_layout.addWidget(delimiter_edit, 2, 1) self.cancel_btn.clicked.connect(self.reset) self.render_layout()
class EditNodeInputDialog(NeVerDialog): def __init__(self, node_block: NodeBlock): super().__init__(node_block.node.name, "") self.layout = QGridLayout() # Connect node self.node = node_block self.new_in_dim = ','.join(map(str, node_block.in_dim)) self.in_dim_box = CustomTextBox() self.has_edits = False # Build main_layout title_label = CustomLabel("Edit network input") title_label.setStyleSheet(style.NODE_LABEL_STYLE) title_label.setAlignment(Qt.AlignCenter) self.layout.addWidget(title_label, 0, 0, 1, 2) # Input box in_dim_label = CustomLabel("Input shape") in_dim_label.setStyleSheet(style.IN_DIM_LABEL_STYLE) in_dim_label.setAlignment(Qt.AlignRight) self.layout.addWidget(in_dim_label, 1, 0) self.in_dim_box.setText(self.new_in_dim) self.in_dim_box.setValidator(ArithmeticValidator.TENSOR) self.layout.addWidget(self.in_dim_box, 1, 1) if not node_block.is_head: self.in_dim_box.setReadOnly(True) # "Apply" button which saves changes apply_button = CustomButton("Apply") apply_button.clicked.connect(self.save_data) self.layout.addWidget(apply_button, 2, 0) # "Cancel" button which closes the dialog without saving cancel_button = CustomButton("Cancel") cancel_button.clicked.connect(self.close) self.layout.addWidget(cancel_button, 2, 1) self.layout.setColumnStretch(0, 1) self.layout.setColumnStretch(1, 1) self.render_layout() def save_data(self) -> None: """ This method saves the new in_dim, returning it to the caller. """ self.has_edits = True if len(self.in_dim_box.text()) != 0: self.new_in_dim = tuple(map(int, self.in_dim_box.text().split(','))) self.close()
def __init__(self, param_dict: dict, t_name: str): super(Param2levelDialog, self).__init__('Parameters required', '') g_layout = QGridLayout() self.layout.addLayout(g_layout) self.params = {} input_widgets = {} g_layout.addWidget(CustomLabel(t_name, primary=True), 0, 0, 1, 0) count = 1 # Event connection def activation_f(key: str): return lambda: self.update_param(key, input_widgets[key].text()) for name, val in param_dict.items(): input_widgets[name] = CustomTextBox(str(val['value'])) input_widgets[name].setValidator(ArithmeticValidator.FLOAT) g_layout.addWidget(CustomLabel(name), count, 0) g_layout.addWidget(input_widgets[name], count, 1) self.params[name] = val['value'] input_widgets[name].textChanged.connect(activation_f(name)) count += 1 # Buttons self.cancel_btn.clicked.connect(lambda: self.reset(param_dict)) self.render_layout()
def __init__(self): super().__init__('Mixed Verification', '') g_layout = QGridLayout() self.layout.addLayout(g_layout) self.n_neurons = 0 target_label = CustomLabel('Neurons number') target_edit = CustomTextBox() target_edit.textChanged.connect(lambda: self.update_neurons(target_edit.text())) target_edit.setValidator(ArithmeticValidator.INT) g_layout.addWidget(target_label, 0, 0) g_layout.addWidget(target_edit, 0, 1) # Buttons self.cancel_btn.clicked.connect(self.reset) self.render_layout()
def __init__(self, message): super().__init__("", message) # Set title label title_label = CustomLabel("Input required") title_label.setStyleSheet(style.NODE_LABEL_STYLE) title_label.setAlignment(Qt.AlignCenter) # Set message label mess_label = CustomLabel("\n" + self.content + "\n") mess_label.setAlignment(Qt.AlignCenter) # Set input reading self.input = None input_line = CustomTextBox() input_line.setValidator(QRegExpValidator(QRegExp( ArithmeticValidator.TENSOR.regExp().pattern() + "|" + ArithmeticValidator.TENSOR_LIST.regExp().pattern()))) # Add buttons to close the dialog confirm_button = CustomButton("Ok") confirm_button.clicked.connect(self.save_input) cancel_button = CustomButton("Cancel") cancel_button.clicked.connect(self.cancel) buttons = QWidget() buttons_layout = QHBoxLayout() buttons_layout.addWidget(confirm_button) buttons_layout.addWidget(cancel_button) buttons.setLayout(buttons_layout) # Compose widgets self.layout.addWidget(title_label) self.layout.addWidget(mess_label) self.layout.addWidget(input_line) self.layout.addWidget(buttons) self.render_layout()
def __init__(self, node_block: NodeBlock): super().__init__(node_block.node.name, "") self.layout = QGridLayout() # Connect node self.node = node_block self.parameters = dict() self.edited_data = dict() self.has_edits = False # Build main_layout title_label = CustomLabel("Edit parameters") title_label.setStyleSheet(style.NODE_LABEL_STYLE) title_label.setAlignment(Qt.AlignCenter) self.layout.addWidget(title_label, 0, 0, 1, 2) # Input box in_dim_label = CustomLabel("Input") in_dim_label.setStyleSheet(style.IN_DIM_LABEL_STYLE) in_dim_label.setAlignment(Qt.AlignRight) self.layout.addWidget(in_dim_label, 1, 0) in_dim_box = CustomTextBox(','.join(map(str, node_block.in_dim))) in_dim_box.setValidator(ArithmeticValidator.TENSOR) self.layout.addWidget(in_dim_box, 1, 1) self.parameters["in_dim"] = in_dim_box if not node_block.is_head: in_dim_box.setReadOnly(True) # Display parameters if present counter = 2 if node_block.node.param: counter = self.append_node_params(node_block.node, node_block.block_data) # "Apply" button which saves changes apply_button = CustomButton("Apply") apply_button.clicked.connect(self.save_data) self.layout.addWidget(apply_button, counter, 0) # "Cancel" button which closes the dialog without saving cancel_button = CustomButton("Cancel") cancel_button.clicked.connect(self.close) self.layout.addWidget(cancel_button, counter, 1) self.layout.setColumnStretch(0, 1) self.layout.setColumnStretch(1, 1) self.render_layout()
def create_widget_layout(self, widget_dict: dict, cb_f: Callable = None, line_f: Callable = None) -> QHBoxLayout: """ This method sets up the parameters layout by reading the JSON-based dict of params and building the corresponding graphic objects. Parameters ---------- widget_dict : dict The dictionary of widgets to build. cb_f : Callable, optional The activation function for combo boxes. line_f : Callable, optional The activation function for text boxes. Returns ---------- QHBoxLayout The layout with all the widgets loaded. """ widget_layout = QHBoxLayout() left_layout = QGridLayout() left_layout.setAlignment(Qt.AlignTop) counter = 0 for first_level in widget_dict.keys(): sub_key = next(iter(widget_dict[first_level])) if type(widget_dict[first_level][sub_key]) == dict: self.widgets[first_level] = CustomComboBox() for second_level in widget_dict[first_level].keys(): self.widgets[first_level].addItem(second_level) self.widgets[first_level].setCurrentIndex(-1) if cb_f is not None: self.widgets[first_level].activated.connect( cb_f(first_level)) else: if widget_dict[first_level]["type"] == "bool": self.widgets[first_level] = CustomComboBox() self.widgets[first_level].addItems([ str(widget_dict[first_level]["value"]), str(not widget_dict[first_level]["value"]) ]) else: self.widgets[first_level] = CustomTextBox() self.widgets[first_level].setText( str(widget_dict[first_level].get("value", ""))) if line_f is not None: self.widgets[first_level].textChanged.connect( line_f(first_level)) if widget_dict[first_level]["type"] == "int": self.widgets[first_level].setValidator( ArithmeticValidator.INT) elif widget_dict[first_level]["type"] == "float": self.widgets[first_level].setValidator( ArithmeticValidator.FLOAT) elif widget_dict[first_level]["type"] == "tensor" or \ widget_dict[first_level]["type"] == "tuple": self.widgets[first_level].setValidator( ArithmeticValidator.TENSOR) w_label = CustomLabel(first_level) if 'optional' not in widget_dict[first_level].keys(): w_label.setText(first_level + '*') w_label.setToolTip(widget_dict[first_level].get("description")) left_layout.addWidget(w_label, counter, 0) left_layout.addWidget(self.widgets[first_level], counter, 1) counter += 1 widget_layout.addLayout(left_layout) return widget_layout
def show_layout(self, name: str) -> None: """ This method displays a grid layout initialized by the dictionary of parameters and default values. Parameters ---------- name : str The name of the main parameter to which the dictionary is related. """ title = CustomLabel(name.replace(':', ': ')) title.setAlignment(Qt.AlignCenter) self.grid_layout.addWidget(title, 0, 0, 1, 2) widgets_2level = dict() count = 1 for k, v in self.gui_params[name].items(): # Activation functions for dynamic widgets def activation_combo(super_key: str, key: str): return lambda: self.update_dict_value( name, key, widgets_2level[f"{super_key}:{key}"][1]. currentText()) def activation_line(super_key: str, key: str): return lambda: self.update_dict_value( name, key, widgets_2level[f"{super_key}:{key}"][1].text()) w_label = CustomLabel(k) w_label.setToolTip(v.get("description")) if v["type"] == "bool": cb = CustomComboBox() cb.addItems([str(v["value"]), str(not v["value"])]) widgets_2level[f"{name}:{k}"] = (w_label, cb) widgets_2level[f"{name}:{k}"][1].activated.connect( activation_combo(name, k)) elif "allowed" in v.keys(): cb = CustomComboBox() cb.addItems(v["allowed"]) widgets_2level[f"{name}:{k}"] = (w_label, cb) widgets_2level[f"{name}:{k}"][1].activated.connect( activation_combo(name, k)) else: widgets_2level[f"{name}:{k}"] = (w_label, CustomTextBox(str( v["value"]))) widgets_2level[f"{name}:{k}"][1].textChanged.connect( activation_line(name, k)) if v["type"] == "int": widgets_2level[f"{name}:{k}"][1].setValidator( ArithmeticValidator.INT) elif v["type"] == "float": widgets_2level[f"{name}:{k}"][1].setValidator( ArithmeticValidator.FLOAT) elif v["type"] == "tensor" or \ v["type"] == "tuple": widgets_2level[f"{name}:{k}"][1].setValidator( ArithmeticValidator.TENSOR) self.grid_layout.addWidget(widgets_2level[f"{name}:{k}"][0], count, 0) self.grid_layout.addWidget(widgets_2level[f"{name}:{k}"][1], count, 1) count += 1
def append_node_params(self, node: NetworkNode, current_data: dict) -> int: """ This method adds to the dialog layer the editable parameters of the node, and returns the last row counter for the grid main_layout. Attributes ---------- node: NetworkNode The node whose parameters are displayed. current_data: dict The node current data. Returns ---------- int The last row counter. """ # Init column counter counter = 2 # Display parameter labels for param, value in node.param.items(): param_label = CustomLabel(param) if node.param[param]["editable"] == "false": param_label.setStyleSheet(style.UNEDITABLE_PARAM_LABEL_STYLE) param_label.setAlignment(Qt.AlignRight) # Set the tooltip of the input with the description param_label.setToolTip("<" + value["type"] + ">: " + value["description"]) self.layout.addWidget(param_label, counter, 0) # Display parameter values if value["type"] == "boolean": line = CustomComboBox() line.addItem("True") line.addItem("False") line.setPlaceholderText(str(current_data[param])) else: line = CustomTextBox() if node.param[param]["editable"] == "false": line.setReadOnly(True) if isinstance(current_data[param], Tensor) or isinstance(current_data[param], np.ndarray): line.setText("(" + ','.join(map(str, current_data[param].shape)) + ")") elif isinstance(current_data[param], tuple): line.setText(','.join(map(str, current_data[param]))) else: line.setText(str(current_data[param])) # Set type validator validator = None if value["type"] == "int": validator = ArithmeticValidator.INT elif value["type"] == "float": validator = ArithmeticValidator.FLOAT elif value["type"] == "Tensor" or value["type"] == "list of ints": validator = ArithmeticValidator.TENSOR elif value["type"] == "list of Tensors": validator = ArithmeticValidator.TENSOR_LIST line.setValidator(validator) if node.param[param]["editable"] == "false": line.setStyleSheet(style.UNEDITABLE_VALUE_LABEL_STYLE) self.layout.addWidget(line, counter, 1) # Keep trace of CustomTextBox objects self.parameters[param] = line counter += 1 return counter
def __init__(self, property_block: PropertyBlock): super().__init__("Edit property", "") self.property_block = property_block self.has_edits = False self.property_list = [] self.viewer = CustomTextArea() self.viewer.setReadOnly(True) self.viewer.setFixedHeight(100) grid = QGridLayout() # Build main_layout title_label = CustomLabel("Polyhedral property") title_label.setStyleSheet(style.NODE_LABEL_STYLE) title_label.setAlignment(Qt.AlignCenter) grid.addWidget(title_label, 0, 0, 1, 3) # Labels var_label = CustomLabel("Variable") var_label.setStyleSheet(style.IN_DIM_LABEL_STYLE) var_label.setAlignment(Qt.AlignRight) grid.addWidget(var_label, 1, 0) relop_label = CustomLabel("Operator") relop_label.setStyleSheet(style.IN_DIM_LABEL_STYLE) relop_label.setAlignment(Qt.AlignCenter) grid.addWidget(relop_label, 1, 1) value_label = CustomLabel("Value") value_label.setStyleSheet(style.IN_DIM_LABEL_STYLE) value_label.setAlignment(Qt.AlignLeft) grid.addWidget(value_label, 1, 2) self.var_cb = CustomComboBox() for v in property_block.variables: self.var_cb.addItem(v) grid.addWidget(self.var_cb, 2, 0) self.op_cb = CustomComboBox() operators = ["<=", "<", ">", ">="] for o in operators: self.op_cb.addItem(o) grid.addWidget(self.op_cb, 2, 1) self.val = CustomTextBox() self.val.setValidator(ArithmeticValidator.FLOAT) grid.addWidget(self.val, 2, 2) # "Add" button which adds the constraint add_button = CustomButton("Add") add_button.clicked.connect( lambda: self.add_entry(str(self.var_cb.currentText()), str(self.op_cb.currentText()), self.val.text())) grid.addWidget(add_button, 3, 0) # "Save" button which saves the state save_button = CustomButton("Save") save_button.clicked.connect(self.save_property) grid.addWidget(save_button, 3, 1) # "Cancel" button which closes the dialog without saving cancel_button = CustomButton("Cancel") cancel_button.clicked.connect(self.close) grid.addWidget(cancel_button, 3, 2) grid.setColumnStretch(0, 1) grid.setColumnStretch(1, 1) grid.setColumnStretch(2, 1) self.layout.addLayout(grid) self.layout.addWidget(self.viewer, 3) self.render_layout()
class EditPolyhedralPropertyDialog(NeVerDialog): """ This dialog allows to define a polyhedral property within a controlled environment. Attributes ---------- property_block : PropertyBlock Current property to edit. property_list : list List of given properties. has_edits : bool Flag signaling if the property was edited. Methods ---------- add_entry(str, str, str) Procedure to append the current constraint to the property list. save_property() Procedure to return the defined property. """ def __init__(self, property_block: PropertyBlock): super().__init__("Edit property", "") self.property_block = property_block self.has_edits = False self.property_list = [] self.viewer = CustomTextArea() self.viewer.setReadOnly(True) self.viewer.setFixedHeight(100) grid = QGridLayout() # Build main_layout title_label = CustomLabel("Polyhedral property") title_label.setStyleSheet(style.NODE_LABEL_STYLE) title_label.setAlignment(Qt.AlignCenter) grid.addWidget(title_label, 0, 0, 1, 3) # Labels var_label = CustomLabel("Variable") var_label.setStyleSheet(style.IN_DIM_LABEL_STYLE) var_label.setAlignment(Qt.AlignRight) grid.addWidget(var_label, 1, 0) relop_label = CustomLabel("Operator") relop_label.setStyleSheet(style.IN_DIM_LABEL_STYLE) relop_label.setAlignment(Qt.AlignCenter) grid.addWidget(relop_label, 1, 1) value_label = CustomLabel("Value") value_label.setStyleSheet(style.IN_DIM_LABEL_STYLE) value_label.setAlignment(Qt.AlignLeft) grid.addWidget(value_label, 1, 2) self.var_cb = CustomComboBox() for v in property_block.variables: self.var_cb.addItem(v) grid.addWidget(self.var_cb, 2, 0) self.op_cb = CustomComboBox() operators = ["<=", "<", ">", ">="] for o in operators: self.op_cb.addItem(o) grid.addWidget(self.op_cb, 2, 1) self.val = CustomTextBox() self.val.setValidator(ArithmeticValidator.FLOAT) grid.addWidget(self.val, 2, 2) # "Add" button which adds the constraint add_button = CustomButton("Add") add_button.clicked.connect( lambda: self.add_entry(str(self.var_cb.currentText()), str(self.op_cb.currentText()), self.val.text())) grid.addWidget(add_button, 3, 0) # "Save" button which saves the state save_button = CustomButton("Save") save_button.clicked.connect(self.save_property) grid.addWidget(save_button, 3, 1) # "Cancel" button which closes the dialog without saving cancel_button = CustomButton("Cancel") cancel_button.clicked.connect(self.close) grid.addWidget(cancel_button, 3, 2) grid.setColumnStretch(0, 1) grid.setColumnStretch(1, 1) grid.setColumnStretch(2, 1) self.layout.addLayout(grid) self.layout.addWidget(self.viewer, 3) self.render_layout() def add_entry(self, var: str, op: str, val: str) -> None: self.property_list.append((var, op, val)) self.viewer.appendPlainText(f"{var} {op} {val}") self.var_cb.setCurrentIndex(0) self.op_cb.setCurrentIndex(0) self.val.setText("") def save_property(self) -> None: self.has_edits = True if self.val.text() != '': self.add_entry(str(self.var_cb.currentText()), str(self.op_cb.currentText()), self.val.text()) self.close()