pyqt5 应用程序中的嵌入式 qtconsole 无法按预期工作

Posted

技术标签:

【中文标题】pyqt5 应用程序中的嵌入式 qtconsole 无法按预期工作【英文标题】:embedded qtconsole in pyqt5 aplication does not works as expected 【发布时间】:2019-05-17 04:30:14 【问题描述】:

我有一个相当大的项目,其中嵌入了 Jupyter QtConsole 4.4.2。

更多详情见: https://github.com/3fon3fonov/trifon

现在,当一些进程正在运行/完成时,我正在尝试向 Qtconsole 发送一些文本并将其用作输出屏幕(反之亦然,我希望 Jupyter 能够控制 GUI如果需要,但这是我稍后必须处理的另一个问题。

问题是“ConsoleWidget”功能的一些内在 似乎不起作用,我找不到原因......

例如在我的主 GUI 代码中:

ConsoleWidget_embed().push_vars('fit':fit) <-- WORKS!   

ConsoleWidget_embed().clear() <-- Does not work!
ConsoleWidget_embed().print_text("Test string")  <-- Does not work!

这是我嵌入到 Qtab 中的代码。

import numpy as np
import sys #,os
from PyQt5 import QtCore, QtGui, QtWidgets, uic

from qtconsole.rich_jupyter_widget import RichJupyterWidget
from qtconsole.inprocess import QtInProcessKernelManager
from qtconsole.console_widget import ConsoleWidget


class ConsoleWidget_embed(RichJupyterWidget,ConsoleWidget):
    global fit

    def __init__(self, customBanner=None, *args, **kwargs):
        super(ConsoleWidget_embed, self).__init__(*args, **kwargs)

        if customBanner is not None:
            self.banner = customBanner

        #self.font_size = 4
        self.kernel_manager =   QtInProcessKernelManager()
        self.kernel_manager.start_kernel(show_banner=True)
        self.kernel_manager.kernel.gui = 'qt'
        self.kernel = self.kernel_manager.kernel
        self.kernel_client = self._kernel_manager.client()
        self.kernel_client.start_channels()

        #self._execute("kernel = %s"%fit, False) 

        def stop():
            self.kernel_client.stop_channels()
            self.kernel_manager.shutdown_kernel()
            self.guisupport.get_app_qt().exit()

        self.exit_requested.connect(stop)


    def push_vars(self, variableDict):
        """
        Given a dictionary containing name / value pairs, push those variables
        to the Jupyter console widget
        """
        self.kernel_manager.kernel.shell.push(variableDict)

    def clear(self):
        """
        Clears the terminal
        """
        self._control.clear()

        # self.kernel_manager

    def print_text(self, text):
        """
        Prints some plain text to the console
        """
        self._append_plain_text(text, before_prompt=False)

    def execute_command(self, command):
        """
        Execute a command in the frame of the console widget
        """
        self._execute(command, False)




if __name__ == "__main__":
    app = QtWidgets.QApplication(sys.argv)
    main = mainWindow()
    main.show()
    sys.exit(app.exec_())  

任何想法都将受到高度赞赏!

一切顺利, 特立丰

【问题讨论】:

【参考方案1】:

您的问题是每次键入ConsoleWidget_embed() 时都会创建ConsoleWidget_embed,而是创建该类的对象并将其设置为该类的属性:

    self.console_widget = ConsoleWidget_embed()
    self.terminal_embeded.addTab(self.console_widget, "Jupyter")

    # ...

def jupiter_push_vars(self):
    global fit        
    self.console_widget.push_vars('fit':fit)   
    self.console_widget.clear()
    self.console_widget.print_text("Test string")

【讨论】:

一如既往的准确!谢谢eyllanesc,我还是想知道我怎么没早点意识到这一点! OK eyllanesc,也许不是这个地方,但既然这个问题已经解决,你能建议如何将变量/对象从“console_widget”“拉”到主小部件吗?例如,如果我在 Jupyter shell 中键入“fit.epoch = 0”以在 gui 中得到它? @TrifonTrifonov 依赖于 qtconsole,不幸的是我不是专家,结论是:qtconsole 必须有一个方法来获取您通过控制台输入的对象,然后解析数据并显示它在 GUI 中。 亲爱的 eyllanesc,你能再次帮助这个线程吗?当我开始一项需要更多时间的工作时,我意识到 qtconsole 正在挂起我的 GUI。我什至打开了一个线程,请参见此处:***.com/questions/54583405/… 但我还没有回复。我确信它应该用 QThread 来完成,但到目前为止,我无法让它工作。

以上是关于pyqt5 应用程序中的嵌入式 qtconsole 无法按预期工作的主要内容,如果未能解决你的问题,请参考以下文章

嵌入 ipython qtconsole 并传递对象

如何在我的应用程序中生成 IPython qtconsole,同时将现有对象传递到该控制台

如何运行连接到 ipython3 实例的 qtconsole?

Jupyter:魔术 %qtconsole 不起作用

为啥我不能在 pyqt5 gui 中嵌入的 matplotlib 颜色图中成功绘制感兴趣区域?

有啥方法可以让浏览器页面避免 Pyqt5 中的重定向?