1

これを行う方法を探すのに何年も費やしましたが、これまでのところ何も思いつきませんでした。:(

私が作成した小さな CLI プログラムの GUI を作成しようとしているので、Ubuntu の「Quickly」を使用するのが最も簡単な方法だと思いました。GUIの作成には基本的にGladeを使用しているようです。CLI バックエンドをサブプロセスで実行し、stdout と stderr をテキストビューに送信する必要があることはわかっています。しかし、これを行う方法がわかりません。

これは、出力を表示するダイアログ ボックス用に Glade/Quickly が作成したコードです。

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 に送信するにはどうすればよいですか? 次の方法でテキストビューに書き込むことができます。

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

しかし、標準出力の新しい行があるたびにこれを呼び出す方法を知る必要があります。

4

1 に答える 1

0

しかし、標準出力の新しい行があるたびにこれを呼び出す方法を知る必要があります。

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()

完全なコード例

于 2013-03-13T03:05:00.060 に答える