I have an embedded Jupyter console in a PyQt5 application implemented using the RichJupyterWidget widget available here.
The console integration itself works fine, the Jupyter console is embedded in a Widget, Python code can be executed and the result is displayed within the console itself.
What I need to do, however, is whenever I run some code that returns a Pandas  DataFrame display it in a TableView outside the console.
Here is a working example of my implementation:
import sys
from PyQt5.QtWidgets import QMainWindow, QApplication
from qtconsole.inprocess import QtInProcessKernelManager
from qtconsole.rich_jupyter_widget import RichJupyterWidget
class IPythonConsole:
    def __init__(self):
        self._kernel_manager = None
        self._kernel = None
        self._kernel_client = None
        self.start()
    @property
    def kernel_manager(self) -> QtInProcessKernelManager:
        return self._kernel_manager
    @property
    def kernel(self):
        return self._kernel
    @property
    def kernel_client(self):
        return self._kernel_client
    def start(self):
        self._kernel_manager = QtInProcessKernelManager()
        self._kernel_manager.start_kernel()
        self._kernel = self._kernel_manager.kernel
        self._kernel.gui = 'qt'
        self._kernel_client = self._kernel_manager.client()
        self._kernel_client.start_channels()
    def stop(self):
        self._kernel_client.stop_channels()
        self._kernel_manager.shutdown_kernel()
class IPythonWidget(RichJupyterWidget):
    """RichIPythonWidget implementation to integrate the IPython console inside a Qt Widget"""
    def __init__(self):
        super().__init__()
        self._console = IPythonConsole()
        self.kernel_manager = self._console.kernel_manager
        self.kernel_client = self._console.kernel_client
    @property
    def console(self):
        return self._console
    def run_command(self, command_str):
        self.execute(command_str, False, True)
    def close(self):
        self._console.stop()
if __name__ == '__main__':
    app = QApplication(sys.argv)
    main_window = QMainWindow()
    ipython_widget = IPythonWidget()
    main_window.layout().addWidget(ipython_widget)
    main_window.setFixedHeight(768)
    main_window.setFixedWidth(1024)
    ipython_widget.run_command("import pandas as pd\n"
                               "df = pd.DataFrame({'Test': ['a', 'b', 'c']})\n"
                               "df")
    main_window.show()
    sys.exit(app.exec_())
So far I tried to override the following method from RichJupyterWidget:
 def _handle_execute_result(self, msg):
        """Overridden to handle rich data types, like SVG."""
        self.log.debug("execute_result: %s", msg.get('content', ''))
        if self.include_output(msg):
            self.flush_clearoutput()
            content = msg['content']
            prompt_number = content.get('execution_count', 0)
            data = content['data']
            metadata = msg['content']['metadata']
            if 'image/svg+xml' in data:
                self._pre_image_append(msg, prompt_number)
                self._append_svg(data['image/svg+xml'], True)
                self._append_html(self.output_sep2, True)
            elif 'image/png' in data:
            [...]
But unfortunately when returning a DataFrame, msg contains a string with the contents of the DataFrame in HTML format.
Edit
I was able to get the DataFrame object from the kernel shell as follows:
if self.ipython_widget.execute("df = pd.DataFrame({'Test': ['a', 'b', 'c']})\n", False, False):
    df = self.ipython_widget.console.kernel.shell.user_ns.get('df')
Unfortunately, this will only work when I run the code myself, not when the user inputs something in the console and also I must know the name of the variable containing the dataframe.