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()
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, message: str, ok_fun: Callable): super().__init__('', message) title_label = CustomLabel('Message', alignment=Qt.AlignCenter) # Set content label mess_label = CustomLabel(f"\n{self.content}\n", alignment=Qt.AlignCenter) # Connect function self.ok_btn.clicked.connect(lambda: ok_fun) self.layout.addWidget(title_label) self.layout.addWidget(mess_label) 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 __init__(self, block_id: str, p_type: str): super().__init__(block_id) self.property_type = p_type self.pre_condition = True self.smt_string = "" if p_type == "Generic SMT": self.label_string = "-" elif p_type == "Polyhedral": self.label_string = "Ax - b <= 0" self.condition_label = CustomLabel("PRE") self.property_label = CustomLabel(self.label_string) self.variables = [] self.init_layout() self.init_context_menu()
def __init__(self, name: str, parameters: dict): super().__init__() self.layout = QVBoxLayout() self.setContentsMargins(0, 0, 0, 0) self.setLayout(self.layout) self.setStyleSheet(style.DROPDOWN_STYLE) self.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Expanding) # Top bar with short info self.top = QWidget() self.top.setContentsMargins(0, 0, 0, 0) self.top.setStyleSheet(style.DROPDOWN_TOP_STYLE) self.top_layout = QHBoxLayout() self.top_layout.setContentsMargins(0, 0, 0, 0) self.top.setLayout(self.top_layout) self.name_label = CustomLabel(name) self.name_label.setAlignment(Qt.AlignLeft) self.name_label.setStyleSheet(style.DROPDOWN_NAME_STYLE) self.top_layout.addWidget(self.name_label, Qt.AlignLeft) self.type_label = CustomLabel(parameters["type"]) self.type_label.setAlignment(Qt.AlignLeft) self.type_label.setToolTip("Type") self.type_label.setStyleSheet(style.DROPDOWN_TYPE_STYLE) self.top_layout.addWidget(self.type_label, Qt.AlignLeft) if "default" in parameters: self.default_label = CustomLabel(parameters["default"]) self.default_label.setStyleSheet(style.DROPDOWN_DEFAULT_STYLE) self.default_label.setToolTip("Default value") self.default_label.setAlignment(Qt.AlignCenter) self.top_layout.addWidget(self.default_label, Qt.AlignRight) self.down_button = CustomButton("\u25bc") self.down_button.setStyleSheet(style.DROPDOWN_ARROW_STYLE) self.down_button.clicked.connect(lambda: self.__toggle_visibility()) self.top_layout.addWidget(self.down_button, Qt.AlignRight) self.layout.addWidget(self.top) self.description = CustomLabel(parameters["description"]) self.description.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Maximum) self.description.setWordWrap(True) self.description.setStyleSheet(style.DESCRIPTION_STYLE) self.description.hide() self.layout.addWidget(self.description)
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 __init__(self, message: str, message_type: MessageType): super().__init__('', message) # Set the dialog stile depending on message_type if message_type == MessageType.MESSAGE: title_label = CustomLabel('Message', alignment=Qt.AlignCenter) title_label.setStyleSheet(style.NODE_LABEL_STYLE) else: title_label = CustomLabel('Error', alignment=Qt.AlignCenter) title_label.setStyleSheet(style.ERROR_LABEL_STYLE) # Set content label mess_label = CustomLabel(f"\n{self.content}\n", alignment=Qt.AlignCenter) # Compose widgets self.layout.addWidget(title_label) self.layout.addWidget(mess_label) self.render_layout()
def __init__(self, title, message): super().__init__(title, message) # Set title label title_label = CustomLabel(self.title, primary=True) # Set message label mess_label = CustomLabel(f"\n{self.content}\n", alignment=Qt.AlignCenter) self.confirm = False # Add buttons to close the dialog self.ok_btn.clicked.connect(self.ok) self.cancel_btn.clicked.connect(self.deny) # Compose widgets self.layout.addWidget(title_label) self.layout.addWidget(mess_label) self.render_layout()
def __init__(self): super(MainWindow, self).__init__() # Init window appearance self.SYSNAME = "NeVer 2" self.setWindowTitle(self.SYSNAME) self.setWindowIcon(QtGui.QIcon(ROOT_DIR + '/res/icons/logo.png')) self.setStyleSheet("background-color: " + style.GREY_1) # Navigation menu self.nav_menu_bar = self.menuBar() self.init_nav_menu_bar() # Blocks toolbar self.toolbar = BlocksToolbar(ROOT_DIR + '/res/json/blocks.json') # Parameters toolbar self.parameters = ParamToolbar() # Drawing Canvas self.canvas = Canvas(self.toolbar.blocks) # Status bar self.status_bar = QStatusBar() self.status_bar.setSizeGripEnabled(False) self.setStatusBar(self.status_bar) self.status_bar.setStyleSheet(style.STATUS_BAR_STYLE) self.status_bar_mode_label = CustomLabel() self.status_bar_mode_label.setStyleSheet(style.STATUS_BAR_WIDGET_STYLE) self.status_bar_selections_label = CustomLabel() self.status_bar_selections_label.setStyleSheet(style.STATUS_BAR_WIDGET_STYLE) self.status_bar.addPermanentWidget(self.status_bar_selections_label) self.status_bar.addPermanentWidget(self.status_bar_mode_label) # And adding them to the window self.addDockWidget(Qt.RightDockWidgetArea, self.parameters, Qt.Vertical) self.addToolBar(QtCore.Qt.ToolBarArea.LeftToolBarArea, self.toolbar) self.setCentralWidget(self.canvas.view) self.connect_events()
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_layout(self): """ Initialize the dialog layout with two ListViews and two buttons in the middle for the composition """ # Setup layouts tr_layout = QHBoxLayout() left_layout = QVBoxLayout() label1 = CustomLabel('Available', primary=True) left_layout.addWidget(label1) left_layout.addWidget(self.available) mid_layout = QVBoxLayout() mid_layout.addWidget(self.add_btn) mid_layout.addWidget(self.rm_btn) mid_layout.setAlignment(Qt.AlignCenter) right_layout = QVBoxLayout() label2 = CustomLabel('Selected', primary=True) right_layout.addWidget(label2) right_layout.addWidget(self.selected) tr_layout.addLayout(left_layout) tr_layout.addLayout(mid_layout) tr_layout.addLayout(right_layout) self.layout.addLayout(tr_layout) transform = utility.read_json(ROOT_DIR + '/res/json/transform.json') for t in transform.keys(): self.available.addItem(t) if transform[t]: self.params_2level[t] = {} for k, v in transform[t].items(): self.params_2level[t][k] = v
def __init__(self, property_block: PropertyBlock): super().__init__("Edit property", "") self.property_block = property_block self.new_property = self.property_block.smt_string self.has_edits = False self.layout = QGridLayout() # Build main_layout title_label = CustomLabel("SMT property") title_label.setStyleSheet(style.NODE_LABEL_STYLE) title_label.setAlignment(Qt.AlignCenter) self.layout.addWidget(title_label, 0, 0, 1, 2) # Input box smt_label = CustomLabel("SMT-LIB definition") smt_label.setStyleSheet(style.IN_DIM_LABEL_STYLE) smt_label.setAlignment(Qt.AlignRight) self.layout.addWidget(smt_label, 1, 0) self.smt_box = CustomTextArea() self.smt_box.insertPlainText(self.new_property) self.layout.addWidget(self.smt_box, 1, 1) # "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 __init__(self, node_file_path: str): super().__init__() self.NODE_FILE_PATH = node_file_path self.setContextMenuPolicy(Qt.PreventContextMenu) self.blocks = dict() self.properties = dict() # Graphic buttons self.f_buttons = dict() self.b_buttons = dict() self.p_buttons = dict() # Labels self.toolbar_tools_label = CustomLabel("Tools") self.toolbar_blocks_label = CustomLabel("Nodes") self.toolbar_properties_label = CustomLabel("Properties") self.isToolbar_tools_label_visible = True self.isToolbar_blocks_label_visible = True self.isToolbar_properties_label_visible = True # Setup view self.__display_tools() self.__init_blocks() self.__display_blocks() self.__init_properties() self.__display_properties() # Toolbar style for item in self.children(): if type(item) is QToolButton: item.setStyleSheet("background-color: " + style.GREEN_2) self.setStyleSheet(style.TOOLBAR_STYLE) self.setOrientation(Qt.Vertical) self.setMovable(False) self.setFloatable(False)
def __init__(self, block_id: str): super(GraphicBlock, self).__init__() self.block_id = block_id self.main_layout = QVBoxLayout() self.main_layout.setSpacing(0) self.title_label = CustomLabel("Graphic block") self.content_layout = QGridLayout() self.rect = None self.proxy_control = None self.context_actions = dict() self.setLayout(self.main_layout) # Set style and transparent background for the rounded corners self.setAttribute(Qt.WA_TranslucentBackground) self.setStyleSheet(style.GRAPHIC_BLOCK_STYLE)
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_layout(self) -> None: """ This method sets up the the property block main_layout with the property parameters. """ # Override title label self.title_label.setText(self.property_type) self.title_label.setStyleSheet(style.PROPERTY_TITLE_STYLE) self.condition_label.setStyleSheet(style.PROPERTY_CONDITION_STYLE) self.main_layout.addWidget(self.title_label) self.main_layout.addWidget(self.condition_label) self.init_grid() formula_label = CustomLabel("Formula") formula_label.setStyleSheet(style.PAR_NODE_STYLE) self.property_label.setStyleSheet(style.DIM_NODE_STYLE) self.content_layout.addWidget(formula_label, 1, 0) self.content_layout.addWidget(self.property_label, 1, 1)
def __init__(self, message: str): super().__init__("", message) # Override window title self.setWindowTitle("Wait...") # Set content label message_label = CustomLabel(self.content) message_label.setStyleSheet(style.LOADING_LABEL_STYLE) # Set loading bar progress_bar = ProgressBar(self, minimum=0, maximum=0, textVisible=False, objectName="ProgressBar") progress_bar.setStyleSheet(style.PROGRESS_BAR_STYLE) # Compose widgets self.layout.addWidget(message_label) self.layout.addWidget(progress_bar) self.render_layout() # Disable the dialog frame and close button self.setWindowFlag(QtCore.Qt.WindowCloseButtonHint, False) self.setWindowFlags(Qt.FramelessWindowHint)
def __init__(self, nn: NeuralNetwork): super().__init__("Train Network") # Training elements self.nn = nn self.is_nn_trained = False self.dataset_path = "" self.dataset_params = dict() self.dataset_transform = tr.Compose([]) self.params = utility.read_json(ROOT_DIR + '/res/json/training.json') self.gui_params = dict() self.loss_f = '' self.metric = '' self.grid_layout = QGridLayout() # Dataset dt_label = CustomLabel("Dataset") dt_label.setAlignment(Qt.AlignCenter) dt_label.setStyleSheet(style.NODE_LABEL_STYLE) self.layout.addWidget(dt_label) dataset_layout = QHBoxLayout() self.widgets["dataset"] = CustomComboBox() self.widgets["dataset"].addItems( ["MNIST", "Fashion MNIST", "Custom data source..."]) self.widgets["dataset"].setCurrentIndex(-1) self.widgets["dataset"].activated \ .connect(lambda: self.setup_dataset(self.widgets["dataset"].currentText())) dataset_layout.addWidget(CustomLabel("Dataset")) dataset_layout.addWidget(self.widgets["dataset"]) self.layout.addLayout(dataset_layout) transform_layout = QHBoxLayout() self.widgets["transform"] = CustomComboBox() self.widgets["transform"].addItems([ "No transform", "Convolutional MNIST", "Fully Connected MNIST", "Custom..." ]) self.widgets["transform"].activated \ .connect(lambda: self.setup_transform(self.widgets["transform"].currentText())) transform_layout.addWidget(CustomLabel("Dataset transform")) transform_layout.addWidget(self.widgets["transform"]) self.layout.addLayout(transform_layout) # Separator sep_label = CustomLabel("Training parameters") sep_label.setAlignment(Qt.AlignCenter) sep_label.setStyleSheet(style.NODE_LABEL_STYLE) self.layout.addWidget(sep_label) # Main body # Activation functions for dynamic widgets def activation_combo(key: str): return lambda: self.update_grid_view( f"{key}:{self.widgets[key].currentText()}") def activation_line(key: str): return lambda: self.update_dict_value(key, "", self.widgets[key]. text()) body_layout = self.create_widget_layout(self.params, activation_combo, activation_line) body_layout.addLayout(self.grid_layout) self.grid_layout.setAlignment(Qt.AlignTop) self.layout.addLayout(body_layout) # Buttons btn_layout = QHBoxLayout() self.train_btn = CustomButton("Train network") self.train_btn.clicked.connect(self.train_network) self.cancel_btn = CustomButton("Cancel") self.cancel_btn.clicked.connect(self.close) btn_layout.addWidget(self.train_btn) btn_layout.addWidget(self.cancel_btn) self.layout.addLayout(btn_layout) self.render_layout()
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_layout(self) -> None: """ This method sets up the the node block main_layout with attributes and values. """ self.init_grid() # Iterate and display parameters, count rows par_labels = dict() count = 1 for name, param in self.node.param.items(): # Set the label par_labels[name] = CustomLabel(name) par_labels[name].setAlignment(Qt.AlignLeft) par_labels[name].setStyleSheet(style.PAR_NODE_STYLE) self.dim_labels[name] = CustomLabel() self.dim_labels[name].setAlignment(Qt.AlignCenter) self.dim_labels[name].setStyleSheet(style.DIM_NODE_STYLE) self.content_layout.addWidget(par_labels[name], count, 0) self.content_layout.addWidget(self.dim_labels[name], count, 1) count += 1 # Init block data with default values if "default" in param.keys() and param["default"] == "None": self.block_data[name] = None elif param["type"] == "Tensor": if "shape" in param.keys(): shape = self.text_to_tuple(param["shape"]) self.block_data[name] = Tensor(shape=shape, buffer=np.random.normal(size=shape)) else: self.block_data[name] = Tensor(shape=(1, 1), buffer=np.random.normal(size=(1, 1))) elif param["type"] == "int": if "default" in param.keys(): if param["default"] == "rand": self.block_data[name] = 1 else: self.block_data[name] = int(param["default"]) else: self.block_data[name] = 1 elif param["type"] == "list of ints": if "default" in param.keys(): self.block_data[name] = tuple(map(int, param["default"].split(', '))) else: self.block_data[name] = (1, 1) elif param["type"] == "float": if "default" in param.keys(): if param["default"] == "rand": self.block_data[name] = 1 else: self.block_data[name] = float(param["default"]) else: self.block_data[name] = 0.1 elif param["type"] == "boolean": if "default" in param.keys(): self.block_data[name] = bool(param["default"]) else: self.block_data[name] = False self.update_labels() self.edited.connect(lambda: self.update_labels())
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 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 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 __init__(self, block: NodeBlock): super().__init__() self.setStyleSheet(style.BLOCK_BOX_STYLE) self.layout = QVBoxLayout() self.layout.setSpacing(0) self.layout.setContentsMargins(0, 0, 10, 0) self.setLayout(self.layout) self.adjustSize() self.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Maximum) # Widget title self.title_label = CustomLabel() self.title_label.setStyleSheet(style.TITLE_LABEL_STYLE) self.title_label.setText(block.block_id + ":" + block.node.name) # NodeBlock description self.description_label = CustomLabel() self.description_label.setStyleSheet(style.DESCRIPTION_STYLE) self.description_label.setWordWrap(True) self.description_label.setAlignment(Qt.AlignLeft) self.description_label.setText(block.node.descr) self.description_label.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Minimum) # Parameters section if block.node.param: self.parameters_label = CustomLabel("Parameters") self.parameters_label.setStyleSheet(style.NODE_LABEL_STYLE) self.parameters = QWidget() self.parameters_layout = QVBoxLayout() self.parameters_layout.setSpacing(0) self.parameters.setLayout(self.parameters_layout) self.parameters.setStyleSheet("padding: 0px") for par, values in block.node.param.items(): self.parameters_layout.addWidget(DropDownLabel(par, values)) # Inputs section if block.node.input: self.inputs_label = CustomLabel("Input") self.inputs_label.setStyleSheet(style.NODE_LABEL_STYLE) self.inputs = QWidget() self.inputs_layout = QVBoxLayout() self.inputs_layout.setSpacing(0) self.inputs.setLayout(self.inputs_layout) self.inputs.setStyleSheet("padding: 0px") for par, values in block.node.input.items(): self.inputs_layout.addWidget(DropDownLabel(par, values)) # Outputs section if block.node.output: self.outputs_label = CustomLabel("Output") self.outputs_label.setStyleSheet(style.NODE_LABEL_STYLE) self.outputs = QWidget() self.outputs_layout = QVBoxLayout() self.outputs_layout.setSpacing(0) self.outputs.setLayout(self.outputs_layout) self.outputs.setStyleSheet("padding: 0px") for par, values in block.node.output.items(): self.outputs_layout.addWidget(DropDownLabel(par, values)) # Compose widget self.layout.addWidget(self.title_label) self.layout.addWidget(self.description_label) if block.node.param: self.layout.addWidget(self.parameters_label) self.layout.addWidget(self.parameters) if block.node.input: self.layout.addWidget(self.inputs_label) self.layout.addWidget(self.inputs) if block.node.output: self.layout.addWidget(self.outputs_label) self.layout.addWidget(self.outputs)