Ejemplo n.º 1
0
class IPFSHashExplorerToolBox(GalacteekTab):
    """
    Organizes IPFSHashExplorerWidgets with a QToolBox
    """
    def __init__(self, gWindow, hashRef, maxItems=16, parent=None):
        super(IPFSHashExplorerToolBox, self).__init__(gWindow)

        self.rootHash = hashRef
        self.maxItems = maxItems

        self.toolbox = QToolBox()
        self.exLayout = QVBoxLayout()
        self.exLayout.addWidget(self.toolbox)

        self.vLayout.addLayout(self.exLayout)
        if self.rootHash:
            self.viewHash(self.rootHash)

    @property
    def itemsCount(self):
        return self.toolbox.count()

    def viewHash(self, hashRef, addClose=False, autoOpenFolders=False):
        w = self.lookup(hashRef)
        if w:
            self.toolbox.setCurrentWidget(w)
            return True

        if self.itemsCount > self.maxItems:
            return False

        view = IPFSHashExplorerWidget(hashRef,
                                      parent=self,
                                      addClose=addClose,
                                      autoOpenFolders=autoOpenFolders)
        view.closeRequest.connect(functools.partial(self.remove, view))
        view.directoryOpenRequest.connect(
            lambda cid: self.viewHash(cid, addClose=True))

        idx = self.toolbox.addItem(view, getIconIpfsWhite(), hashRef)
        self.toolbox.setCurrentIndex(idx)
        view.reFocus()
        return True

    def lookup(self, hashRef):
        for idx in range(self.itemsCount):
            if self.toolbox.itemText(idx) == hashRef:
                return self.toolbox.widget(idx)

    def remove(self, view):
        idx = self.toolbox.indexOf(view)
        if idx:
            self.toolbox.removeItem(idx)
            # Always display previous index in the stack
            if self.itemsCount > 0:
                rIdx = idx - 1
                view = self.toolbox.widget(rIdx)
                if view:
                    self.toolbox.setCurrentWidget(view)
                    view.reFocus()
