Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. Qt for Python
  4. PYQT5 - UI Function working for Layout 1 not for Layout 2

PYQT5 - UI Function working for Layout 1 not for Layout 2

Scheduled Pinned Locked Moved Unsolved Qt for Python
7 Posts 2 Posters 589 Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • S Offline
    S Offline
    sudo_ranjith
    wrote on 19 Jul 2022, 06:53 last edited by sudo_ranjith
    #1

    we have an application Yaml editor in which on click on MDI sub window, the Yaml editor sub module gets opened and submodule has multiple tabs and those multiple tabs will have sub tabs. on top of the submodule there is a file menu which has open , save , exit and actions menu which has addrow, remove row etc. addrow should add row in the loaded yaml content inside the tab.

    Direct Question:

    File_1= yamleditor.py

    File_2= treemodel.py

    The problem we face is addrow(), remove row() function works fine when it is inside the Qtreeview model (file_2),but when it is called from a actions menu(file_1) the function gets executed but it is not reflecting in the ui?. The same error occurs in all the action item.

    CODE REF for File_2: https://doc.qt.io/qtforpython/examples/example_widgets_itemviews_jsonmodel.html#json-model-example

    077c9b0d-a325-4989-b778-69486dd5fc3e-image.png

    6c3768f8-69f0-41b6-bf93-05548253e0d8-image.png

    yaml_editor.py

    import sys
    import traceback
    from PyQt5.QtWidgets import QApplication, QWidget, QTreeView, QMessageBox, QVBoxLayout, QLabel, QLineEdit, QComboBox, QListWidget, QHBoxLayout, QPushButton, QFileDialog, QProgressBar, QListView, QAbstractItemView, QTabWidget, QMdiArea, QMainWindow, QMenu, QToolBar, QAction, QFrame
    from PyQt5.QtGui import QIntValidator, QFont
    from PyQt5.QtCore import Qt
    import yaml
    import os
    import json
    from datetime import datetime
    import subprocess
    from threading import *
    from tree_model import TreeModelClass as ETreeWindw
    
    
    class AnaYAMLEditor(QWidget):
        def __init__(self):
            super().__init__()
            self.title = 'YAML Editor'
            self.ui_fields_access = 0
            self.config = yaml.safe_load(open("input.yaml")) 
            self.config_key = 'yaml_editor'
            self.current_file_path = os.getcwd()
            self.module_name = "Tab_1"
            self.save_flag = 0
            try:
                self.initUI()
                self.showMaximized()
                self.show()
            except Exception:
                print(traceback.format_exc())
    
        def initUI(self):        
            print(f"{self.title} app started at {datetime.now()}")
            self.setWindowTitle(self.title)
    
            self.tabs = QTabWidget()
            self.analysis_config_tab = QWidget()
            self.tabs.addTab(self.analysis_config_tab, "Tab_1")
            
            self.tabs.setCurrentIndex(0)
            self.tabs.currentChanged.connect(self.tab_changed)
    
            
            self.toolbar = QToolBar(self)
            self.file_meu = QPushButton(" File")
            self.actions_menu = QPushButton("Actions")
            self.file_meu.setStyleSheet('''
                QPushButton{
                    border: none;
                    }
                QPushButton:menu-indicator{
                    image: none;
                    }
                QPushButton:hover {
                    background-color: lightgrey;
                    }
                QPushButton:pressed {
                    background-color: lightgrey;
                    }
                QPushButton:align{
                    text-align: center;
                    }
    
                ''')
    
            self.file_meu.setFont(QFont("Arial", 10))
            self.actions_menu.setStyleSheet('''
                QPushButton{
                    border: none;
                    }
                QPushButton:menu-indicator{
                    image: none;
                    }
                QPushButton:hover {
                    background-color: lightgrey;
                    }
                ''')
            self.actions_menu.setFont(QFont("Arial", 10))
            self.toolbar.addWidget(self.file_meu)
            self.toolbar.addWidget(self.actions_menu)
            
            menu_file = QMenu()
            menu_action = QMenu()
            self.actions_menu.setMenu(menu_action)
            self.file_meu.setMenu(menu_file)
    
            self.file_menu_1 = QAction("Open", self)
            self.file_menu_1.triggered.connect(lambda: self.menu_open(self.module_name))
            self.file_menu_1.setShortcut("Ctrl+O")
            self.file_menu_1.setStatusTip("Open a file")
    
            menu_file.addAction(self.file_menu_1)
    
            self.file_menu_2 = QAction("Open Containing Folder", self)
            menu_file_2 = QMenu()
            menu_file_2.addAction("File Explorer")
            menu_file_2.addAction("cmd")
            menu_file_2.actions()[0].triggered.connect(lambda: self.menu_open_containing_folder(self.module_name))
            menu_file_2.actions()[1].triggered.connect(self.invoke_menu_cmd_thread)
    
    
            self.file_menu_2.setMenu(menu_file_2)
            self.file_menu_2.setStatusTip("Open Containing Folder")
    
            self.file_menu_2.triggered.connect(lambda: self.menu_open_containing_folder(self.module_name))
            menu_file.addAction(self.file_menu_2)
    
            self.file_menu_3 = QAction("Save", self)
            self.file_menu_3.triggered.connect(lambda: self.menu_save(self.module_name))
            menu_file.addAction(self.file_menu_3)
    
            self.file_menu_4 = QAction("Save As", self)
            self.file_menu_4.triggered.connect(lambda: self.menu_save_as(self.module_name))
            menu_file.addAction(self.file_menu_4)
    
            self.file_menu_4 = QAction("Exit", self)
            self.file_menu_4.triggered.connect(self.closeEvent)
            menu_file.addAction(self.file_menu_4)
    
    
            self.actions_menu_1 = QAction("Add Row", self)
            self.actions_menu_1.triggered.connect(lambda: self.menu_add_row(self.module_name))
            menu_action.addAction(self.actions_menu_1)
            self.actions_menu_2 = QAction("Remove Row", self)
            self.actions_menu_2.triggered.connect(lambda: self.menu_remove_row(self.module_name))
            menu_action.addAction(self.actions_menu_2)
            self.actions_menu_3 = QAction("Insert Child Row", self)
            self.actions_menu_3.triggered.connect(lambda: self.menu_add_child_row(self.module_name))
            menu_action.addAction(self.actions_menu_3)
            
    
            self.vertical_layout = QVBoxLayout(self)
            self.vertical_layout.setAlignment(Qt.AlignTop | Qt.AlignLeft)
    
    
            self.h_box_layout = QHBoxLayout(self)
            self.h_box_layout.setAlignment(Qt.AlignTop | Qt.AlignLeft)
            self.h_box_layout.addWidget(self.toolbar)
    
            
            self.vertical_layout.addLayout(self.h_box_layout)
    
            self.horizontal_line = QFrame()
            self.horizontal_line.setFrameShape(QFrame.HLine)
            self.horizontal_line.setFrameShadow(QFrame.Sunken)
            self.vertical_layout.addWidget(self.horizontal_line)
    
            self.h_box_layout = QHBoxLayout()
            self.h_box_layout.addWidget(self.tabs)
            self.vertical_layout.addLayout(self.h_box_layout)
    
            self.vertical_layout.setContentsMargins(0, 0, 0, 0)
            self.setWindowTitle(self.title)
            self.show()
    
    
    
        def menu_open(self, module_name):
            file_path = QFileDialog.getOpenFileName(self, 'Open File', '', "All Files (*)")
            print(file_path)
            if file_path[0] != '':
                self.current_file_path = file_path[0]
                self.setWindowTitle(f"{self.title} - {file_path[0]}")
                self.edit_tree_window = ETreeWindw(self.module_name, self.current_file_path, self.save_flag)
                self.horizontal_box_layout = QHBoxLayout()
                self.horizontal_box_layout.addWidget(self.edit_tree_window)
                self.analysis_config_tab.setLayout(self.horizontal_box_layout)
    
                self.h_box_layout = QHBoxLayout()
                self.h_box_layout.addWidget(self.tabs)
                self.vertical_layout.addLayout(self.h_box_layout)
                self.show()
    
        def menu_open_containing_folder(self, module_name):
            FILEBROWSER_PATH = os.path.join(os.getenv('WINDIR'), 'explorer.exe')
            subprocess.run([FILEBROWSER_PATH, '/select,', os.path.normpath(self.current_file_path)])
            return
    
        def invoke_menu_cmd_thread(self):
            self.t1 = Thread(target=self.menu_open_cmd)
            self.t1.start()
    
        def menu_open_cmd(self):
            os.system("start cmd /K ")
            os.system("pause")
            return
    
        def update_window_title_edited(self):
            temp_title = self.windowTitle()
            temp_title.replace(" - ", " - *")
            self.setWindowTitle(temp_title)
            return
    
        def menu_save(self, module_name):
            self.edit_tree_window.save_file()
            temp_title = self.windowTitle()
            temp_title.replace(" - *", " - ")
            self.setWindowTitle(temp_title)
            return
            
        def menu_add_row(self, tab_name="Tab_1"):
            e_tree_class = ETreeWindw(tab_name, self.current_file_path, self.save_flag)
            e_tree_class.add_row()
        
        def menu_add_child_row(self, tab_name="Tab_1"):
            e_tree_class = ETreeWindw(tab_name, self.current_file_path, self.save_flag)
            e_tree_class.add_child_row()
    
        def menu_remove_row(self, tab_name="Tab_1"):
            e_tree_class = ETreeWindw(tab_name, self.current_file_path, self.save_flag)
            e_tree_class.remove_row()
    
        def tab_changed(self, index):
            self.module_name = self.tabs.tabText(index)
            print(f"Tab changed to {self.tabs.tabText(index)}")
            if self.tabs.tabText(index) == 'Tab_1':
                self.edit_tree_window = ETreeWindw(self.tabs.tabText(index), self.current_file_path, self.save_flag)
                self.horizontal_box_layout = QHBoxLayout()
                self.horizontal_box_layout.addWidget(self.edit_tree_window)
                self.analysis_config_tab.setLayout(self.horizontal_box_layout)
                self.show()
    
    
    if __name__ == '__main__':
        app = QApplication(sys.argv)
        ex = AnaYAMLEditor()
        ex.show()
        sys.exit(app.exec_())
    

    tree_model.py

    from fileinput import filename
    import json
    import sys
    import traceback
    from typing import Any, List, Dict, Union
    import os
    from PySide6.QtWidgets import QTreeView, QApplication
    from PySide6.QtCore import QAbstractItemModel, QModelIndex, QObject, Qt
    from PyQt5.QtGui import *
    from PyQt5.QtCore import *
    from PyQt5.QtWidgets import *
    import yaml
    
    
    class TreeItem:
    
        def __init__(self, parent: "TreeItem" = None):
            self._parent = parent
            self._key = ""
            self._value = ""
            self._comment = ""
            self._key_type = None
            self._value_type = None
            self._comment_type = None
            self._children = []
            self.config = yaml.safe_load(open("input.yaml"))
            self.value_splitter = "###"
    
        def appendChild(self, item: "TreeItem"):
            self._children.append(item)
    
        def child(self, row: int) -> "TreeItem":
            return self._children[row]
    
        def parent(self) -> "TreeItem":
            return self._parent
    
        def childCount(self) -> int:
            return len(self._children)
    
        def row(self) -> int:
            return self._parent._children.index(self) if self._parent else 0
    
        @property
        def key(self) -> str:
            return self._key
    
        @key.setter
        def key(self, key: str):
            self._key = key
        @property
        def key_type(self):
            return self._key_type
    
        @key_type.setter
        def key_type(self, key):
            self._key_type = key
    
        @property
        def value(self) -> str:
            return self._value
    
        @value.setter
        def value(self, value: str):
            self._value = value
    
        @property
        def value_type(self):
            return self._value_type
    
        @value_type.setter
        def value_type(self, value):
            self._value_type = value
    
        @property
        def comment(self) -> str:
            return self._comment
    
        @comment.setter
        def comment(self, comment: str):
            self._comment = comment
    
        @property
        def comment_type(self):
            return self._comment_type
    
        @comment_type.setter
        def comment_type(self, comment):
            self._comment_type = comment
    
    
        @classmethod
        def load(
            cls, value: Union[List, Dict], parent: "TreeItem" = None, sort=False
        ) -> "TreeItem":
    
            try:
                rootItem = TreeItem(parent)
                rootItem.key = "root"
    
                if isinstance(value, dict):
                    items = sorted(value.items()) if sort else value.items()
    
                    for key, value in items:
                        child = cls.load(value, rootItem)
                        child.key = key
                        child.value_type = type(value)
                        rootItem.appendChild(child)
    
                elif isinstance(value, list):
                    for index, value in enumerate(value):
                        child = cls.load(value, rootItem)
                        child.key = index
                        child.value_type = type(value)
                        rootItem.appendChild(child)
    
                else:
                    if isinstance(value, int):
                        value = str(value)
                        rootItem.value = str(value)
                        rootItem.value_type = type(value)
                        rootItem.comment = ""
                        rootItem.comment_type = type(value)
                    elif isinstance(value, str):
                        if not "###" in value:
                            rootItem.value = str(value)
                            rootItem.value_type = type(value)
                            rootItem.comment = ""
                            rootItem.comment_type = type(value)
                        else:
                            rootItem.value = value.split("###")[0]
                            rootItem.value_type = type(value)
                            rootItem.comment = value.split("###")[-1]
                            rootItem.comment_type = type(value)
                    elif isinstance(value, float):
                        rootItem.value = str(value)
                        rootItem.value_type = type(value)
                        rootItem.comment = ""
                        rootItem.comment_type = type(value)
            except Exception as e:
                pass
            finally:
                return rootItem
    
    class JsonModel(QAbstractItemModel):
    
        def __init__(self, module_name, yaml_file_name,save_flag, parent: QObject = None):
            super().__init__(parent)
            self.config = yaml.safe_load(open("input.yaml"))
            self.value_splitter = "###"
            self._rootItem = TreeItem()
            self._headers = ("key", "value", "Comments")
            self._module_name = module_name
            self.yaml_file_name = yaml_file_name
            self.save_flag = save_flag
    
        def clear(self):
            self.load({})
    
        def load(self, document: dict):
    
            try:
                assert isinstance(
                    document, (dict, list, tuple)
                ), "`document` must be of dict, list or tuple, " f"not {type(document)}"
    
                self.beginResetModel()
    
                self._rootItem = TreeItem.load(document)
                self._rootItem.value_type = type(document)
                self.endResetModel()
                
            except Exception:
                pass
                return False
            finally:
                return True
    
        def data(self, index: QModelIndex, role: Qt.ItemDataRole) -> Any:
            if not index.isValid():
                return None
    
            item = index.internalPointer()
    
            if role == Qt.DisplayRole:
                if index.column() == 0:
                    return item.key
    
                if index.column() == 1:
                    return item.value
                
                if index.column() == 2:
                    return item.comment
    
            elif role == Qt.EditRole:
                if index.column() == 1:
                    if self.value_splitter in item.value:
                        QMessageBox.about(self, "Information", f"### is not allowed in value")
                    return item.value
                elif index.column() == 0:
                    return item.key
                elif index.column() == 2:
                    return item.comment
    
        def setData(self, index: QModelIndex, value: Any, role: Qt.ItemDataRole):
            if role == Qt.EditRole:
                                
                if index.column() == 1:
                    item = index.internalPointer()
                    item.value = str(value)
                    self.dataChanged.emit(index, index, [Qt.EditRole])
                    # RK HERE we can write logics to file save ###
                    self.save_data(self._rootItem)
                    return True
                elif index.column() == 0:
                    item = index.internalPointer()
                    item.key = str(value)
                    self.dataChanged.emit(index, index, [Qt.EditRole])
                    self.save_data(self._rootItem)
                    return True
                elif index.column() == 2:
                    item = index.internalPointer()
                    item.comment = str(value)
                    self.dataChanged.emit(index, index, [Qt.EditRole])
                    self.save_data(self._rootItem)
                    return True
    
            return False
    
        def read_json_file(self):
            with open(self.yaml_file_name) as file:
                data = json.load(file)
                return data
    
        def save_data(self, to_write_data):
            _space = "    "
            to_write_dict = {}
            for f_data in to_write_data._children:
                if len(f_data._children) !=0:
                    for _child in f_data._children:
                        _child.comment = _child.comment if not _child.comment is None else ""
                        to_write_dict[f_data.key] = {}
                        _child_value = _child.value 
                        if _space in _child.value:
                            _child_value = _child.value.replace(_space,'')  
                        _child_value = f"{_child.value}{_space}"
                        to_write_dict[f_data.key][_child.key] = _child_value + self.value_splitter + _child.comment.strip()
                else:
                    f_data.comment = f_data.comment if not f_data.comment is None else ""
                    to_write_value = f_data.value 
                    if _space in f_data.value:
                        to_write_value = f_data.value.replace(_space,'')
                    to_write_value = f"{f_data.value}{_space}"
                    to_write_dict[f_data.key] = to_write_value + self.value_splitter +  f_data.comment.strip()
    
            module_dict = {}
            full_file_data = yaml.safe_load(open(self.yaml_file_name))
            if "," in self._module_name:
                main_module = self._module_name.split(",")[0]
                sub_module = self._module_name.split(",")[-1]
                module_dict[main_module] = {}
                module_dict[main_module][sub_module] = to_write_dict
            else:
                module_dict[self._module_name] = to_write_dict
    
            update_file_content = {**full_file_data, **module_dict}
            TreeModelClass._tree_document = to_write_dict
            pass
            if self.save_flag ==1:
                with open(self.yaml_file_name , 'w') as f:
                    yaml.safe_dump(update_file_content, f, indent=4, default_flow_style=False)
    
        def save_dict_data(self, to_write_dict, module_name, save_flag=0):
            module_dict = {}
            full_file_data = yaml.safe_load(open(self.yaml_file_name))
            if "," in self.module_name:
                main_module = self.module_name.split(",")[0]
                sub_module = self.module_name.split(",")[-1]
                module_dict[main_module] = {}
                module_dict[main_module][sub_module] = to_write_dict
            else:
                module_dict[self.module_name] = to_write_dict
            
            update_file_content = {**full_file_data, **module_dict}
            TreeModelClass._tree_document = to_write_dict
            pass
            if self.save_flag ==1 or save_flag ==1:
                with open(self.yaml_file_name , 'w') as f:
                    yaml.safe_dump(update_file_content, f, indent=4, default_flow_style=False)
            
        def headerData(
            self, section: int, orientation: Qt.Orientation, role: Qt.ItemDataRole
        ):
            if role != Qt.DisplayRole:
                return None
    
            if orientation == Qt.Horizontal:
                return self._headers[section]
    
        def index(self, row: int, column: int, parent=QModelIndex()) -> QModelIndex:
            if not self.hasIndex(row, column, parent):
                return QModelIndex()
    
            if not parent.isValid():
                parentItem = self._rootItem
            else:
                parentItem = parent.internalPointer()
    
            childItem = parentItem.child(row)
            if childItem:
                return self.createIndex(row, column, childItem)
            else:
                return QModelIndex()
    
        def parent(self, index: QModelIndex) -> QModelIndex:
    
            if not index.isValid():
                return QModelIndex()
    
            childItem = index.internalPointer()
            parentItem = childItem.parent()
    
            if parentItem == self._rootItem:
                return QModelIndex()
    
            return self.createIndex(parentItem.row(), 0, parentItem)
    
        def rowCount(self, parent=QModelIndex()):
            if parent.column() > 0:
                return 0
    
            if not parent.isValid():
                parentItem = self._rootItem
            else:
                parentItem = parent.internalPointer()
    
            return parentItem.childCount()
    
        def columnCount(self, parent=QModelIndex()):
            return len(self._headers)
    
        def flags(self, index: QModelIndex) -> Qt.ItemFlags:
            flags = super(JsonModel, self).flags(index)
    
            return Qt.ItemIsEditable | flags
    
    
        def to_json(self, item=None):
    
            if item is None:
                item = self._rootItem
    
            nchild = item.childCount()
    
            if item.value_type is dict:
                document = {}
                for i in range(nchild):
                    ch = item.child(i)
                    document[ch.key] = self.to_json(ch)
                return document
    
            elif item.value_type == list:
                document = []
                for i in range(nchild):
                    ch = item.child(i)
                    document.append(self.to_json(ch))
                return document
    
            else:
                return item.value
    
    class TreeModelClass(QWidget):
        def __init__(self, module_name, file_name, save_flag):
            super(TreeModelClass, self).__init__()
            TreeModelClass._tree_document = {}
            self.config = yaml.safe_load(open("input.yaml"))
            self.yaml_file_name = file_name
            self.save_flag = save_flag
    
            # Toolbar menu item
            self.toolbar = QToolBar(self)
            self.add_row_action = QAction("Add Row", self)
            self.add_row_action.triggered.connect(self.add_row)
            self.toolbar.addAction(self.add_row_action)
    
            self.remove_row_action = QAction("Remove Row", self)
            self.remove_row_action.triggered.connect(self.remove_row)
            self.toolbar.addAction(self.remove_row_action)
            self.module_name = 'Heading_data'
            
            self.view = QTreeView()
            self.model = JsonModel(self.module_name, self.yaml_file_name, self.save_flag)
            self.view.setSelectionMode(QAbstractItemView.SingleSelection)
    
            self.json_path = file_name
            
            if not os.path.exists(self.json_path):
                with open(self.json_path, 'w') as f:
                    json.dump({}, f, indent=4)
    
            try:
                TreeModelClass._tree_document = yaml.safe_load(open(file_name))
            except FileNotFoundError:
                QMessageBox.warning(self, "Warning", "Config file not found")
                return
    
            if "," in self.module_name:
                main_module = module_name.split(",")[0]
                sub_module = module_name.split(",")[-1]
                TreeModelClass._tree_document = TreeModelClass._tree_document[main_module][sub_module]
                self.model.load(TreeModelClass._tree_document)
            elif not "," in self.module_name and not self.module_name in TreeModelClass._tree_document:
                QMessageBox.about(self, "Information", f"{self.module_name} is not yet configured")
                return 
            else:
                TreeModelClass._tree_document = TreeModelClass._tree_document[self.module_name]
                self.model.load(TreeModelClass._tree_document)
    
            
            QAbstractItemView.reset(self.view)
            self.view.setModel(self.model)
            self.view.resizeColumnToContents(0)
            self.view.resizeColumnToContents(1)
            self.view.expandAll()
            # create label "Heading"
            self.heading = QLabel("Heading")
            self.heading.setAlignment(Qt.AlignCenter)
    
    
            self.vertical_layout = QVBoxLayout(self)
            self.h_box_layout = QHBoxLayout()
            self.h_box_layout.addWidget(self.toolbar)
            self.vertical_layout.addLayout(self.h_box_layout)
    
            self.h_box_layout = QHBoxLayout()
            self.h_box_layout.addWidget(self.view)
            self.vertical_layout.addLayout(self.h_box_layout)
    
        def save_file(self):
            try:
                class__tree_document = TreeModelClass._tree_document
                JsonModel.save_dict_data(self, class__tree_document, self.module_name, 1)
                self.model.load(self._tree_document)
                try:
                    self.view.setModel(self.model)  
                except Exception:
                    pass
            except Exception:
                pass
        
        def add_row(self):
            try:
                class__tree_document = TreeModelClass._tree_document
                pass
                pass
                temp_document = {"new_key": "value  ###     "}
                if "key" in class__tree_document:
                    QMessageBox.about(self, "Information", f"This key already exists")
                self._tree_document = {**class__tree_document, **temp_document}
                class__tree_document = self._tree_document
                JsonModel.save_dict_data(self, class__tree_document, self.module_name)
                self.model.load(self._tree_document)
                try:
                    self.view.setModel(self.model)  
                except Exception:
                    pass
            except Exception:
                pass
    
    
        def remove_row(self):
            pass
            if len(self.view.selectedIndexes()) == 0:
                QMessageBox.about(self, "Information", f"Please select a row to remove")
                return 
            else:
                class__tree_document = TreeModelClass._tree_document
                if self.view.currentIndex().internalPointer()._value_type == dict:
                    child_temp_dict_key = self.view.currentIndex().internalPointer().key
                    del class__tree_document[child_temp_dict_key]
                    self._tree_document = class__tree_document
                elif self.view.currentIndex().internalPointer()._value_type == str:
                    child_temp_dict_key = self.view.currentIndex().internalPointer().key
                    for _child_dict in class__tree_document:
                        if isinstance(class__tree_document[_child_dict], dict):
                            for _child_dict_key in class__tree_document[_child_dict]:
                                if _child_dict_key == child_temp_dict_key:
                                    if len(class__tree_document[_child_dict]) == 1:
                                        _parent_key = self.view.selectedIndexes()[0].internalPointer()._parent.key
                                        del class__tree_document[_child_dict][_child_dict_key]
                                        break
                                    else:
                                        pass
                                        del class__tree_document[_child_dict][_child_dict_key]
                                        break
                        elif isinstance(class__tree_document[_child_dict], str):
                            if _child_dict == child_temp_dict_key:
                                _parent_key = self.view.selectedIndexes()[0].internalPointer()._parent.key
                                if _parent_key == "root":
                                    del class__tree_document[_child_dict]
                                    break
                                else:
                                    class__tree_document[_parent_key] = class__tree_document[_child_dict]
                                    break
                    self._tree_document = class__tree_document
    
                JsonModel.save_dict_data(self, class__tree_document, self.module_name)
                self.model.load(self._tree_document)
                self.view.setModel(self.model)
    
    
    if __name__ == "__main__":
        app = QApplication(sys.argv)
        window = TreeModelClass()
        app.exec()
    
    

    input.yaml

    Heading_data:
        data_2: '1.3.24        ###'
        data_3: 'asdf            ###this is quote comment'
        data_4: '126        ###'
        working: 'fine    ###'
    
    
    J 1 Reply Last reply 19 Jul 2022, 07:09
    0
    • S sudo_ranjith
      19 Jul 2022, 06:53

      we have an application Yaml editor in which on click on MDI sub window, the Yaml editor sub module gets opened and submodule has multiple tabs and those multiple tabs will have sub tabs. on top of the submodule there is a file menu which has open , save , exit and actions menu which has addrow, remove row etc. addrow should add row in the loaded yaml content inside the tab.

      Direct Question:

      File_1= yamleditor.py

      File_2= treemodel.py

      The problem we face is addrow(), remove row() function works fine when it is inside the Qtreeview model (file_2),but when it is called from a actions menu(file_1) the function gets executed but it is not reflecting in the ui?. The same error occurs in all the action item.

      CODE REF for File_2: https://doc.qt.io/qtforpython/examples/example_widgets_itemviews_jsonmodel.html#json-model-example

      077c9b0d-a325-4989-b778-69486dd5fc3e-image.png

      6c3768f8-69f0-41b6-bf93-05548253e0d8-image.png

      yaml_editor.py

      import sys
      import traceback
      from PyQt5.QtWidgets import QApplication, QWidget, QTreeView, QMessageBox, QVBoxLayout, QLabel, QLineEdit, QComboBox, QListWidget, QHBoxLayout, QPushButton, QFileDialog, QProgressBar, QListView, QAbstractItemView, QTabWidget, QMdiArea, QMainWindow, QMenu, QToolBar, QAction, QFrame
      from PyQt5.QtGui import QIntValidator, QFont
      from PyQt5.QtCore import Qt
      import yaml
      import os
      import json
      from datetime import datetime
      import subprocess
      from threading import *
      from tree_model import TreeModelClass as ETreeWindw
      
      
      class AnaYAMLEditor(QWidget):
          def __init__(self):
              super().__init__()
              self.title = 'YAML Editor'
              self.ui_fields_access = 0
              self.config = yaml.safe_load(open("input.yaml")) 
              self.config_key = 'yaml_editor'
              self.current_file_path = os.getcwd()
              self.module_name = "Tab_1"
              self.save_flag = 0
              try:
                  self.initUI()
                  self.showMaximized()
                  self.show()
              except Exception:
                  print(traceback.format_exc())
      
          def initUI(self):        
              print(f"{self.title} app started at {datetime.now()}")
              self.setWindowTitle(self.title)
      
              self.tabs = QTabWidget()
              self.analysis_config_tab = QWidget()
              self.tabs.addTab(self.analysis_config_tab, "Tab_1")
              
              self.tabs.setCurrentIndex(0)
              self.tabs.currentChanged.connect(self.tab_changed)
      
              
              self.toolbar = QToolBar(self)
              self.file_meu = QPushButton(" File")
              self.actions_menu = QPushButton("Actions")
              self.file_meu.setStyleSheet('''
                  QPushButton{
                      border: none;
                      }
                  QPushButton:menu-indicator{
                      image: none;
                      }
                  QPushButton:hover {
                      background-color: lightgrey;
                      }
                  QPushButton:pressed {
                      background-color: lightgrey;
                      }
                  QPushButton:align{
                      text-align: center;
                      }
      
                  ''')
      
              self.file_meu.setFont(QFont("Arial", 10))
              self.actions_menu.setStyleSheet('''
                  QPushButton{
                      border: none;
                      }
                  QPushButton:menu-indicator{
                      image: none;
                      }
                  QPushButton:hover {
                      background-color: lightgrey;
                      }
                  ''')
              self.actions_menu.setFont(QFont("Arial", 10))
              self.toolbar.addWidget(self.file_meu)
              self.toolbar.addWidget(self.actions_menu)
              
              menu_file = QMenu()
              menu_action = QMenu()
              self.actions_menu.setMenu(menu_action)
              self.file_meu.setMenu(menu_file)
      
              self.file_menu_1 = QAction("Open", self)
              self.file_menu_1.triggered.connect(lambda: self.menu_open(self.module_name))
              self.file_menu_1.setShortcut("Ctrl+O")
              self.file_menu_1.setStatusTip("Open a file")
      
              menu_file.addAction(self.file_menu_1)
      
              self.file_menu_2 = QAction("Open Containing Folder", self)
              menu_file_2 = QMenu()
              menu_file_2.addAction("File Explorer")
              menu_file_2.addAction("cmd")
              menu_file_2.actions()[0].triggered.connect(lambda: self.menu_open_containing_folder(self.module_name))
              menu_file_2.actions()[1].triggered.connect(self.invoke_menu_cmd_thread)
      
      
              self.file_menu_2.setMenu(menu_file_2)
              self.file_menu_2.setStatusTip("Open Containing Folder")
      
              self.file_menu_2.triggered.connect(lambda: self.menu_open_containing_folder(self.module_name))
              menu_file.addAction(self.file_menu_2)
      
              self.file_menu_3 = QAction("Save", self)
              self.file_menu_3.triggered.connect(lambda: self.menu_save(self.module_name))
              menu_file.addAction(self.file_menu_3)
      
              self.file_menu_4 = QAction("Save As", self)
              self.file_menu_4.triggered.connect(lambda: self.menu_save_as(self.module_name))
              menu_file.addAction(self.file_menu_4)
      
              self.file_menu_4 = QAction("Exit", self)
              self.file_menu_4.triggered.connect(self.closeEvent)
              menu_file.addAction(self.file_menu_4)
      
      
              self.actions_menu_1 = QAction("Add Row", self)
              self.actions_menu_1.triggered.connect(lambda: self.menu_add_row(self.module_name))
              menu_action.addAction(self.actions_menu_1)
              self.actions_menu_2 = QAction("Remove Row", self)
              self.actions_menu_2.triggered.connect(lambda: self.menu_remove_row(self.module_name))
              menu_action.addAction(self.actions_menu_2)
              self.actions_menu_3 = QAction("Insert Child Row", self)
              self.actions_menu_3.triggered.connect(lambda: self.menu_add_child_row(self.module_name))
              menu_action.addAction(self.actions_menu_3)
              
      
              self.vertical_layout = QVBoxLayout(self)
              self.vertical_layout.setAlignment(Qt.AlignTop | Qt.AlignLeft)
      
      
              self.h_box_layout = QHBoxLayout(self)
              self.h_box_layout.setAlignment(Qt.AlignTop | Qt.AlignLeft)
              self.h_box_layout.addWidget(self.toolbar)
      
              
              self.vertical_layout.addLayout(self.h_box_layout)
      
              self.horizontal_line = QFrame()
              self.horizontal_line.setFrameShape(QFrame.HLine)
              self.horizontal_line.setFrameShadow(QFrame.Sunken)
              self.vertical_layout.addWidget(self.horizontal_line)
      
              self.h_box_layout = QHBoxLayout()
              self.h_box_layout.addWidget(self.tabs)
              self.vertical_layout.addLayout(self.h_box_layout)
      
              self.vertical_layout.setContentsMargins(0, 0, 0, 0)
              self.setWindowTitle(self.title)
              self.show()
      
      
      
          def menu_open(self, module_name):
              file_path = QFileDialog.getOpenFileName(self, 'Open File', '', "All Files (*)")
              print(file_path)
              if file_path[0] != '':
                  self.current_file_path = file_path[0]
                  self.setWindowTitle(f"{self.title} - {file_path[0]}")
                  self.edit_tree_window = ETreeWindw(self.module_name, self.current_file_path, self.save_flag)
                  self.horizontal_box_layout = QHBoxLayout()
                  self.horizontal_box_layout.addWidget(self.edit_tree_window)
                  self.analysis_config_tab.setLayout(self.horizontal_box_layout)
      
                  self.h_box_layout = QHBoxLayout()
                  self.h_box_layout.addWidget(self.tabs)
                  self.vertical_layout.addLayout(self.h_box_layout)
                  self.show()
      
          def menu_open_containing_folder(self, module_name):
              FILEBROWSER_PATH = os.path.join(os.getenv('WINDIR'), 'explorer.exe')
              subprocess.run([FILEBROWSER_PATH, '/select,', os.path.normpath(self.current_file_path)])
              return
      
          def invoke_menu_cmd_thread(self):
              self.t1 = Thread(target=self.menu_open_cmd)
              self.t1.start()
      
          def menu_open_cmd(self):
              os.system("start cmd /K ")
              os.system("pause")
              return
      
          def update_window_title_edited(self):
              temp_title = self.windowTitle()
              temp_title.replace(" - ", " - *")
              self.setWindowTitle(temp_title)
              return
      
          def menu_save(self, module_name):
              self.edit_tree_window.save_file()
              temp_title = self.windowTitle()
              temp_title.replace(" - *", " - ")
              self.setWindowTitle(temp_title)
              return
              
          def menu_add_row(self, tab_name="Tab_1"):
              e_tree_class = ETreeWindw(tab_name, self.current_file_path, self.save_flag)
              e_tree_class.add_row()
          
          def menu_add_child_row(self, tab_name="Tab_1"):
              e_tree_class = ETreeWindw(tab_name, self.current_file_path, self.save_flag)
              e_tree_class.add_child_row()
      
          def menu_remove_row(self, tab_name="Tab_1"):
              e_tree_class = ETreeWindw(tab_name, self.current_file_path, self.save_flag)
              e_tree_class.remove_row()
      
          def tab_changed(self, index):
              self.module_name = self.tabs.tabText(index)
              print(f"Tab changed to {self.tabs.tabText(index)}")
              if self.tabs.tabText(index) == 'Tab_1':
                  self.edit_tree_window = ETreeWindw(self.tabs.tabText(index), self.current_file_path, self.save_flag)
                  self.horizontal_box_layout = QHBoxLayout()
                  self.horizontal_box_layout.addWidget(self.edit_tree_window)
                  self.analysis_config_tab.setLayout(self.horizontal_box_layout)
                  self.show()
      
      
      if __name__ == '__main__':
          app = QApplication(sys.argv)
          ex = AnaYAMLEditor()
          ex.show()
          sys.exit(app.exec_())
      

      tree_model.py

      from fileinput import filename
      import json
      import sys
      import traceback
      from typing import Any, List, Dict, Union
      import os
      from PySide6.QtWidgets import QTreeView, QApplication
      from PySide6.QtCore import QAbstractItemModel, QModelIndex, QObject, Qt
      from PyQt5.QtGui import *
      from PyQt5.QtCore import *
      from PyQt5.QtWidgets import *
      import yaml
      
      
      class TreeItem:
      
          def __init__(self, parent: "TreeItem" = None):
              self._parent = parent
              self._key = ""
              self._value = ""
              self._comment = ""
              self._key_type = None
              self._value_type = None
              self._comment_type = None
              self._children = []
              self.config = yaml.safe_load(open("input.yaml"))
              self.value_splitter = "###"
      
          def appendChild(self, item: "TreeItem"):
              self._children.append(item)
      
          def child(self, row: int) -> "TreeItem":
              return self._children[row]
      
          def parent(self) -> "TreeItem":
              return self._parent
      
          def childCount(self) -> int:
              return len(self._children)
      
          def row(self) -> int:
              return self._parent._children.index(self) if self._parent else 0
      
          @property
          def key(self) -> str:
              return self._key
      
          @key.setter
          def key(self, key: str):
              self._key = key
          @property
          def key_type(self):
              return self._key_type
      
          @key_type.setter
          def key_type(self, key):
              self._key_type = key
      
          @property
          def value(self) -> str:
              return self._value
      
          @value.setter
          def value(self, value: str):
              self._value = value
      
          @property
          def value_type(self):
              return self._value_type
      
          @value_type.setter
          def value_type(self, value):
              self._value_type = value
      
          @property
          def comment(self) -> str:
              return self._comment
      
          @comment.setter
          def comment(self, comment: str):
              self._comment = comment
      
          @property
          def comment_type(self):
              return self._comment_type
      
          @comment_type.setter
          def comment_type(self, comment):
              self._comment_type = comment
      
      
          @classmethod
          def load(
              cls, value: Union[List, Dict], parent: "TreeItem" = None, sort=False
          ) -> "TreeItem":
      
              try:
                  rootItem = TreeItem(parent)
                  rootItem.key = "root"
      
                  if isinstance(value, dict):
                      items = sorted(value.items()) if sort else value.items()
      
                      for key, value in items:
                          child = cls.load(value, rootItem)
                          child.key = key
                          child.value_type = type(value)
                          rootItem.appendChild(child)
      
                  elif isinstance(value, list):
                      for index, value in enumerate(value):
                          child = cls.load(value, rootItem)
                          child.key = index
                          child.value_type = type(value)
                          rootItem.appendChild(child)
      
                  else:
                      if isinstance(value, int):
                          value = str(value)
                          rootItem.value = str(value)
                          rootItem.value_type = type(value)
                          rootItem.comment = ""
                          rootItem.comment_type = type(value)
                      elif isinstance(value, str):
                          if not "###" in value:
                              rootItem.value = str(value)
                              rootItem.value_type = type(value)
                              rootItem.comment = ""
                              rootItem.comment_type = type(value)
                          else:
                              rootItem.value = value.split("###")[0]
                              rootItem.value_type = type(value)
                              rootItem.comment = value.split("###")[-1]
                              rootItem.comment_type = type(value)
                      elif isinstance(value, float):
                          rootItem.value = str(value)
                          rootItem.value_type = type(value)
                          rootItem.comment = ""
                          rootItem.comment_type = type(value)
              except Exception as e:
                  pass
              finally:
                  return rootItem
      
      class JsonModel(QAbstractItemModel):
      
          def __init__(self, module_name, yaml_file_name,save_flag, parent: QObject = None):
              super().__init__(parent)
              self.config = yaml.safe_load(open("input.yaml"))
              self.value_splitter = "###"
              self._rootItem = TreeItem()
              self._headers = ("key", "value", "Comments")
              self._module_name = module_name
              self.yaml_file_name = yaml_file_name
              self.save_flag = save_flag
      
          def clear(self):
              self.load({})
      
          def load(self, document: dict):
      
              try:
                  assert isinstance(
                      document, (dict, list, tuple)
                  ), "`document` must be of dict, list or tuple, " f"not {type(document)}"
      
                  self.beginResetModel()
      
                  self._rootItem = TreeItem.load(document)
                  self._rootItem.value_type = type(document)
                  self.endResetModel()
                  
              except Exception:
                  pass
                  return False
              finally:
                  return True
      
          def data(self, index: QModelIndex, role: Qt.ItemDataRole) -> Any:
              if not index.isValid():
                  return None
      
              item = index.internalPointer()
      
              if role == Qt.DisplayRole:
                  if index.column() == 0:
                      return item.key
      
                  if index.column() == 1:
                      return item.value
                  
                  if index.column() == 2:
                      return item.comment
      
              elif role == Qt.EditRole:
                  if index.column() == 1:
                      if self.value_splitter in item.value:
                          QMessageBox.about(self, "Information", f"### is not allowed in value")
                      return item.value
                  elif index.column() == 0:
                      return item.key
                  elif index.column() == 2:
                      return item.comment
      
          def setData(self, index: QModelIndex, value: Any, role: Qt.ItemDataRole):
              if role == Qt.EditRole:
                                  
                  if index.column() == 1:
                      item = index.internalPointer()
                      item.value = str(value)
                      self.dataChanged.emit(index, index, [Qt.EditRole])
                      # RK HERE we can write logics to file save ###
                      self.save_data(self._rootItem)
                      return True
                  elif index.column() == 0:
                      item = index.internalPointer()
                      item.key = str(value)
                      self.dataChanged.emit(index, index, [Qt.EditRole])
                      self.save_data(self._rootItem)
                      return True
                  elif index.column() == 2:
                      item = index.internalPointer()
                      item.comment = str(value)
                      self.dataChanged.emit(index, index, [Qt.EditRole])
                      self.save_data(self._rootItem)
                      return True
      
              return False
      
          def read_json_file(self):
              with open(self.yaml_file_name) as file:
                  data = json.load(file)
                  return data
      
          def save_data(self, to_write_data):
              _space = "    "
              to_write_dict = {}
              for f_data in to_write_data._children:
                  if len(f_data._children) !=0:
                      for _child in f_data._children:
                          _child.comment = _child.comment if not _child.comment is None else ""
                          to_write_dict[f_data.key] = {}
                          _child_value = _child.value 
                          if _space in _child.value:
                              _child_value = _child.value.replace(_space,'')  
                          _child_value = f"{_child.value}{_space}"
                          to_write_dict[f_data.key][_child.key] = _child_value + self.value_splitter + _child.comment.strip()
                  else:
                      f_data.comment = f_data.comment if not f_data.comment is None else ""
                      to_write_value = f_data.value 
                      if _space in f_data.value:
                          to_write_value = f_data.value.replace(_space,'')
                      to_write_value = f"{f_data.value}{_space}"
                      to_write_dict[f_data.key] = to_write_value + self.value_splitter +  f_data.comment.strip()
      
              module_dict = {}
              full_file_data = yaml.safe_load(open(self.yaml_file_name))
              if "," in self._module_name:
                  main_module = self._module_name.split(",")[0]
                  sub_module = self._module_name.split(",")[-1]
                  module_dict[main_module] = {}
                  module_dict[main_module][sub_module] = to_write_dict
              else:
                  module_dict[self._module_name] = to_write_dict
      
              update_file_content = {**full_file_data, **module_dict}
              TreeModelClass._tree_document = to_write_dict
              pass
              if self.save_flag ==1:
                  with open(self.yaml_file_name , 'w') as f:
                      yaml.safe_dump(update_file_content, f, indent=4, default_flow_style=False)
      
          def save_dict_data(self, to_write_dict, module_name, save_flag=0):
              module_dict = {}
              full_file_data = yaml.safe_load(open(self.yaml_file_name))
              if "," in self.module_name:
                  main_module = self.module_name.split(",")[0]
                  sub_module = self.module_name.split(",")[-1]
                  module_dict[main_module] = {}
                  module_dict[main_module][sub_module] = to_write_dict
              else:
                  module_dict[self.module_name] = to_write_dict
              
              update_file_content = {**full_file_data, **module_dict}
              TreeModelClass._tree_document = to_write_dict
              pass
              if self.save_flag ==1 or save_flag ==1:
                  with open(self.yaml_file_name , 'w') as f:
                      yaml.safe_dump(update_file_content, f, indent=4, default_flow_style=False)
              
          def headerData(
              self, section: int, orientation: Qt.Orientation, role: Qt.ItemDataRole
          ):
              if role != Qt.DisplayRole:
                  return None
      
              if orientation == Qt.Horizontal:
                  return self._headers[section]
      
          def index(self, row: int, column: int, parent=QModelIndex()) -> QModelIndex:
              if not self.hasIndex(row, column, parent):
                  return QModelIndex()
      
              if not parent.isValid():
                  parentItem = self._rootItem
              else:
                  parentItem = parent.internalPointer()
      
              childItem = parentItem.child(row)
              if childItem:
                  return self.createIndex(row, column, childItem)
              else:
                  return QModelIndex()
      
          def parent(self, index: QModelIndex) -> QModelIndex:
      
              if not index.isValid():
                  return QModelIndex()
      
              childItem = index.internalPointer()
              parentItem = childItem.parent()
      
              if parentItem == self._rootItem:
                  return QModelIndex()
      
              return self.createIndex(parentItem.row(), 0, parentItem)
      
          def rowCount(self, parent=QModelIndex()):
              if parent.column() > 0:
                  return 0
      
              if not parent.isValid():
                  parentItem = self._rootItem
              else:
                  parentItem = parent.internalPointer()
      
              return parentItem.childCount()
      
          def columnCount(self, parent=QModelIndex()):
              return len(self._headers)
      
          def flags(self, index: QModelIndex) -> Qt.ItemFlags:
              flags = super(JsonModel, self).flags(index)
      
              return Qt.ItemIsEditable | flags
      
      
          def to_json(self, item=None):
      
              if item is None:
                  item = self._rootItem
      
              nchild = item.childCount()
      
              if item.value_type is dict:
                  document = {}
                  for i in range(nchild):
                      ch = item.child(i)
                      document[ch.key] = self.to_json(ch)
                  return document
      
              elif item.value_type == list:
                  document = []
                  for i in range(nchild):
                      ch = item.child(i)
                      document.append(self.to_json(ch))
                  return document
      
              else:
                  return item.value
      
      class TreeModelClass(QWidget):
          def __init__(self, module_name, file_name, save_flag):
              super(TreeModelClass, self).__init__()
              TreeModelClass._tree_document = {}
              self.config = yaml.safe_load(open("input.yaml"))
              self.yaml_file_name = file_name
              self.save_flag = save_flag
      
              # Toolbar menu item
              self.toolbar = QToolBar(self)
              self.add_row_action = QAction("Add Row", self)
              self.add_row_action.triggered.connect(self.add_row)
              self.toolbar.addAction(self.add_row_action)
      
              self.remove_row_action = QAction("Remove Row", self)
              self.remove_row_action.triggered.connect(self.remove_row)
              self.toolbar.addAction(self.remove_row_action)
              self.module_name = 'Heading_data'
              
              self.view = QTreeView()
              self.model = JsonModel(self.module_name, self.yaml_file_name, self.save_flag)
              self.view.setSelectionMode(QAbstractItemView.SingleSelection)
      
              self.json_path = file_name
              
              if not os.path.exists(self.json_path):
                  with open(self.json_path, 'w') as f:
                      json.dump({}, f, indent=4)
      
              try:
                  TreeModelClass._tree_document = yaml.safe_load(open(file_name))
              except FileNotFoundError:
                  QMessageBox.warning(self, "Warning", "Config file not found")
                  return
      
              if "," in self.module_name:
                  main_module = module_name.split(",")[0]
                  sub_module = module_name.split(",")[-1]
                  TreeModelClass._tree_document = TreeModelClass._tree_document[main_module][sub_module]
                  self.model.load(TreeModelClass._tree_document)
              elif not "," in self.module_name and not self.module_name in TreeModelClass._tree_document:
                  QMessageBox.about(self, "Information", f"{self.module_name} is not yet configured")
                  return 
              else:
                  TreeModelClass._tree_document = TreeModelClass._tree_document[self.module_name]
                  self.model.load(TreeModelClass._tree_document)
      
              
              QAbstractItemView.reset(self.view)
              self.view.setModel(self.model)
              self.view.resizeColumnToContents(0)
              self.view.resizeColumnToContents(1)
              self.view.expandAll()
              # create label "Heading"
              self.heading = QLabel("Heading")
              self.heading.setAlignment(Qt.AlignCenter)
      
      
              self.vertical_layout = QVBoxLayout(self)
              self.h_box_layout = QHBoxLayout()
              self.h_box_layout.addWidget(self.toolbar)
              self.vertical_layout.addLayout(self.h_box_layout)
      
              self.h_box_layout = QHBoxLayout()
              self.h_box_layout.addWidget(self.view)
              self.vertical_layout.addLayout(self.h_box_layout)
      
          def save_file(self):
              try:
                  class__tree_document = TreeModelClass._tree_document
                  JsonModel.save_dict_data(self, class__tree_document, self.module_name, 1)
                  self.model.load(self._tree_document)
                  try:
                      self.view.setModel(self.model)  
                  except Exception:
                      pass
              except Exception:
                  pass
          
          def add_row(self):
              try:
                  class__tree_document = TreeModelClass._tree_document
                  pass
                  pass
                  temp_document = {"new_key": "value  ###     "}
                  if "key" in class__tree_document:
                      QMessageBox.about(self, "Information", f"This key already exists")
                  self._tree_document = {**class__tree_document, **temp_document}
                  class__tree_document = self._tree_document
                  JsonModel.save_dict_data(self, class__tree_document, self.module_name)
                  self.model.load(self._tree_document)
                  try:
                      self.view.setModel(self.model)  
                  except Exception:
                      pass
              except Exception:
                  pass
      
      
          def remove_row(self):
              pass
              if len(self.view.selectedIndexes()) == 0:
                  QMessageBox.about(self, "Information", f"Please select a row to remove")
                  return 
              else:
                  class__tree_document = TreeModelClass._tree_document
                  if self.view.currentIndex().internalPointer()._value_type == dict:
                      child_temp_dict_key = self.view.currentIndex().internalPointer().key
                      del class__tree_document[child_temp_dict_key]
                      self._tree_document = class__tree_document
                  elif self.view.currentIndex().internalPointer()._value_type == str:
                      child_temp_dict_key = self.view.currentIndex().internalPointer().key
                      for _child_dict in class__tree_document:
                          if isinstance(class__tree_document[_child_dict], dict):
                              for _child_dict_key in class__tree_document[_child_dict]:
                                  if _child_dict_key == child_temp_dict_key:
                                      if len(class__tree_document[_child_dict]) == 1:
                                          _parent_key = self.view.selectedIndexes()[0].internalPointer()._parent.key
                                          del class__tree_document[_child_dict][_child_dict_key]
                                          break
                                      else:
                                          pass
                                          del class__tree_document[_child_dict][_child_dict_key]
                                          break
                          elif isinstance(class__tree_document[_child_dict], str):
                              if _child_dict == child_temp_dict_key:
                                  _parent_key = self.view.selectedIndexes()[0].internalPointer()._parent.key
                                  if _parent_key == "root":
                                      del class__tree_document[_child_dict]
                                      break
                                  else:
                                      class__tree_document[_parent_key] = class__tree_document[_child_dict]
                                      break
                      self._tree_document = class__tree_document
      
                  JsonModel.save_dict_data(self, class__tree_document, self.module_name)
                  self.model.load(self._tree_document)
                  self.view.setModel(self.model)
      
      
      if __name__ == "__main__":
          app = QApplication(sys.argv)
          window = TreeModelClass()
          app.exec()
      
      

      input.yaml

      Heading_data:
          data_2: '1.3.24        ###'
          data_3: 'asdf            ###this is quote comment'
          data_4: '126        ###'
          working: 'fine    ###'
      
      
      J Offline
      J Offline
      JonB
      wrote on 19 Jul 2022, 07:09 last edited by
      #2

      @sudo_ranjith
      Hello and welcome.

      So you are saying the code works OK for "file 2", whose code you post, but not for "file 1", whose code you do not post?

      You really need to show non-working code. Actual code, if it's not identical to an example you quote, and preferably some minimal reproducible example where you have stripped out all the irrelevant stuff for others to wade through so that we only have to look at whatever is not working.

      S 2 Replies Last reply 19 Jul 2022, 08:40
      1
      • J JonB
        19 Jul 2022, 07:09

        @sudo_ranjith
        Hello and welcome.

        So you are saying the code works OK for "file 2", whose code you post, but not for "file 1", whose code you do not post?

        You really need to show non-working code. Actual code, if it's not identical to an example you quote, and preferably some minimal reproducible example where you have stripped out all the irrelevant stuff for others to wade through so that we only have to look at whatever is not working.

        S Offline
        S Offline
        sudo_ranjith
        wrote on 19 Jul 2022, 08:40 last edited by
        #3

        @JonB I have added code snippet in the question, could you please check and help

        J 1 Reply Last reply 19 Jul 2022, 09:00
        0
        • S sudo_ranjith
          19 Jul 2022, 08:40

          @JonB I have added code snippet in the question, could you please check and help

          J Offline
          J Offline
          JonB
          wrote on 19 Jul 2022, 09:00 last edited by JonB
          #4

          @sudo_ranjith
          You have now pasted 700+ lines of code. Full of things including threads, OS commands, goodness knows what else. Sorry, but this is not for me, maybe someone else will choose to look through and figure. A minimal reproducible example means removing all extraneous code till you have the minimum which reproduces an issue, not just pasting the totality of what you have --- at which point you might even spot it yourself....

          A couple of observations:

                      class__tree_document = self._tree_document
                      JsonModel.save_dict_data(self, class__tree_document, self.module_name)
                      self.model.load(self._tree_document)
          

          Verify whether the final self._tree_document contains the newly inserted data.

                      except Exception:
                          pass
          

          You have this all over the place in your code. It means if, for whatever reason, there is an error you simply ignore it, do not report, and we/you would have no idea there has been a problem. This is dangerous at the best of times in Python, and certainly is inadvisable during development.

          TreeModelClass._tree_document = {}
          

          Perhaps not related to your issue, but why would you want to store the document to be used as a singleton class variable? I cannot imagine why you would not want it as a member variable.

          S 1 Reply Last reply 19 Jul 2022, 15:46
          1
          • J JonB
            19 Jul 2022, 07:09

            @sudo_ranjith
            Hello and welcome.

            So you are saying the code works OK for "file 2", whose code you post, but not for "file 1", whose code you do not post?

            You really need to show non-working code. Actual code, if it's not identical to an example you quote, and preferably some minimal reproducible example where you have stripped out all the irrelevant stuff for others to wade through so that we only have to look at whatever is not working.

            S Offline
            S Offline
            sudo_ranjith
            wrote on 19 Jul 2022, 09:04 last edited by
            #5

            @JonB
            Please follow steps to reproduce the issue:

            1. download 3 code and save in a file

            2. run the yaml_editor.py file you should see the UI like this
              853df505-2a96-40a5-9913-623881be6f75-image.png

            3. click on the file -> open -> choose "input.yaml"
              a4f8bf32-49bb-4ed3-81a5-f4f74fbe1618-image.png

            4. click on Add row button - it will work (add new row)
              3ff36fe4-31c3-4022-9a4a-4a6e8836cb11-image.png

            2161c16d-0849-47b7-9d13-9e34f768e32c-image.png

            1. When you click on "Actions" -> "Add row" nothing will happen in the UI but backend functions will be invoked.

            Note: "Point 5" is the exact problem that I'm facing.
            Thanks in advance.

            1 Reply Last reply
            0
            • J JonB
              19 Jul 2022, 09:00

              @sudo_ranjith
              You have now pasted 700+ lines of code. Full of things including threads, OS commands, goodness knows what else. Sorry, but this is not for me, maybe someone else will choose to look through and figure. A minimal reproducible example means removing all extraneous code till you have the minimum which reproduces an issue, not just pasting the totality of what you have --- at which point you might even spot it yourself....

              A couple of observations:

                          class__tree_document = self._tree_document
                          JsonModel.save_dict_data(self, class__tree_document, self.module_name)
                          self.model.load(self._tree_document)
              

              Verify whether the final self._tree_document contains the newly inserted data.

                          except Exception:
                              pass
              

              You have this all over the place in your code. It means if, for whatever reason, there is an error you simply ignore it, do not report, and we/you would have no idea there has been a problem. This is dangerous at the best of times in Python, and certainly is inadvisable during development.

              TreeModelClass._tree_document = {}
              

              Perhaps not related to your issue, but why would you want to store the document to be used as a singleton class variable? I cannot imagine why you would not want it as a member variable.

              S Offline
              S Offline
              sudo_ranjith
              wrote on 19 Jul 2022, 15:46 last edited by
              #6

              @JonB

              self._tree_document contains the newly inserted data, but while loading the screen it was not populating the data.
              I'm still investigating this issue.

              Note:
              Actually, I have reduced a lot of code (I tried to reduce the number of code that you see), and I have added exceptions and logger in the code base, I thought it might not be relevant for the question so I removed many items.

              Anyway, thank you so much for your time.
              I really appreciate your efforts,
              Have a great day.

              J 1 Reply Last reply 19 Jul 2022, 17:11
              0
              • S sudo_ranjith
                19 Jul 2022, 15:46

                @JonB

                self._tree_document contains the newly inserted data, but while loading the screen it was not populating the data.
                I'm still investigating this issue.

                Note:
                Actually, I have reduced a lot of code (I tried to reduce the number of code that you see), and I have added exceptions and logger in the code base, I thought it might not be relevant for the question so I removed many items.

                Anyway, thank you so much for your time.
                I really appreciate your efforts,
                Have a great day.

                J Offline
                J Offline
                JonB
                wrote on 19 Jul 2022, 17:11 last edited by
                #7

                @sudo_ranjith said in PYQT5 - UI Function working for Layout 1 not for Layout 2:

                self._tree_document contains the newly inserted data

                Does it? I pointed out you seem to be using TreeModelClass._tree_document....

                1 Reply Last reply
                0

                4/7

                19 Jul 2022, 09:00

                • Login

                • Login or register to search.
                4 out of 7
                • First post
                  4/7
                  Last post
                0
                • Categories
                • Recent
                • Tags
                • Popular
                • Users
                • Groups
                • Search
                • Get Qt Extensions
                • Unsolved