code: def __init__(self, jdata: Union[list, dict], parent=None):
      super().__init__(parent)
  
      self.jdata = jdata
  
      self.search_mode: Literal["filter", "highlight"] = "filter"
  
      self.search_mode_picker = QtWidgets.QComboBox()
      self.search_mode_picker.addItems(["filter", "highlight"])
      self.search_mode_picker.currentTextChanged.connect(
          lambda text: [
              self.__setattr__("search_mode", text),
              self.find(),
          ]
      )
  
      self.find_box = QtWidgets.QLineEdit()
      self.find_box.returnPressed.connect(self.find)
      self.find_box.textChanged.connect(self.find)
      self.find_box.setPlaceholderText("Find regex")
  
      self.tree_widget = base_widgets.QTreeWidget()
      self.tree_widget.setHeaderLabels(["Key", "Value"])
  
      root_item = self.tree_widget.invisibleRootItem()
      self.recurse_jdata(jdata, root_item)
      self.tree_widget.addTopLevelItem(root_item)
      self.tree_widget.expandAll()
  
      # We call .find after collapse because it will re-expand highlighted items (matching the find_box text)
      self.expand_all = QtWidgets.QPushButton("Expand All")
      self.expand_all.clicked.connect(
          lambda: [self.tree_widget.expandAll(), self.find()]
      )
      self.collapse_all = QtWidgets.QPushButton("Collapse All")
      self.collapse_all.clicked.connect(
          lambda: [self.tree_widget.collapseAll(), self.find()]
      )
  
      top_section = QtWidgets.QHBoxLayout()
      top_section.addWidget(self.find_box)
      top_section.addWidget(self.search_mode_picker)
      top_section.addWidget(self.expand_all)
      top_section.addWidget(self.collapse_all)
  
      main_view_layout = QtWidgets.QVBoxLayout()
      main_view_layout.addLayout(top_section)
      main_view_layout.addWidget(self.tree_widget)
  
      main_view = QtWidgets.QWidget()
      main_view.setLayout(main_view_layout)
  
      summary_view = QtWidgets.QTextEdit()
      summary_view.setReadOnly(True)
      summary_view.setText(summarize_json(jdata))
  
      font = QtGui.QFont("Monospace")
      font.setStyleHint(QtGui.QFont.TypeWriter)
      summary_view.setFont(font)
  
      self.tabs = QtWidgets.QTabWidget()
      self.tabs.addTab(main_view, "Viewer")
      self.tabs.addTab(summary_view, "Structure")
  
      layout = QtWidgets.QVBoxLayout()
      layout.addWidget(self.tabs)
  
      self.setLayout(layout)
      self.resize(QtCore.QSize(400, 500))
  
      self.tree_widget.setSelectionMode(
          QtWidgets.QTreeWidget.ExtendedSelection
      )
  
file_path: PandasGUI/pandasgui/widgets/json_viewer.py
imports: import sys
  from typing import Union, List
  from PyQt5 import QtCore, QtGui, QtWidgets
  from pandasgui.store import PandasGuiStoreItem
  from pandasgui.utility import summarize_json, traverse_tree_widget
  from pandasgui.widgets import base_widgets
label_desc: Use image node_id 1 to create a new JsonViewer object from inherited base classes: QtWidgets, PandasGuiStoreItem with example: obj = JsonViewer(jdata, parent)