2013-03-11 79 views
1

我花了很多年尋找一種方法來做到這一點,我迄今爲止沒有任何東西。 :(蟒蛇,快速和林間空地,在TextView中顯示標準輸出

我想爲我製作的一個小小的CLI程序製作一個圖形用戶界面 - 所以我認爲使用Ubuntu的「快速」將是最簡單的方法,基本上它似乎使用Glade製作GUI。我知道我需要在一個子進程中運行我的CLI後端,然後將stdout和stderr發送到一個textview,但我不知道如何做到這一點。我想要的輸出出現在對話框中:

from gi.repository import Gtk # pylint: disable=E0611 

from onice_lib.helpers import get_builder 

import gettext 
from gettext import gettext as _ 
gettext.textdomain('onice') 

class BackupDialog(Gtk.Dialog): 
    __gtype_name__ = "BackupDialog" 

    def __new__(cls): 
     """Special static method that's automatically called by Python when 
     constructing a new instance of this class. 

     Returns a fully instantiated BackupDialog object. 
     """ 
     builder = get_builder('BackupDialog') 
     new_object = builder.get_object('backup_dialog') 
     new_object.finish_initializing(builder) 
     return new_object 

    def finish_initializing(self, builder): 
     """Called when we're finished initializing. 

     finish_initalizing should be called after parsing the ui definition 
     and creating a BackupDialog object with it in order to 
     finish initializing the start of the new BackupDialog 
     instance. 
     """ 
     # Get a reference to the builder and set up the signals. 
     self.builder = builder 
     self.ui = builder.get_ui(self) 

     self.test = False 

    def on_btn_cancel_now_clicked(self, widget, data=None): 
     # TODO: Send SIGTERM to the subprocess 
     self.destroy() 

if __name__ == "__main__": 
    dialog = BackupDialog() 
    dialog.show() 
    Gtk.main() 

如果我把這個在finish_initializing功能

backend_process = subprocess.Popen(["python", <path to backend>], stdout=subprocess.PIPE, shell=False) 

然後進程啓動並作爲另一個PID運行,這是我想要的,但現在如何將backend_process.stdout發送到TextView?我可以寫到textview:

BackupDialog.ui.backup_output.get_buffer().insert_at_cursor("TEXT") 

但我只需要知道如何讓這個被稱爲每次有一個新的標準輸出行。

回答

0

但是我只需要知道如何在每次有新的stdout行時調用它。

您可以使用GObject.io_add_watch來監視子進程輸出或創建一個單獨的線程從子進程中讀取。

# read from subprocess 
def read_data(source, condition): 
    line = source.readline() # might block 
    if not line: 
     source.close() 
     return False # stop reading 
    # update text 
    label.set_text('Subprocess output: %r' % (line.strip(),)) 
    return True # continue reading 
io_id = GObject.io_add_watch(proc.stdout, GObject.IO_IN, read_data) 

,或者使用線程:

# read from subprocess in a separate thread 
def reader_thread(proc, update_text): 
    with closing(proc.stdout) as file: 
     for line in iter(file.readline, b''): 
      # execute update_text() in GUI thread 
      GObject.idle_add(update_text, 'Subprocess output: %r' % (
        line.strip(),)) 

t = Thread(target=reader_thread, args=[proc, label.set_text]) 
t.daemon = True # exit with the program 
t.start() 

Complete code examples