Ejemplo n.º 2
0
class NodeManagerWidget(QWidget):
    signal_new_node = pyqtSignal(Node)

    def __init__(self,
                 parent: QWidget = None,
                 scene: 'PMGraphicsScene' = None):
        super().__init__(parent)
        self.groups = ['simple_calc', 'logic', 'matrix', 'plot', 'io']
        self.node_info_dic: Dict[str, List[Dict[str, object]]] = {
            key: []
            for key in self.groups
        }

        self.setLayout(QVBoxLayout())
        self.top_layout = QHBoxLayout()
        self.layout().addLayout(self.top_layout)
        self.button_edit = QPushButton('Edit')
        self.button_add = QPushButton('Add')
        self.top_layout.addWidget(self.button_edit)
        self.top_layout.addWidget(self.button_add)
        self.button_edit.clicked.connect(self.on_edit)
        self.button_add.clicked.connect(self.on_add)
        self.toolbox = QToolBox()
        self.list_widgets: Dict[str, QListWidget] = {}
        for text in self.groups:
            list_widget = QListWidget()
            list_widget.doubleClicked.connect(self.on_item_double_clicked)
            self.layout().addWidget(self.toolbox)
            self.toolbox.addItem(list_widget, text)
            self.list_widgets[text] = list_widget
        self.scene: 'PMGraphicsScene' = scene
        self.load_nodes()

    def on_add(self):
        group = self.get_current_list_widget_group()
        self.add_node_info({
            'text': 'untitled',
            'inputs': ['input1'],
            'outputs': ['output1'],
            'code': '',
            'params': [],
            'icon': '',
            'group': group,
            'ports_changeable': [False, False]
        })

    def on_edit(self):
        list_widget = self.toolbox.currentWidget()
        curr_row = list_widget.currentRow()

        if curr_row >= 0:
            dic = self.node_info_dic[self.toolbox.itemText(
                self.toolbox.currentIndex())][curr_row]
            edit_layout = QHBoxLayout()
            input_widget = QLineEdit()
            edit_layout.addWidget(input_widget)
            check_button = QPushButton(text='check')
            edit_layout.addWidget(check_button)
            input_widget.setText(repr(dic['params']))
            views = [('line_edit', 'text', 'Node Text', dic['text']),
                     ('bool', 'inputs_changeable', 'Input Ports Changeable',
                      dic['ports_changeable'][0]),
                     ('bool', 'outputs_changeable', 'Output Ports Changeble',
                      dic['ports_changeable'][1]),
                     ('text_edit', 'code', 'Input Python Code', dic['code'],
                      'python'),
                     ('entry_list', 'inputs', 'Set Inputs',
                      [[None] * len(dic['inputs']),
                       dic['inputs']], lambda: None),
                     ('entry_list', 'outputs', 'Set Outputs',
                      [[None] * len(dic['outputs']),
                       dic['outputs']], lambda: None),
                     ('file', 'icon', 'Set Icon', dic['icon']),
                     ('choose_box', 'group', 'Group Name', dic['group'],
                      self.groups)]
            sp = SettingsPanel(parent=None, views=views)
            dialog = QDialog(self)

            def verify():
                try:
                    text = input_widget.text()
                    l = eval(text)
                    if isinstance(l, list):
                        dialog2 = QDialog(dialog)
                        sp2 = SettingsPanel(parent=None, views=l)
                        dialog2.setLayout(QHBoxLayout())
                        dialog2.layout().addWidget(sp2)
                        dialog2.layout().addLayout(edit_layout)
                        dialog2.exec_()

                except:
                    import traceback
                    traceback.print_exc()

            check_button.clicked.connect(verify)
            dialog.setLayout(QVBoxLayout())
            dialog.layout().addWidget(sp)
            dialog.layout().addLayout(edit_layout)
            dialog.exec_()
            dic = sp.get_value()
            params = None
            try:
                params = eval(input_widget.text())
            except:
                import traceback
                traceback.print_exc()
            group = self.get_current_list_widget_group()
            if isinstance(params, list):
                self.node_info_dic[group][curr_row]['params'] = params
            self.node_info_dic[group][curr_row]['text'] = dic['text']
            self.node_info_dic[group][curr_row]['icon'] = dic['icon']
            self.node_info_dic[group][curr_row]['code'] = dic['code']
            self.node_info_dic[group][curr_row]['inputs'] = dic['inputs'][1]
            self.node_info_dic[group][curr_row]['outputs'] = dic['outputs'][1]
            self.node_info_dic[group][curr_row]['group'] = dic['group']
            self.node_info_dic[group][curr_row]['ports_changeable'] = [
                dic['inputs_changeable'], dic['outputs_changeable']
            ]
            list_widget.item(curr_row).setText(dic['text'])

            self.save_node_templetes()
            self.load_nodes()
        else:
            return

    def add_node(self,
                 text: str,
                 inputs: List[str],
                 outputs: List[str],
                 ports_changeable: List[bool],
                 params_str: str = '',
                 icon_path: str = '',
                 func_str: str = ''):
        """
        添加新的节点
        """
        node_id = self.scene.new_id()
        input_ports = [
            CustomPort(node_id + ':input:%d' % int(i + 1),
                       text=name,
                       port_type='input') for i, name in enumerate(inputs)
        ]
        output_ports = [
            CustomPort(node_id + ':output:%d' % int(i + 1),
                       text=name,
                       port_type='output') for i, name in enumerate(outputs)
        ]
        node = Node(canvas=self.scene,
                    node_id=node_id,
                    text=text,
                    input_ports=input_ports,
                    output_ports=output_ports,
                    icon_path=icon_path)
        content = FlowContentForFunction(node)
        content.set_function(func_str, 'function')
        content.set_params(params_str)
        content.ports_changable = ports_changeable
        node.set_content(content)
        self.scene.add_node(node)

    def on_item_double_clicked(self):
        list_widget: QListWidget = self.toolbox.currentWidget()
        group = self.get_current_list_widget_group()
        curr_row = list_widget.currentRow()
        if curr_row >= 0:
            node_info = self.node_info_dic[group][curr_row]
            text: str = node_info.get('text')
            inputs: List[str] = node_info.get('inputs')
            outputs: List[str] = node_info.get('outputs')
            code: str = node_info.get('code')
            params: str = node_info.get('params')
            icon_path: str = node_info.get('icon')
            ports_changeable: List[bool] = node_info.get('ports_changeable')

            self.add_node(text, inputs, outputs, ports_changeable, params,
                          icon_path, code)

    def add_node_info(self, info_dic: Dict[str, object]):
        """
        add new infomation of node
        """
        group = self.get_current_list_widget_group()
        text = info_dic.get('text')
        self.get_current_list_widget().addItem(text)
        print(group)
        self.node_info_dic[group].append(info_dic)
        pass

    def get_current_list_widget(self) -> QListWidget:
        return self.toolbox.currentWidget()

    def get_current_list_widget_group(self) -> str:
        return self.toolbox.itemText(self.toolbox.currentIndex())

    def load_nodes(self):
        """
        加载节点
        加载节点之后,可以
        """
        import pandas
        self.node_info_dic = {key: [] for key in self.groups}
        df = pandas.read_csv(
            os.path.join(os.path.dirname(__file__), 'lib', 'test.csv'))
        # for k in self.node_info_dic:
        for i in range(df.shape[0]):
            row = df.loc[i]
            dic = {
                'text': row['text'] if not pandas.isna(row['text']) else '',
                'code': row['code'] if not pandas.isna(row['code']) else '',
                'inputs': json.loads(row['inputs']),
                'outputs': json.loads(row['outputs']),
                'params': json.loads(row['params'])
            }
            dic['icon'] = row['icon'] if not pandas.isna(row['icon']) else ''
            dic['group'] = row['group'] if not pandas.isna(
                row.get('group')) else 'simple_calc'
            ports_changeable = row.get('ports_changeable')
            dic['ports_changeable'] = json.loads(
                ports_changeable) if ports_changeable is not None else [
                    False, False
                ]
            self.node_info_dic[dic['group']].append(dic)
        self.refresh_list()

    def save_node_templetes(self):
        import pandas

        columns = [
            'text', 'inputs', 'outputs', 'ports_changeable', 'params', 'icon',
            'group', 'code'
        ]
        content = []
        node_infos = []
        for k in self.node_info_dic:
            node_infos += self.node_info_dic[k]

        for node_info in node_infos:
            text = node_info.get('text')
            icon = node_info.get('icon')
            inputs = json.dumps(node_info.get('inputs'))
            outputs = json.dumps(node_info.get('outputs'))
            ports_changeable = json.dumps(node_info.get('ports_changeable'))
            params = json.dumps(node_info.get('params'))
            code = node_info.get('code')
            group = node_info.get('group')
            content.append([
                text, inputs, outputs, ports_changeable, params, icon, group,
                code
            ])
        df = pandas.DataFrame(content, columns=columns)

        df.to_csv(os.path.join(os.path.dirname(__file__), 'lib', 'test.csv'))

    def refresh_list(self):
        for k in self.node_info_dic:
            node_infos = self.node_info_dic[k]
            list_widget = self.list_widgets[k]
            list_widget.clear()
            for info in node_infos:
                list_widget.addItem(info['text'])