def setup_possible_locations_tree(self): """ Creates the possible_locations_tree with all worlds, areas and nodes. """ self.possible_locations_tree.itemDoubleClicked.connect( self._on_tree_node_double_clicked) # TODO: Dark World names for world in self.game_description.world_list.worlds: world_item = QTreeWidgetItem(self.possible_locations_tree) world_item.setText(0, world.name) world_item.setExpanded(True) self._asset_id_to_item[world.world_asset_id] = world_item for area in world.areas: area_item = QTreeWidgetItem(world_item) area_item.area = area area_item.setText(0, area.name) area_item.setHidden(True) self._asset_id_to_item[area.area_asset_id] = area_item for node in area.nodes: node_item = QTreeWidgetItem(area_item) if isinstance(node, TranslatorGateNode): node_item.setText( 0, "{} ({})".format(node.name, node.gate)) else: node_item.setText(0, node.name) node_item.node = node if node.is_resource_node: node_item.setFlags(node_item.flags() & ~Qt.ItemIsUserCheckable) self._node_to_item[node] = node_item
def build_menu_by_recursive(root: QTreeWidgetItem, menu_dict: dict): for key in menu_dict: item = QTreeWidgetItem() item_font = QFont() item_font.setPointSize( self.config.getint('master', 'master_item_font_size')) try: text = str(menu_dict[key]['text']) item.setText(0, text) item.setFont(0, item_font) except KeyError: pass try: descript = str(menu_dict[key]['descript']) item.setToolTip(0, descript) except KeyError: pass try: scl = str(menu_dict[key]['scl']) item.setText(2, scl) except KeyError: pass try: children = menu_dict[key]['children'] build_menu_by_recursive(item, children) except KeyError: pass try: expanded = menu_dict[key]['expanded'] item.setExpanded(expanded) except KeyError: pass root.addChild(item)
def _create(self): struct = self.dm.getStructure(self.isInverse) for ws in struct: gparent = QTreeWidgetItem(self) gparent.setText(0, ws) for key in struct[ws]: parent = QTreeWidgetItem(gparent) parent.setText(0, key) parent.setFlags(parent.flags() | Qt.ItemIsTristate | Qt.ItemIsUserCheckable) if (self.inputList is not None and key == self.inputList[1] and ws == self.inputList[0]): channelsChecked = True gparent.setExpanded(True) self.curChecked = parent parent.setSelected(True) else: channelsChecked = False for k in struct[ws][key]: child = QTreeWidgetItem(parent) child.setFlags(child.flags()) child.setText(0, k) if channelsChecked: child.setCheckState(0, Qt.Checked) else: child.setCheckState(0, Qt.Unchecked)
class CopyDBDialog(QDialog, Ui_Dialog): def __init__(self, db_url, parent=None): QDialog.__init__(self, parent) Ui_Dialog.setupUi(self, self) self.db_url = db_url self.selectButton.clicked.connect(self.slot_accept) self.cancelButton.clicked.connect(self.slot_reject) self.success = False self.collection = None t = threading.Thread(target=self.fill_tree_widget) t.start() def slot_accept(self): col = self.get_collection() if col is not None: self.collection, c_name, c_type = col self.success = True self.close() def slot_reject(self): self.close() def fill_tree_widget(self, parent=None): if parent is None: self.collectionTreeWidget.clear() self.rootItem = QTreeWidgetItem(self.collectionTreeWidget, ["root", "root"]) self.rootItem.setExpanded(True) # root collection has id 0 parent_id = 0 parent_item = self.rootItem self.rootItem.setData(0, Qt.UserRole, parent_id) else: parent_id = parent[1] parent_item = parent[0] collection_list = get_collections_by_parent_id_from_remote_db( self.db_url, parent_id) for col in collection_list: colItem = QTreeWidgetItem(parent_item, [col[1], col[2]]) colItem.setData(0, Qt.UserRole, col[0]) self.fill_tree_widget((colItem, col[0])) def get_collection(self): colItem = self.collectionTreeWidget.currentItem() if colItem is None: return return int(colItem.data(0, Qt.UserRole)), str(colItem.text(0)), str( colItem.text(1))
class SelectTransitionDialog(QDialog, Ui_Dialog): def __init__(self, graph_data, parent=None): QDialog.__init__(self, parent) Ui_Dialog.setupUi(self, self) self.graph_data = graph_data self.selectButton.clicked.connect(self.slot_accept) self.cancelButton.clicked.connect(self.slot_reject) self.success = False self.transition_name = "" self.transition_entry = None self.fill_tree_widget() def slot_accept(self): colItem = self.collectionTreeWidget.currentItem() if colItem is None or colItem.parent() is None: return model_name = str(colItem.text(0)) action_name = str(colItem.parent().text(0)) model_id = int(colItem.data(0, Qt.UserRole)) self.transition_name = action_name + ":" + model_name self.transition_entry = { "action_name": action_name, "model_name": model_name, "model_id": model_id } self.success = True self.close() def slot_reject(self): self.close() def fill_tree_widget(self): self.collectionTreeWidget.clear() self.rootItem = QTreeWidgetItem(self.collectionTreeWidget, ["root", "root"]) self.rootItem.setExpanded(True) # root collection has id 0 self.rootItem.setData(0, Qt.UserRole, 0) for action in self.graph_data["nodes"]: actionItem = QTreeWidgetItem(self.rootItem, [action, "action"]) actionItem.setData(0, Qt.UserRole, action) for mp_id in self.graph_data["nodes"][action]: model_name = self.graph_data["nodes"][action][mp_id]["name"] mpItem = QTreeWidgetItem(actionItem, [model_name, "primitive"]) mpItem.setData(0, Qt.UserRole, int(mp_id))
def __init__(self, ui_file): super(Form, self).__init__() ui_file = QFile(ui_file) ui_file.open(QFile.ReadOnly) loader = QUiLoader() self.window = loader.load(ui_file) self.window.setFixedSize(self.window.width(), self.window.height()); ui_file.close() self.tree = self.window.findChild(QTreeWidget, 'treeMenu') # self.tree.itemSelectionChanged.connect(self.itemSelection) self.tree.currentItemChanged.connect(self.itemSelection) self.tree.itemClicked.connect(self.itemSelection) menulist = ["Cadastro de Pessoa"] itemlist = ["Inserir", "Atualizar", "Excluir", "Listar"] for str in menulist: parent = QTreeWidgetItem(self.tree) parent.setText(0, str) for opcao in itemlist: child = QTreeWidgetItem(parent) child.setText(0, opcao) parent.setExpanded(1) self.window.show() return
def build_toplevel_menu(self, surpac_scl_cfg: str): # Tree递归构建 def build_menu_by_recursive(root: QTreeWidgetItem, menu_dict: dict): for key in menu_dict: item = QTreeWidgetItem() item_font = QFont() item_font.setPointSize( self.config.getint('master', 'master_item_font_size')) try: text = str(menu_dict[key]['text']) item.setText(0, text) item.setFont(0, item_font) except KeyError: pass try: descript = str(menu_dict[key]['descript']) item.setToolTip(0, descript) except KeyError: pass try: scl = str(menu_dict[key]['scl']) item.setText(2, scl) except KeyError: pass try: children = menu_dict[key]['children'] build_menu_by_recursive(item, children) except KeyError: pass try: expanded = menu_dict[key]['expanded'] item.setExpanded(expanded) except KeyError: pass root.addChild(item) surpac_scl_encoding = self.config.get('master', 'surpac_scl_encoding') menus = [] with open(file=surpac_scl_cfg, encoding=surpac_scl_encoding) as _f: menu_dict = yaml.load(_f, yaml.loader.FullLoader) for key in menu_dict: menu_toplevel_item = QTreeWidgetItem() menu_toplevel_item_font = QFont() menu_toplevel_item_font.setPointSize( self.config.getint('master', 'master_root_font_size')) try: text = str(menu_dict[key]['text']) menu_toplevel_item.setText(0, text) menu_toplevel_item.setFont(0, menu_toplevel_item_font) except KeyError: pass try: descript = str(menu_dict[key]['descript']) menu_toplevel_item.setToolTip(0, descript) except KeyError: pass try: scl = str(menu_dict[key]['scl']) menu_toplevel_item.setText(2, scl) except KeyError: pass try: expanded = menu_dict[key]['expanded'] menu_toplevel_item.setExpanded(expanded) except KeyError: pass try: children = menu_dict[key]['children'] build_menu_by_recursive(menu_toplevel_item, children) except KeyError: pass menus.append(menu_toplevel_item) return menus
class EditCollectionDialog(QDialog, Ui_Dialog): def __init__(self, collection_id, parent_name, parent_id, default_name="", col_type="", owner=0, parent=None): QDialog.__init__(self, parent) Ui_Dialog.setupUi(self, self) self.acceptButton.clicked.connect(self.slot_accept) self.rejectButton.clicked.connect(self.slot_reject) self.parent_name = parent_name self.collection_id = collection_id #self.parentLabel.setText("Parent: "+parent_name) self.parent_id = parent_id self.db_url = DB_URL self.success = False self.name = default_name self.nameLineEdit.setText(default_name) self.col_type = col_type self.typeLineEdit.setText(col_type) self.ownerLineEdit.setText(str(owner)) t = threading.Thread(target=self.fill_tree_widget) t.start() def fill_tree_widget(self, parent=None): if parent is None: self.collectionTreeWidget.clear() self.rootItem = QTreeWidgetItem(self.collectionTreeWidget, ["root", "root"]) self.rootItem.setExpanded(True) # root collection has id 0 parent_id = 0 parent_item = self.rootItem self.rootItem.setData(0, Qt.UserRole, parent_id) else: parent_id = parent[1] parent_item = parent[0] collection_list = get_collections_by_parent_id_from_remote_db( self.db_url, parent_id) for col in collection_list: if col[0] == self.collection_id: self.select_tree_node(parent_item) continue colItem = QTreeWidgetItem(parent_item, [col[1], col[2]]) colItem.setData(0, Qt.UserRole, col[0]) self.fill_tree_widget((colItem, col[0])) def select_tree_node(self, node): node.setSelected(True) while node is not None: node.setExpanded(True) node = node.parent() def get_collection(self): colItem = self.collectionTreeWidget.currentItem() if colItem is None: return return int(colItem.data(0, Qt.UserRole)), str(colItem.text(0)), str( colItem.text(1)) def slot_accept(self): col = self.get_collection() if col is not None: self.parent_id, self.parent_name, c_type = col self.success = True self.name = str(self.nameLineEdit.text()) self.col_type = str(self.typeLineEdit.text()) self.owner = int(self.ownerLineEdit.text()) self.success = True self.close() def slot_reject(self): self.close()
class GraphDefinitionDialog(QDialog, Ui_Dialog): def __init__(self, db_url, skeleton, graph_data=None, name="",parent=None): QDialog.__init__(self, parent) Ui_Dialog.setupUi(self, self) self.skeleton = skeleton self.db_url = db_url self.selectButton.clicked.connect(self.slot_accept) self.cancelButton.clicked.connect(self.slot_reject) self.success = False t = threading.Thread(target=self.fill_tree_widget) t.start() self.graphRootItem = QTreeWidgetItem(self.graphTreeWidget, ["root", "root"]) self.graphRootItem.setExpanded(True) self.data = graph_data if self.data is not None: if "start_node" not in self.data: self.data["start_node"] = "" self.init_graph_view() else: self.data = dict() self.data["nodes"] = dict() self.data["start_node"] = "" self.name = name self.nameLineEdit.setText(name) self.collectionTreeWidget.itemClicked.connect(self._fill_model_list_from_db) self.modelListWidget.itemClicked.connect(self.update_selected_model) self.graphTreeWidget.itemClicked.connect(self.update_model_info) self.addModelButton.clicked.connect(self.slot_add_primitive) self.replaceModelButton.clicked.connect(self.slot_replace_primitive) self.addActionButton.clicked.connect(self.slot_add_action) self.removeGraphItemButton.clicked.connect(self.slot_remove_graph_item) self.setToStartNodeButton.clicked.connect(self.slot_set_to_start_node) self.addTransitionButton.clicked.connect(self.slot_add_transition) self.removeTransitionButton.clicked.connect(self.slot_remove_transition) self.fill_node_type_combobox() self.nodeTypeComboBox.currentIndexChanged.connect(self.update_node_type) self._fill_model_list_from_db() def init_graph_view(self): print("init graph view") start_node = str(self.data["start_node"]) self.startNodeLabel.setText(start_node) for action_name in self.data["nodes"]: actionItem = QTreeWidgetItem(self.graphRootItem, [action_name, "action"]) for mp_id in self.data["nodes"][action_name]: mp_name = self.data["nodes"][action_name][mp_id]["name"] mpItem = QTreeWidgetItem(actionItem, [mp_name, "primitive"]) mpItem.setData(0, Qt.UserRole, int(mp_id)) def slot_accept(self): self.name = str(self.nameLineEdit.text()) self.success = self.name != "" self.close() def slot_reject(self): self.close() def slot_add_primitive(self): selected_action = self.graphTreeWidget.currentItem() selected_primitive = self.modelListWidget.currentItem() if selected_action is not None and selected_primitive is not None: action_name = str(selected_action.text(0)) type_str = str(selected_action.text(1)) if type_str == "action": mp_id = int(selected_primitive.data(Qt.UserRole)) mp_name = str(selected_primitive.text()) mp_key = str(mp_id) if mp_key not in self.data["nodes"][action_name]: mpItem = QTreeWidgetItem(selected_action, [mp_name, "primitive"]) mpItem.setData(0, Qt.UserRole, mp_id) mp_dict = dict() mp_dict["transitions"] = dict() mp_dict["type"] = "standard" mp_dict["name"] = mp_name self.data["nodes"][action_name][mp_key] = mp_dict else: print(mp_name, "already part of action", action_name) def slot_replace_primitive(self): selected_graph_node = self.graphTreeWidget.currentItem() selected_primitive = self.modelListWidget.currentItem() if selected_graph_node is not None and selected_primitive is not None: type_str = str(selected_graph_node.text(1)) if type_str == "primitive": action_node = selected_graph_node.parent() action_name = str(action_node.text(0)) if action_name in self.data["nodes"]: old_mp_id = int(selected_graph_node.data(0, Qt.UserRole)) old_mp_name = str(selected_graph_node.text(0)) old_key = str(old_mp_id) new_mp_id = int(selected_primitive.data(Qt.UserRole)) new_mp_name = str(selected_primitive.text()) new_key = str(new_mp_id) if old_key in self.data["nodes"][action_name]: old_transitions = self.data["nodes"][action_name][old_key]["transitions"] old_type = self.data["nodes"][action_name][old_key]["type"] del self.data["nodes"][action_name][old_key] selected_graph_node.setText(0, new_mp_name) selected_graph_node.setData(0, Qt.UserRole, new_mp_id) mp_dict = dict() mp_dict["transitions"] = old_transitions mp_dict["type"] = old_type mp_dict["name"] = new_mp_name self.data["nodes"][action_name][new_key] = mp_dict self.replace_transitions(action_name, old_mp_name, old_mp_id, new_mp_name, new_mp_id) self.update_model_info() print("replaced", old_mp_id, "with", new_mp_id) else: print(old_mp_name, "not part of action", action_name) def replace_transitions(self, action_name, old_model_name, old_model_id, new_model_name, new_model_id): old_key = action_name+":"+old_model_name new_key = action_name+":"+new_model_name new_entry = dict() new_entry["model_name"] = new_model_name new_entry["model_id"] = new_model_id for a in self.data["nodes"]: for mp in self.data["nodes"][a]: if old_key in self.data["nodes"][a][mp]["transitions"]: del self.data["nodes"][a][mp]["transitions"][old_key] self.data["nodes"][a][mp]["transitions"][new_key] = copy(new_entry) def slot_remove_graph_item(self): item = self.graphTreeWidget.currentItem() if item is not None: #and item != self.graphRootItem parent_item = item.parent() item_name = str(item.text(0)) parent_name = str(parent_item.text(0)) if parent_name in self.data["nodes"]: mp_id = str(item.data(0, Qt.UserRole)) if mp_id in self.data["nodes"][parent_name]: del self.data["nodes"][parent_name][mp_id] elif item_name in self.data["nodes"]: del self.data["nodes"][item_name] parent_item.removeChild(item) def slot_set_to_start_node(self): item = self.graphTreeWidget.currentItem() if item is not None: #and item != self.graphRootItem parent_item = item.parent() if parent_item is not None: item_name = str(item.text(0)) parent_name = str(parent_item.text(0)) start_node = [parent_name, item_name] start_node_str = str(start_node) self.data["start_node"] = [parent_name, item_name] self.startNodeLabel.setText(start_node_str) def slot_add_action(self): dialog = EnterNameDialog() dialog.exec_() if dialog.success: action_name = dialog.name if action_name not in self.data["nodes"]: actionItem = QTreeWidgetItem(self.graphRootItem, [action_name, "action"]) self.data["nodes"][action_name] = dict() def slot_add_transition(self): item = self.graphTreeWidget.currentItem() if item is not None: parent_item = item.parent() item_name = str(item.text(0)) type_name = str(item.text(1)) parent_name = str(parent_item.text(0)) if type_name == "primitive": mp_id = str(item.data(0, Qt.UserRole)) if mp_id in self.data["nodes"][parent_name]: dialog = SelectTransitionDialog(self.data) dialog.exec_() if dialog.success and dialog.transition_entry is not None: action_name = str(dialog.transition_entry["action_name"]) model_name = str(dialog.transition_entry["model_name"]) name = action_name+":"+model_name self.data["nodes"][parent_name][mp_id]["transitions"][name] = dialog.transition_entry self.update_model_info() def slot_remove_transition(self): selected_transition = self.transitionListWidget.currentItem() if selected_transition is not None: self.transitionListWidget.takeItem(self.transitionListWidget.row(selected_transition)) transiton_name = str(selected_transition.text()) selected_item = self.graphTreeWidget.currentItem() action_name = str(selected_item.parent().text(0)) #mp_name = str(selected_item.text(0)) mp_id = str(selected_item.data(0, Qt.UserRole)) del self.data["nodes"][action_name][mp_id]["transitions"][transiton_name] self.update_model_info() def fill_tree_widget(self, parent=None): if parent is None: self.collectionTreeWidget.clear() self.rootItem = QTreeWidgetItem(self.collectionTreeWidget, ["root", "root"]) self.rootItem.setExpanded(True) # root collection has id 0 parent_id = 0 parent_item = self.rootItem self.rootItem.setData(0, Qt.UserRole, parent_id) else: parent_id = parent[1] parent_item = parent[0] collection_list = get_collections_by_parent_id_from_remote_db(self.db_url, parent_id) for col in collection_list: colItem = QTreeWidgetItem(parent_item, [col[1], col[2]]) colItem.setData(0, Qt.UserRole, col[0]) self.fill_tree_widget((colItem, col[0])) def get_collection(self): colItem = self.collectionTreeWidget.currentItem() if colItem is None: return return int(colItem.data(0, Qt.UserRole)), str(colItem.text(0)), str(colItem.text(1)) def _fill_model_list_from_db(self, idx=None): self.modelListWidget.clear() col = self.get_collection() if col is None: return c_id, c_name, c_type = col model_list = get_model_list_from_remote_db(self.db_url, c_id, self.skeleton) print("model list", model_list) if model_list is None: return for node_id, name in model_list: item = QListWidgetItem() item.setText(name) item.setData(Qt.UserRole, node_id) self.modelListWidget.addItem(item) self.update_selected_model() def update_selected_model(self): selected_action = self.graphTreeWidget.currentItem() selected_primitive = self.modelListWidget.currentItem() if selected_action is not None and selected_primitive is not None: self.selectedModelLabel.setText(selected_primitive.text()) else: self.selectedModelLabel.setText("None") def update_model_info(self, idx=None): self.transitionListWidget.clear() self.nodeTypeComboBox.setCurrentIndex(0) selected_item = self.graphTreeWidget.currentItem() if selected_item is None: return item_type = str(selected_item.text(1)) if item_type != "primitive": return item_name = str(selected_item.text(0)) mp_id = str(selected_item.data(0, Qt.UserRole)) action_name = str(selected_item.parent().text(0)) if action_name not in self.data["nodes"]: return if mp_id not in self.data["nodes"][action_name]: print("mp id not in nodes", mp_id) return for transiton_key in self.data["nodes"][action_name][mp_id]["transitions"]: item = QListWidgetItem() item.setText(transiton_key) self.transitionListWidget.addItem(item) node_type = self.data["nodes"][action_name][mp_id]["type"] index = self.nodeTypeComboBox.findText(node_type, Qt.MatchFixedString) if index >= 0: self.nodeTypeComboBox.setCurrentIndex(index) print("node_type", node_type, index, mp_id) def fill_node_type_combobox(self): self.nodeTypeComboBox.clear() self.nodeTypeComboBox.addItem("", 0) self.nodeTypeComboBox.addItem("standard", 1) self.nodeTypeComboBox.addItem("start", 2) self.nodeTypeComboBox.addItem("end", 3) self.nodeTypeComboBox.addItem("single", 4) self.nodeTypeComboBox.addItem("idle", 5) def update_node_type(self): selected_item = self.graphTreeWidget.currentItem() if selected_item is None: return item_type = str(selected_item.text(1)) if item_type != "primitive": return item_name = str(selected_item.text(0)) mp_id = str(selected_item.data(0, Qt.UserRole)) action_name = str(selected_item.parent().text(0)) if action_name not in self.data["nodes"]: return if mp_id not in self.data["nodes"][action_name]: return node_type = str(self.nodeTypeComboBox.currentText()) if node_type != "": self.data["nodes"][action_name][mp_id]["type"] = node_type print("set node type", item_name, node_type)
def loadBacktestTree(self): options = self.config.get("options", {}) underlyings = options.get("underlyings", []) for i in range(1): item = self.backtest_tree.topLevelItem(i) item.setExpanded(True) for j in range(item.childCount()): child_item = item.child(j) child_item.setExpanded(True) whatsthis = child_item.whatsThis(0) if whatsthis == "option": for underlying in underlyings: current_item = child_item node = QTreeWidgetItem(current_item) node.setText(0, underlying["name"]) node.setCheckState(0, Qt.Unchecked) node.setWhatsThis(0, "option_underlying") node.setExpanded(True) data = underlying.get("id", {}).get("data", pd.DataFrame()) if not data.empty: id_dict = underlying.get("id", {}) name = id_dict["list"][id_dict["value"]] childSubWindow = { "title": "%s的当日合约", "type": "option_contract_table", "table_name": "%date%", "where": "", "select": id, "hidden_columns": [], "index_column": [], "childSubWindow": {}, } hidden_columns = [ 'total_turnover', 'limit_up', 'limit_down', 'settlement', 'prev_settlement', 'discount_rate', 'acc_net_value', 'unit_net_value', 'date', 'open_interest', 'iopv', 'num_trades' ] GridView(self.parent, name, data, id=name, hidden_columns=hidden_columns, index_column='date', childSubWindow=childSubWindow, type="option_underlying") current_item = node groups = underlying.get("groups", []) for group in groups: node = QTreeWidgetItem(current_item) node.setText(0, group["name"]) node.setCheckState(0, Qt.Unchecked) node.setIcon(0, QtGui.QIcon("../icon/group.png")) node.setWhatsThis(0, "option_group") node.setExpanded(True) current_item = node contracts = group.get("contracts") for contract in contracts: node = QTreeWidgetItem(current_item) node.setText(0, contract["name"]) node.setCheckState(0, Qt.Unchecked) node.setWhatsThis(0, "option_contract") node.setExpanded(True) current_item = node
class RetargetDBDialog(QDialog, Ui_Dialog): def __init__(self, db_url, parent=None): QDialog.__init__(self, parent) Ui_Dialog.setupUi(self, self) self.db_url = db_url self.selectButton.clicked.connect(self.slot_accept) self.cancelButton.clicked.connect(self.slot_reject) self.success = False self.scale_factor = 1.0 self.place_on_ground = False self.fill_combo_box_with_skeletons() t = threading.Thread(target=self.fill_tree_widget) t.start() self.src_model = None self.target_model = None self.collection = None def fill_combo_box_with_skeletons(self): skeleton_list = get_skeletons_from_remote_db(self.db_url) for idx, skel, owner in skeleton_list: self.sourceModelComboBox.addItem(skel, idx) self.targetModelComboBox.addItem(skel, idx) def slot_accept(self): self.scale_factor = float(self.scaleLineEdit.text()) self.src_model = str(self.sourceModelComboBox.currentText()) self.target_model = str(self.targetModelComboBox.currentText()) self.place_on_ground = self.placeOnGroundRadioButton.isChecked() col = self.get_collection() if col is not None: self.collection, c_name, c_type = col self.success = True self.close() def slot_reject(self): self.close()# def fill_tree_widget(self, parent=None): if parent is None: self.collectionTreeWidget.clear() self.rootItem = QTreeWidgetItem(self.collectionTreeWidget, ["root", "root"]) self.rootItem.setExpanded(True) # root collection has id 0 parent_id = 0 parent_item = self.rootItem self.rootItem.setData(0, Qt.UserRole, parent_id) else: parent_id = parent[1] parent_item = parent[0] collection_list = get_collections_by_parent_id_from_remote_db(self.db_url, parent_id) for col in collection_list: colItem = QTreeWidgetItem(parent_item, [col[1], col[2]]) colItem.setData(0, Qt.UserRole, col[0]) self.fill_tree_widget((colItem, col[0])) def get_collection(self): colItem = self.collectionTreeWidget.currentItem() if colItem is None: return return int(colItem.data(0, Qt.UserRole)), str(colItem.text(0)), str(colItem.text(1))
class SonetPCPManagerQt(QDialog, sonet_pcp_manager_ui.Ui_sonet_pcp_manager): """ Window in charge of managing the available PCP trajectories within the app, and also generates new ones, if desired. The matlab data is stored in .mat files, in matrix format. The app needs pcp data in table format. The tables are stored in .pkl files. """ def __init__(self, *args, p_main_window=None, p_mat_eng=None): super(SonetPCPManagerQt, self).__init__(*args) self.setupUi(self) self.setModal(True) self.show() # Reference to the main window. self._p_main_window = p_main_window # Reference to matlab engine. self._p_matlab_engine = p_mat_eng # Some widgets settings. self.sonet_read_pcp_qtw.setHeaderLabels([ 'Selected .mat files', 'Total trajectories', 'Departure Dates', 'TOFs' ]) self.matrix_tw_outgoing_root_item = QTreeWidgetItem( self.sonet_read_pcp_qtw, ['Earth-Mars', '', '', '']) self.matrix_tw_incoming_root_item = QTreeWidgetItem( self.sonet_read_pcp_qtw, ['Mars-Earth', '', '', '']) self.resize_matrix_tw_columns() self.sonet_working_pcp_qtw.setHeaderLabels( ['Selected .pkl files', 'Rows', 'Columns']) self.table_tw_outgoing_root_item = QTreeWidgetItem( self.sonet_working_pcp_qtw, ['Earth-Mars', '', '']) self.table_tw_incoming_root_item = QTreeWidgetItem( self.sonet_working_pcp_qtw, ['Mars-Earth', '', '']) self.resize_table_tw_columns() # Status bar,for messages to the user. self.status_bar = QStatusBar() self.status_bar.setBaseSize(580, 22) self.status_bar.setSizeGripEnabled(False) self.status_bar_HLayout.addWidget(self.status_bar) # Other members. self._pcp_mat_file_incoming = None self._pcp_mat_file_outgoing = None self._pcp_table_file_incoming = None self._pcp_table_file_outgoing = None # Signals and slots connect. self.sonet_read_pcp_outgoing_trajectories_matrix_qpb.clicked.connect( self.clicked_read_pcp_matrix_file_outgoing) self.sonet_read_pcp_incoming_trajectories_matrix_qpb.clicked.connect( self.clicked_read_pcp_matrix_file_incoming) self.sonet_dvt_limit_qcb.stateChanged.connect( self.clicked_dvt_limit_checkbox) self.sonet_convert_pcp_2_table_format_qpb.clicked.connect( self.clicked_convert_pcp_2_table_format) self.sonet_read_pcp_outgoing_trajectories_table_qpb.clicked.connect( self.clicked_read_pcp_table_file_outgoing) self.sonet_read_pcp_incoming_trajectories_table_qpb.clicked.connect( self.clicked_read_pcp_table_file_incoming) self.matlab_pcp_generator_pb.clicked.connect( self.clicked_matlab_pcp_generator) self.btn_OK = self.sonet_ok_cancel_qpb_group.button( QDialogButtonBox.Ok) self.btn_OK.clicked.connect(self.clicked_ok) self.btn_OK.clicked.connect(self.accept) self.btn_cancel = self.sonet_ok_cancel_qpb_group.button( QDialogButtonBox.Cancel) self.btn_cancel.clicked.connect(self.clicked_cancel) self.btn_cancel.clicked.connect(self.reject) # If there's a currently working pcp in the database, display it to the user. self.read_database_pcp() # sonet_log(SonetLogType.INFO, 'class_tal.method_tal') # self.status_bar.showMessage('tal.', SONET_MSG_TIMEOUT) def read_database_pcp(self): """ If there's a currently working pcp in the database, display it to the user. """ working_pcp_paths = database.get_working_pcp_paths() pkl_file_outgoing_path = working_pcp_paths[0] pkl_file_incoming_path = working_pcp_paths[1] # Fill the pkl files path line edit widgets. self.sonet__outgoing_trajectories_table_line_edit.setText( pkl_file_outgoing_path) self.sonet__incoming_trajectories_table_line_edit.setText( pkl_file_incoming_path) # Set the members pkl files & update the table tree view. if pkl_file_outgoing_path: self._pcp_table_file_outgoing = database.get_pcp_table( TripType.OUTGOING) self.update_table_tree_view(pkl_file_outgoing_path, p_trip='Earth-Mars') if pkl_file_incoming_path: self._pcp_table_file_incoming = database.get_pcp_table( TripType.INCOMING) self.update_table_tree_view(pkl_file_incoming_path, p_trip='Mars-Earth') def clicked_ok(self): """ Sets the current working pcp files (if any) & close the window. If we have changed the outgoing or incoming pkl files, all the currently set trajectories are going to be reset. If the s/c had any filter, it remains unchanged. """ pkl_file_path_outgoing = self.sonet__outgoing_trajectories_table_line_edit.text( ) pkl_file_path_incoming = self.sonet__incoming_trajectories_table_line_edit.text( ) has_changed_outgoing = database.set_working_pcp( TripType.OUTGOING, pkl_file_path_outgoing) has_changed_incoming = database.set_working_pcp( TripType.INCOMING, pkl_file_path_incoming) # Reset the trajectories for ALL the s/c if necessary, AND inform to the user. if has_changed_outgoing or has_changed_incoming: reset_sc_filters_and_trajectories( p_filters_and_trajectories='Trajectories') self._p_main_window.statusbar.showMessage( 'Database has changed. Selected trajectories reset for ALL s/c', SONET_MSG_TIMEOUT * 3) self._exit_status = 'clicked_ok_and_changed' else: self._exit_status = 'clicked_ok' def clicked_cancel(self): """ Abort all the operations & close the window. """ self._exit_status = 'clicked_cancel' def clicked_convert_pcp_2_table_format(self): """ Converts matrix to tabular pcp data. .mat -> .pkl. - Reads all the current available .mat files. - Converts them to tabular format (pandas dataframes). - Also does some filtering (i.e. max dvt). - Saves the tables to pickle .pkl files. """ # self.status_bar.showMessage('SonetPCPManagerQt.clicked_convert_pcp_2_table_format."Not implemented."', # SONET_MSG_TIMEOUT) # Check if user has limited the dvt value. dvt_widget = self.sonet_dvt_limit_qdoublespinbox if dvt_widget.isEnabled(): dvt_limit_value = dvt_widget.value() else: dvt_limit_value = None # Convert mat obj to dataframe obj. result = [] for mat_file in [ self._pcp_mat_file_outgoing, self._pcp_mat_file_incoming ]: if mat_file is None: result.append(None) else: result.append( self.convert_mat_2_dataframe(mat_file, dvt_limit_value)) # Save the dataframes to pickle files. for df in result: df: pd.DataFrame if df is not None: file_path = df.attrs['file_name'] file_name = file_path.split('/')[-2] self.status_bar.showMessage('Writing' + file_name + 'pkl file', 2 * SONET_MSG_TIMEOUT) df.to_pickle(file_path) self.status_bar.showMessage('Pickle files written', 2 * SONET_MSG_TIMEOUT) # Remove mat files and reset associated widgets. self.reset_matrix_widgets() def clicked_dvt_limit_checkbox(self): """ Activate/deactivate the dvt limit line edit widget, depending of the check box state. """ self.sonet_dvt_limit_qdoublespinbox.setEnabled( self.sonet_dvt_limit_qcb.isChecked()) def clicked_matlab_pcp_generator(self): self._p_matlab_engine.PCPGenerator(nargout=0) def clicked_read_pcp_matrix_file_incoming(self): """ Opens a select file dialog, the user has to select a valid matlab .mat file containing the pcp data. """ file_path, filter_ = QFileDialog.getOpenFileName( parent=self, caption='Read PCP file (.mat)', dir=SONET_PCP_DATA_DIR, filter='*.mat') if file_path: self.sonet__incoming_trajectories_matrix_line_edit.setText( file_path) else: # The user canceled the open file window. return self._pcp_mat_file_incoming = loadmat(file_path) self.status_bar.showMessage('PCP incoming .mat file read', SONET_MSG_TIMEOUT) file_name = file_path.split('/')[-2] my_mat_file_dep_dates = self._pcp_mat_file_incoming[ 'departure_dates'].shape[1] my_mat_file_tofs = self._pcp_mat_file_incoming['tofs'].shape[1] my_mat_file_total_trajectories = my_mat_file_dep_dates * my_mat_file_tofs self.fill_matrix_QTreeWidget('Mars-Earth', file_name, str(my_mat_file_total_trajectories), str(my_mat_file_dep_dates), str(my_mat_file_dep_dates)) def clicked_read_pcp_matrix_file_outgoing(self): """ Opens a select file dialog, the user has to select a valid matlab .mat file containing the pcp data. """ # Read the .mat file. file_path, filter_ = QFileDialog.getOpenFileName( parent=self, caption='Read PCP file (.mat)', dir=SONET_PCP_DATA_DIR, filter='*.mat') if file_path: self.sonet__outgoing_trajectories_matrix_line_edit.setText( file_path) else: # The user canceled the open file window. return self._pcp_mat_file_outgoing = loadmat(file_path) self.status_bar.showMessage('PCP outgoing .mat file read', SONET_MSG_TIMEOUT) file_name = file_path.split('/')[-2] my_mat_file_dep_dates = self._pcp_mat_file_outgoing[ 'departure_dates'].shape[1] my_mat_file_tofs = self._pcp_mat_file_outgoing['tofs'].shape[1] my_mat_file_total_trajectories = my_mat_file_dep_dates * my_mat_file_tofs self.fill_matrix_QTreeWidget('Earth-Mars', file_name, str(my_mat_file_total_trajectories), str(my_mat_file_dep_dates), str(my_mat_file_dep_dates)) def clicked_read_pcp_table_file_incoming(self): """ Opens a select file dialog, the user has to select a valid pickle .pkl file containing the pcp data. """ file_path, filter_ = QFileDialog.getOpenFileName( parent=self, caption='Read PCP file (.pkl)', dir=SONET_PCP_DATA_DIR, filter='*.pkl') if file_path: self.sonet__incoming_trajectories_table_line_edit.setText( file_path) else: # The user canceled the open file window. return # Read the Python .pkl file. self._pcp_table_file_incoming = pd.read_pickle(file_path) self.status_bar.showMessage('PCP incoming .pkl file read', SONET_MSG_TIMEOUT) # Update the bottom tree view. self.update_table_tree_view(file_path, p_trip='Mars-Earth') def update_table_tree_view(self, a_file_path, p_trip=''): a_file_name = a_file_path.split('/')[-2] if p_trip == 'Earth-Mars': my_pkl_file_rows = self._pcp_table_file_outgoing.shape[0] my_pkl_file_cols = self._pcp_table_file_outgoing.shape[1] self.fill_table_QTreeWidget('Earth-Mars', a_file_name, str(my_pkl_file_rows), str(my_pkl_file_cols)) else: my_pkl_file_rows = self._pcp_table_file_incoming.shape[0] my_pkl_file_cols = self._pcp_table_file_incoming.shape[1] self.fill_table_QTreeWidget('Mars-Earth', a_file_name, str(my_pkl_file_rows), str(my_pkl_file_cols)) def clicked_read_pcp_table_file_outgoing(self): """ Opens a select file dialog, the user has to select a valid pickle .pkl file containing the pcp data. """ # Read the file name. file_path, filter_ = QFileDialog.getOpenFileName( parent=self, caption='Read PCP file (.pkl)', dir=SONET_PCP_DATA_DIR, filter='*.pkl') if file_path: self.sonet__outgoing_trajectories_table_line_edit.setText( file_path) else: # The user canceled the open file window. return # Read the Python .pkl file. self._pcp_table_file_outgoing = pd.read_pickle(file_path) self.status_bar.showMessage('PCP outgoing .pkl file read', SONET_MSG_TIMEOUT) # Update the bottom tree view. self.update_table_tree_view(file_path, p_trip='Earth-Mars') def reset_matrix_widgets(self): self._pcp_mat_file_outgoing = None self._pcp_mat_file_incoming = None self.sonet_dvt_limit_qcb.setChecked(False) self.sonet__outgoing_trajectories_matrix_line_edit.clear() self.sonet__incoming_trajectories_matrix_line_edit.clear() self.matrix_tw_outgoing_root_item.takeChildren() self.matrix_tw_incoming_root_item.takeChildren() @staticmethod def convert_mat_2_dataframe(a_my_mat_file, a_dvt_limit=None) -> pd.DataFrame: """ Converts the input mat file to tabular data, in the form of pandas dataframe obj. :param a_my_mat_file: input mat file. :param a_dvt_limit: the max dvt allowed for the output dataframe. """ # Initialize the data structures. table_rows = a_my_mat_file['departure_dates'].shape[ 1] # Table rows is N. table_size = table_rows**2 # Table size is N^2. rows = [i for i in range(table_size)] cols = ['DepDates', 'tof', 'c3d', 'c3a', 'dvd', 'dva', 'dvt', 'theta'] data = np.zeros((table_size, len(cols)), dtype=np.double) # Do the conversion. get_value = SonetPCPManagerQt._fill_the_table_data row = 0 for i in range(0, table_rows): # For each departure date. # print(i) for j in range(0, table_rows): # For each tof. # First, check max dvt, if greater than the cut-off value, discard this table row. dvt = get_value(a_my_mat_file, 'dvt', i, j) if dvt > a_dvt_limit: continue # Independent vars are (1,table_rows) ndarrays. data[row, 0] = get_value(a_my_mat_file, 'departure_dates', 0, i) data[row, 1] = get_value(a_my_mat_file, 'tofs', 0, j) # Dependent vars are (table_rows,table_rows) ndarrays. data[row, 2] = get_value(a_my_mat_file, 'c3d', i, j) data[row, 3] = get_value(a_my_mat_file, 'c3a', i, j) data[row, 4] = get_value(a_my_mat_file, 'dvd', i, j) data[row, 5] = get_value(a_my_mat_file, 'dva', i, j) data[row, 6] = dvt data[row, 7] = get_value(a_my_mat_file, 'theta', i, j) row = row + 1 # If the user has set a dvt limit, the returned dataframe my have less rows than the original expected. if a_dvt_limit: unfilled_rows = len(rows) - row df = pd.DataFrame(data[:-unfilled_rows, :], columns=cols, index=[i for i in range(row)]) else: df = pd.DataFrame(data, columns=cols, index=rows) # Add 'ArrivDates' column and perform some conversions and columns reordering. df = SonetPCPManagerQt.post_process(df) # Add attributes to the dataframe. df.attrs['file_name'] = str(a_my_mat_file['fname'][0]) + '.pkl' df.attrs['limit_dvt'] = a_dvt_limit df.attrs['memory_usage'] = int(df.memory_usage().sum() / 1e6) df.attrs['m_departure_dates'] = a_my_mat_file[ 'departure_dates'].tolist()[0] df.attrs['m_tofs'] = a_my_mat_file['tofs'].tolist()[0] return df @staticmethod def _fill_the_table_data(a_my_mat_file, var='', row=0, col=0): return a_my_mat_file[var][row, col] def fill_matrix_QTreeWidget(self, a_file_type='', a_file_name='', a_total_trajectories='0', a_total_dep_dates='0', a_total_tofs='0', p_clean_qtw_before_cleaning=False): if p_clean_qtw_before_cleaning: self.sonet_read_pcp_qtw.clear() # root_node = self.sonet_read_pcp_qtw.invisibleRootItem() if a_file_type == 'Earth-Mars': self.matrix_tw_outgoing_root_item.takeChildren() the_new_item = QTreeWidgetItem(self.matrix_tw_outgoing_root_item, [ a_file_name, a_total_trajectories, a_total_dep_dates, a_total_tofs ]) else: self.matrix_tw_incoming_root_item.takeChildren() the_new_item = QTreeWidgetItem(self.matrix_tw_incoming_root_item, [ a_file_name, a_total_trajectories, a_total_dep_dates, a_total_tofs ]) self.matrix_tw_outgoing_root_item.setExpanded(True) self.matrix_tw_incoming_root_item.setExpanded(True) self.resize_matrix_tw_columns() def fill_table_QTreeWidget(self, a_file_type='', a_file_name='', a_total_rows='0', a_total_cols='0', p_clean_qtw_before_cleaning=False): if p_clean_qtw_before_cleaning: self.sonet_working_pcp_qtw.clear() if a_file_type == 'Earth-Mars': self.table_tw_outgoing_root_item.takeChildren() the_new_item = QTreeWidgetItem( self.table_tw_outgoing_root_item, [a_file_name, a_total_rows, a_total_cols]) else: self.table_tw_incoming_root_item.takeChildren() the_new_item = QTreeWidgetItem( self.table_tw_incoming_root_item, [a_file_name, a_total_rows, a_total_cols]) self.table_tw_outgoing_root_item.setExpanded(True) self.table_tw_incoming_root_item.setExpanded(True) self.resize_table_tw_columns() def resize_matrix_tw_columns(self): self.sonet_read_pcp_qtw.resizeColumnToContents(0) self.sonet_read_pcp_qtw.resizeColumnToContents(1) self.sonet_read_pcp_qtw.resizeColumnToContents(2) self.sonet_read_pcp_qtw.resizeColumnToContents(3) def resize_table_tw_columns(self): self.sonet_working_pcp_qtw.resizeColumnToContents(0) self.sonet_working_pcp_qtw.resizeColumnToContents(1) self.sonet_working_pcp_qtw.resizeColumnToContents(2) @staticmethod def post_process(a_df: pd.DataFrame): """ Given a input dataframe: - Creates a new column called 'ArrivDates', which is a lineal combination of 'DepDates' and 'tof'. - Converts 'DepDates' and 'ArrivDates' from JD2000 to JD, as QDate objects work with absolute dates. - Converts 'theta' from radians to sexagesimal degrees. - Reorder columns in a more convenient way. :param a_df: a Pandas DataFrame. """ # Create 'ArrivDates' column. a_df['ArrivDates'] = a_df.DepDates + a_df.tof # Convert dates JD2000 to JD. JD2000 = 2451545.0 # Julian Day 2000, extracted from AstroLib matlab code. a_df['DepDates'] = (a_df.DepDates + JD2000) a_df['ArrivDates'] = (a_df.ArrivDates + JD2000) # Convert theta rad to º. a_df.theta = a_df.theta * 180 / np.pi # Reorder columns. reordered_cols = [ 'DepDates', 'ArrivDates', 'tof', 'theta', 'dvt', 'dvd', 'dva', 'c3d', 'c3a' ] return a_df.reindex(columns=reordered_cols)
class UploadMotionDialog(QDialog, Ui_Dialog): def __init__(self, controller_list, parent=None): QDialog.__init__(self, parent) self.controller_list = controller_list Ui_Dialog.setupUi(self, self) self.selectButton.clicked.connect(self.slot_accept) self.cancelButton.clicked.connect(self.slot_reject) self.db_url = constants.DB_URL self.session = SessionManager.session self.urlLineEdit.setText(self.db_url) self.motion_table = "motion_clips" self.action_table = "motion_primitives" self.action_table = "actions" self.action = "grasp" self.success = False self.fill_combo_box_with_skeletons() t = threading.Thread(target=self.fill_tree_widget) t.start() self.urlLineEdit.textChanged.connect(self.set_url) def set_url(self, text): print("set url", text) self.db_url = str(text) def fill_tree_widget(self, parent=None): if parent is None: self.collectionTreeWidget.clear() self.rootItem = QTreeWidgetItem(self.collectionTreeWidget, ["root", "root"]) self.rootItem.setExpanded(True) # root collection has id 0 parent_id = 0 parent_item = self.rootItem self.rootItem.setData(0, Qt.UserRole, parent_id) else: parent_id = parent[1] parent_item = parent[0] collection_list = get_collections_by_parent_id_from_remote_db( self.db_url, parent_id) for col in collection_list: colItem = QTreeWidgetItem(parent_item, [col[1], col[2]]) colItem.setData(0, Qt.UserRole, col[0]) self.fill_tree_widget((colItem, col[0])) def get_collection(self): colItem = self.collectionTreeWidget.currentItem() if colItem is None: return return int(colItem.data(0, Qt.UserRole)), str(colItem.text(0)), str( colItem.text(1)) def fill_combo_box_with_skeletons(self): self.skeletonModelComboBox.clear() skeleton_list = get_skeletons_from_remote_db(self.db_url) for idx, s in enumerate(skeleton_list): self.skeletonModelComboBox.addItem(s[1], idx) def slot_accept(self): skeleton_name = str(self.skeletonModelComboBox.currentText()) col = self.get_collection() if col is not None: c_id, c_name, c_type = col self.success = True is_processed = bool(self.isProcessedCheckBox.isChecked()) for c in self.controller_list: name = c.scene_object.name motion_data = c.get_json_data() print("upload motion clip ", name, "to ", c_id, c_name, c_type, skeleton_name) semantic_annotation = c._motion._semantic_annotation meta_info = dict() if len(semantic_annotation) > 0: meta_info[ "sections"] = create_section_dict_from_annotation( semantic_annotation) time_function = c._motion._time_function if time_function is not None and is_processed: meta_info["time_function"] = time_function else: is_processed = False if len(meta_info) > 0: meta_info_str = json.dumps(meta_info) else: meta_info_str = "" upload_motion_to_db(self.db_url, name, motion_data, c_id, skeleton_name, meta_info_str, is_processed, session=self.session) self.close() def slot_reject(self): self.close() def slot_new_skeleton(self): dialog = NewSkeletonDialog() dialog.exec_() if dialog.success: name = dialog.name bvh_str = dialog.bvh_str model = dialog.skeleton_model_str if model == "" and name in SKELETON_MODELS: model = json.dumps(SKELETON_MODELS[name]) create_new_skeleton_in_db(self.db_url, name, bvh_str, model) self.fill_combo_box_with_skeletons() self._fill_motion_list_from_db()