2017-05-27 47 views
0

我試圖建立一個自定義的python解釋器。如何從無法傳入QObject的類發出信號?

下面是interpreter.py

import sys 
from io import StringIO, IncrementalNewlineDecoder 
from code import InteractiveConsole 
from PyQt5.QtCore import QObject, pyqtSignal, pyqtSlot 
from stream import NewLineIO 

class PythonInterpreter(QObject, InteractiveConsole): 
    output = pyqtSignal(str) 

    def __init__(self): 
     QObject.__init__(self) 
     self.l = {} 
     InteractiveConsole.__init__(self, self.l) 
     self.out = NewLineIO() 
     self.out.output.connect(self.console) 

    def write(self, data): 
     self.output.emit(data) 

    def runcode(self, codez): 
     """ 
     Reimplementation to capture stdout and stderr 
     """ 
     sys.stdout = self.out 
     sys.stderr = self.out 
     sys.excepthook = sys.__excepthook__ 
     result = InteractiveConsole.runcode(self, codez) # Own namespace :(
     sys.stdout = sys.__stdout__ 
     sys.stderr = sys.__stderr__ 
     #self.output.emit(self.out.getvalue()) # Send the output 
     return result 

    @pyqtSlot(str) 
    def console(self, string): 
     self.output.emit(string) 

代碼即可獲得解釋器將輸出發送我不得不創建一個自定義StreamIO類會從每次write()方法被調用的時間內發出。

這裏是stream.py

from io import StringIO 
import sys 
from PyQt5.QtCore import QObject, pyqtSignal 
from signals import PrimitiveSignals 


class NewLineIO(QObject, StringIO): 
    def __init__(self, *args, **kwargs): 
     QObject.__init__(self) 
     StringIO.__init__(self, *args, **kwargs) 
     self.output = PrimitiveSignals() 

    def write(self, s): 
     print(s, file=sys.__stdout__) 
     self.output.signal_str.emit(s) 

然而,出於某種原因,我不能在class NewLineIO實例的QObject。

這是我得到的追溯。

File "G:\Programming\Projects\AlphaDice\alpha_dice\main.py", line 9, in <module> 
    from interpreters import PythonInterpreter 
 File "G:\Programming\Projects\AlphaDice\alpha_dice\interpreters.py", line 5, in <module> 
    from stream import NewLineIO 
 File "G:\Programming\Projects\AlphaDice\alpha_dice\stream.py", line 17, in <module> 
    class NewLineIO(QObject, TestLineIO): 

builtins.TypeError: multiple bases have instance lay-out conflict 

刪除從NewLineIO QObject的暫時解決了這個問題,但我將不再能夠self.out連接到self.console

有沒有辦法讓這段代碼有效?

+0

是什麼PrimitiveSignals? – eyllanesc

+0

它們只是一個包含pyqtSignals的簡單類。所以基本上'signal_str = pyqtSignal(str)'很多。這是爲了以後我需要格式化任何東西。 – daegontaven

+0

NewLineIO類不必從QObject繼承,PrimitiveSignals類應該繼承自QObject – eyllanesc

回答

1

包含的信號必須繼承自QObject的類:

class PrimitiveSignals(QObject): 
    signal_str = pyqtSignal(str) 
    [...] 
    def __init__(self): 
     QObject.__init__(self) 

的NewLineIO類不能繼承自QObject,所以你可以將它修改爲:

class NewLineIO(StringIO): 
    def __init__(self, *args, **kwargs): 
     StringIO.__init__(self, *args, **kwargs) 
     self.output = PrimitiveSignals() 

    def write(self, s): 
     print(s, file=sys.__stdout__) 
     self.output.signal_str.emit(s) 

QObject及其派生類不有連接方法,這些都有信號。您必須更改:

self.out.output.connect(self.console) 

到:

self.out.output.signal_str.connect(self.console) 
相關問題