【问题标题】:How to make an embedded python interpreter's local space share some variables with global space如何使嵌入式python解释器的本地空间与全局空间共享一些变量
【发布时间】:2016-05-26 21:12:40
【问题描述】:

我在我的 pyside 程序中编写了一个命令行小部件。结构是这样的:

class CommandWidget(QWidget):
  def __init__(self, parent = None):
      super(CommandWidget, self).__init__(parent)
      self.buffer=PyInterp(self)
      self.buffer.initInterpreter(locals())
      self........

class PyInterp(QTextEdit):

    class InteractiveInterpreter(code.InteractiveInterpreter):

        def __init__(self, locals):
            code.InteractiveInterpreter.__init__(self, locals)

        def runIt(self, command):
            code.InteractiveInterpreter.runsource(self, command)

    def __init__(self,  parent = None):
        super(PyInterp,  self).__init__(parent)

我还有一个与其他小部件一起运行的主窗口程序。我的问题是如何在这个解释器的其他小部件类中导入一些函数,运行函数并将结果输出到全局空间。或者换句话说,我想在解释器的本地空间和全局主窗口空间之间共享一些变量。我怎样才能做到这一点?

编辑: 这是我要放入信号的数据类型。

class PosType(QObject):
    def __init__(self, nx, ny, nz, start_pos, type):
        self.nx = nx
        self.ny = ny
        self.nz = nz
        self.start_pos = start_pos
        self.type = type

这是信号。

class PosSig(QObject):
    sig = Signal(PosType)

    def emit_sig(self, pos_data):
        self.sig.emit(pos_data)

这是我想放入解释器的函数,这样当它被调用时会发出一个信号。

def graphene(nx, ny, start_pos):
    pos_info = PosType(nx = nx, ny = ny, nz = None, start_pos = start_pos, type = 1)
    tmp_sig = PosSig()
    tmp_sig.emit_sig(pos_info)
    return

上面的类都在一个名为 ExposeFunc.py 的文件中,我打算在解释器中导入这个 .py 文件,然后调用石墨烯函数发出信号。

在主窗口类中,我有一个插槽。

 def __init__(self):
    #Interpreter Signals :
    possig = PosSig()
    possig.sig.connect(self.createObject)

 @Slot(PosType)
 def createObject(self, pos_info):
     type = pos_info.type
     if type == 1:
        SharedItems.QS._FillData(pos_info.nx, pos_info.ny, start_pos)

     return

【问题讨论】:

    标签: python pyqt pyside


    【解决方案1】:

    有几种机制。如果您有在某个时间点被传递的东西,您可以使用QtCore.Signal()@QtCore.Slot()。您可以将大部分内容放入Signal 中,参见信号/插槽示例。 Qt Signals & Slots Documentation

    另一个我不太熟悉的机制是QQueue 类。需要解决的问题是您正在跨线程传递数据,因此需要保护数据访问。

    信号/槽示例:

    class myDataType(QObject):
        def __init__(self, data):
           self.data = data
        ...
    
    class foo(QObject):
        mySignal = QtCore.Signal(myDataType)
        def __init__(self):
        ...
        def someFunction(self, data):
            mySignal.emit(data)
    
    class bar(QObject):
        def __init__(self):
            self.otherObject = foo()
            self.otherObject.mySignal.connect(self.handler)
    
        @QtCore.Slot(myDataType)
        def handler(self, data):
            do something with data
    

    附录 1:

    假设你有一个QMainWindow

    class myMainWindow(QtGui.QMainWindow):
        mainWindowSignal = QtCore.Signal(QObject)
        def __init__(self, parent, *vargs, **kwargs):
            ...
            self.myCommandWidget = CommandWidget(parent=self)
            self.myCommandButton = QtGui.QPushButton("Press Me")
    
            #This connects the button being clicked to a function.
            self.myCommandButton.clicked.connect(self.button_pressed)
    
            #This connects the Signal we made 'mainWindowSignal' to
            # the do_something Slot in CommandWidget 'myCommandWidget'
            self.mainWindowSignal.connect(self.myCommandWidget.do_something)
    
            #This connects the Signal from 'myCommandWidget' 'dataReady'
            # to Slot 'data_returned' to handle the data
            self.myCommandWidget.dataReady.connect(self.dataReady)
            self.data = "some data"
    
        #We don't have to decorate this, but should
        @QtCore.Slot()
        def button_pressed(self):
            self.mainWindowsSignal.emit(self.data)
    
        @QtCore.Slot(str, int)
        def data_returned(self, strValue, intValue):
            #do something with the data.
            #e.g.
            self.command = strValue
            self.retCode = intValue
    
    
    
    
    class CommandWidget(QWidget):
        dataReady = QtCore.Signal(str, int)
        def __init__(self, parent=None):
            #stuff you had here.
            ...
        @QtCore.Slot(QObject
        def do_something(self, data):
            retStr = self.buffer.... #insert your function calls here
            retInt = self.buffer.... 
            self.dataReady.emit(retValue, retInt)
    

    【讨论】:

    • 感谢您的回答。 Signal/Slot 是一种传递数据的方式,我如何将其他类中定义的一些函数暴露给解释器,然后将结果返回到全局空间?
    • 您可以从解释器发出信号,并在主窗口中将它们连接到插槽/函数(您不需要显式使用插槽,您可以将其连接到任何方法)
    • 我试图实现你的建议,它不起作用。能举个具体的例子吗?
    • 是否可以使用 slot/signal 从嵌入式 python 解释器获取数据?
    • 嗨,对不起,我还没有回复你。您可以发布您尝试过的代码吗?
    猜你喜欢
    • 2012-06-11
    • 2012-01-11
    • 1970-01-01
    • 1970-01-01
    • 2013-12-09
    • 2017-12-20
    • 2019-03-23
    • 2015-04-22
    • 2012-03-13
    相关资源
    最近更新 更多