1

I have written a command line widget in my pyside program. The structure is like this:

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)

I also have a mainwindow program running together with some other widgets. My question is how can i import some functions in other widget class in this interpreter, run the function and output the result to the global space. Or in other words, I want to share some variables between the local space of the interpreter and the global mainwindow space. How can I achieve that ?

EDIT: This is the data type I want to put into a signal.

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

This is the signal.

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

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

This is the function I want to put into the interpreter, so that when it is called it will emit a signal.

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

The above classes are in a file called ExposeFunc.py, and I plan to import this .py file in the interpreter, then call the graphene function to emit the signal.

In the mainwindow class, I have a slot.

 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
Johnnylin
  • 507
  • 2
  • 7
  • 26

1 Answers1

1

There are a couple mechanisms. You can use QtCore.Signal() and @QtCore.Slot() if you have things that are being passed at a certain point. You can put most anything into a Signal see signal/slot example. Qt Signals & Slots Documentation

Another mechanism, which I am less versed in would be the QQueue class. The issue to need to address is that you are passing data across threads so data access needs to be protected.

Signal/Slot example:

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

ADDENDUM 1:

Lets say you have a 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)
Tom Myddeltyn
  • 1,307
  • 1
  • 13
  • 27
  • Thanks for your answer. Signal/Slot is a way to pass data and how can I expose some functions defined in other classes to the interpreter, then return the result to global space ? – Johnnylin May 20 '16 at 02:32
  • You can emit signals from the interpreter and connect them in the mainWindow to Slots/functions (you do not need to explicitly use Slots you can connect it to any method) – Tom Myddeltyn May 20 '16 at 12:39
  • I tried to implement what you suggest, it does not work. can you give me a concrete example? – Johnnylin May 26 '16 at 01:36
  • Is it possible to get data from the embedded python interpreter using slot/signal? – Johnnylin May 26 '16 at 03:42
  • Hi Sorry I haven't gotten back to you yet. Can you post the code that you tried? – Tom Myddeltyn May 26 '16 at 12:29