2015-04-24 54 views
1

我使用Python創建了一個控制檯驅動的Qt應用程序。我不想實現自己的自定義控制檯,而是想嵌入IPython Qt控制檯,但也使其對我的應用程序有響應。例如,我希望輸入到控制檯的某些關鍵字在我的主應用程序中觸發動作。所以我在控制檯中鍵入「dothis」,並在我的應用程序的另一個窗口中顯示一個圖。Coopt IPython Qt控制檯用於我的PyQt應用程序

我見過這些問題的一些問題:this one討論瞭如何將IPython Qt小部件嵌入到應用程序中並傳遞函數,儘管看起來這些函數在IPython內核中執行,而不是在主應用程序的內核中執行。也有this guy,但我不能執行示例中的代碼(這是兩歲),它看起來並不像我想要的那樣做。

有沒有一種方法可以傳入將在我的主內核中執行的函數或方法,或者至少通過與IPython內核通信來模擬這種行爲?有沒有人做過這個?

+0

有[示例](https://github.com/ipython/ipython/blob/3.x/examples/Embedding /inprocess_qtconsole.py)嵌入到同一應用程序中的Qt控制檯和內核的IPython存儲庫中。不過,它從來都不是最穩定或支持得當的東西。如果你只需要觸發某些預定義函數,就可以使用某種RPC機制將它們公開回IPython內核 - 或者準備好像[Pyro 4](https://pythonhosted.org/Pyro4/)一樣的東西,或者簡單的定製事情,如果這符合您的需求。 –

+0

我開始着手將控制檯代碼移植並手動將其集成到我的應用程序中,但我堅持希望我可以保持IPython框架完好無損。 – jeremiahbuddha

回答

3

這就是我想出來的,到目前爲止它工作得很好。我繼承了RichIPythonWidget類,並重載了_execute方法。每當用戶在控制檯中鍵入內容時,我都會根據註冊命令列表進行檢查;如果它匹配一個命令,那麼我執行命令代碼,否則我只是將輸入傳遞給默認的_execute方法。

控制檯代碼:

from IPython.qt.console.rich_ipython_widget import RichIPythonWidget 

class CommandConsole(RichIPythonWidget): 
    """ 
    This is a thin wrapper around IPython's RichIPythonWidget. It's 
    main purpose is to register console commands and intercept 
    them when typed into the console. 

    """ 
    def __init__(self, *args, **kw): 
     kw['kind'] = 'cc' 
     super(CommandConsole, self).__init__(*args, **kw) 
     self.commands = {} 


    def _execute(self, source, hidden): 
     """ 
     Overloaded version of the _execute first checks the console 
     input against registered commands. If it finds a command it 
     executes it, otherwise it passes the input to the back kernel 
     for processing. 

     """ 
     try: 
      possible_cmd = source.split()[0].strip() 
     except: 
      return super(CommandConsole, self)._execute("pass", hidden) 

     if possible_cmd in self.commands.keys(): 
      # Commands return code that is passed to the console for execution. 
      s = self.commands[possible_cmd].execute() 
      return super(CommandConsole, self)._execute(s, hidden) 
     else: 
      # Default back to the original _execute 
      return super(CommandConsole, self)._execute(source, hidden) 


    def register_command(self, name, command): 
     """ 
     This method links the name of a command (name) to the function 
     that should be called when it is typed into the console (command). 

     """ 
     self.commands[name] = command 

示例命令:

from PyQt5.QtCore import pyqtSignal, QObject, QFile 

class SelectCommand(QObject): 
    """ 
    The Select command class. 

    """ 
    # This signal is emitted whenever the command is executed. 
    executed = pyqtSignal(str, dict, name = "selectExecuted") 

    # This is the command as typed into the console. 
    name = "select" 

    def execute(self): 
     """ 
     This method is executed whenever the ``name`` command is issued 
     in the console. 

     """ 
     name = "data description" 
     data = { "data dict" : 0 } 
     # The signal is sent to my Qt Models 
     self.executed.emit(name, data) 
     # This code is executed in the console. 
     return 'print("the select command has been executed")' 
相關問題