Уведомления

Группа в Telegram: @pythonsu

#1 Авг. 16, 2012 16:30:21

ASTAPP
Зарегистрирован: 2012-08-16
Сообщения: 5
Репутация: +  0  -
Профиль   Отправить e-mail  

Перенапрвление вывода из Popen

Есть приложение по типу yes, постоянно выводящее текст в командную строку.
Требуется создать GUI, которое в реальном времени будет выводить результат этой программы в TextCtrl

Т.е. возникает 2 вопроса:
1) Как получить вывод программы до ее завершения
2) Как обеспечить постоянное обновление TextCtrl

Офлайн

#2 Авг. 16, 2012 16:42:01

odnochlen
Зарегистрирован: 2012-06-28
Сообщения: 794
Репутация: +  14  -
Профиль   Отправить e-mail  

Перенапрвление вывода из Popen

В цикле читаем stdout программы и выводим.

Офлайн

#3 Авг. 16, 2012 16:52:06

ASTAPP
Зарегистрирован: 2012-08-16
Сообщения: 5
Репутация: +  0  -
Профиль   Отправить e-mail  

Перенапрвление вывода из Popen

odnochlen
В цикле читаем stdout программы и выводим.

Только программа должна еще кучу всего делать, поэтому циклом не получится. Надо как-то наверное с потоками, прошу подсказать.

Офлайн

#4 Авг. 16, 2012 22:13:55

odnochlen
Зарегистрирован: 2012-06-28
Сообщения: 794
Репутация: +  14  -
Профиль   Отправить e-mail  

Перенапрвление вывода из Popen

Создаешь отдельный поток, читаешь им stdout и выводишь прочитанное. Писать в stdin не надо?

Офлайн

#5 Авг. 22, 2012 14:35:30

ASTAPP
Зарегистрирован: 2012-08-16
Сообщения: 5
Репутация: +  0  -
Профиль   Отправить e-mail  

Перенапрвление вывода из Popen

odnochlen
Создаешь отдельный поток, читаешь им stdout и выводишь прочитанное. Писать в stdin не надо?

Из второго потока не получается писать в textctrl, созданным основным потоком. Что делать?

import re
import os
import subprocess
import wx
import string
import threading
from itertools import count
class MyThread(threading.Thread):
    textArea = 0
    pp = 0
    
    def __init__(self, pp, textArea):
        self.pp = pp
        self.textArea = textArea
        threading.Thread.__init__(self)
    
    def run(self):
        for i in count(1):                
            oo = self.pp.stdout.readline()
            
            self.textArea.AppendText("oo") ##От этого умирает
class LaucherFrame(wx.Frame):
    def __init__(self):
    
        wx.Frame.__init__(self, id=-1, parent=None,
            pos=wx.Point(400, 200), size=wx.Size(830, 640), title='Система запуска ИРК')
        self.panel = wx.Panel(self)
        
        self.imitator = wx.TextCtrl(self, pos=(10,20), size=(400,300), style = wx.TE_MULTILINE)
        
        pp = subprocess.Popen(
            ["yes"]
            ,shell = True, stdout=subprocess.PIPE
            )
        MyThread(pp, self.imitator).start()
        
            
            
class HelloApp(wx.App):
    def OnInit(self):
        frame = LaucherFrame()
        frame.Show(True)
        return True
if __name__ == '__main__':
    app = HelloApp()
    app.MainLoop()


Вывод ошибки:
(python:2108): Gtk-WARNING **: Invalid text buffer iterator: either the iterator is uninitialized, or the characters/pixbufs/widgets in the buffer have been modified since the iterator was created.
You must use marks, character numbers, or line numbers to preserve a position across buffer modifications.
You can apply tags and insert marks without invalidating your iterators,
but any mutation that affects 'indexable' buffer contents (contents that can be referred to by character offset)
will invalidate all outstanding iterators
(python:2108): Gtk-CRITICAL **: IA__gtk_text_layout_wrap_loop_start: assertion `layout->one_style_cache == NULL' failed
(python:2108): Gtk-CRITICAL **: IA__gtk_text_layout_wrap_loop_end: assertion `layout->wrap_loop_count > 0' failed
(python:2108): Gtk-WARNING **: Invalid text buffer iterator: either the iterator is uninitialized, or the characters/pixbufs/widgets in the buffer have been modified since the iterator was created.
You must use marks, character numbers, or line numbers to preserve a position across buffer modifications.
You can apply tags and insert marks without invalidating your iterators,
but any mutation that affects 'indexable' buffer contents (contents that can be referred to by character offset)
will invalidate all outstanding iterators
(python:2108): Gtk-CRITICAL **: gtk_text_layout_real_invalidate: assertion `layout->wrap_loop_count == 0' failed
(python:2108): Gtk-CRITICAL **: gtk_text_layout_real_invalidate: assertion `layout->wrap_loop_count == 0' failed
(python:2108): Gtk-WARNING **: Invalid text buffer iterator: either the iterator is uninitialized, or the characters/pixbufs/widgets in the buffer have been modified since the iterator was created.
You must use marks, character numbers, or line numbers to preserve a position across buffer modifications.
You can apply tags and insert marks without invalidating your iterators,
but any mutation that affects 'indexable' buffer contents (contents that can be referred to by character offset)
will invalidate all outstanding iterators
(python:2108): Pango-CRITICAL **: pango_layout_get_iter: assertion `PANGO_IS_LAYOUT (layout)' failed
Ошибка сегментирования
adeykin@adeykin-System-Product-Name:~/Документы/test$ yes: стандартный вывод: Обрыв канала
yes: ошибка записи

Отредактировано ASTAPP (Авг. 22, 2012 14:39:46)

Офлайн

#6 Авг. 22, 2012 15:12:46

ASTAPP
Зарегистрирован: 2012-08-16
Сообщения: 5
Репутация: +  0  -
Профиль   Отправить e-mail  

Перенапрвление вывода из Popen

Нашел решение (\^_^/)

Нужно в главном потоке создавать таймеры, по срабатыванию которых проверять состояние дочерних потоков и выводить их в textctrl

import re
import os
import subprocess
import wx
import string
import threading
from itertools import count
class MyThread(threading.Thread):
    textArea = 0
    pp = 0
    result = "bbb"
    
    def __init__(self, pp, textArea):
        self.pp = pp
        self.textArea = textArea
        threading.Thread.__init__(self)
    
    def run(self):
        for i in count(1):                
            oo = self.pp.stdout.readline()
            
            #self.textArea.AppendText("oo")
            self.result = "ccc"
class LaucherFrame(wx.Frame):
    p = 0
    def __init__(self):
    
        wx.Frame.__init__(self, id=-1, parent=None,
            pos=wx.Point(400, 200), size=wx.Size(830, 640), title='Система запуска ИРК')
        self.panel = wx.Panel(self)
        
        self.imitator = wx.TextCtrl(self, pos=(10,20), size=(400,300), style = wx.TE_MULTILINE)
        
        self.timer = wx.Timer(self)        
        self.Bind(wx.EVT_TIMER, self.update, self.timer)
        
        pp = subprocess.Popen(
            ["yes"]
            ,shell = True, stdout=subprocess.PIPE
            )
        self.p = MyThread(pp, self.imitator)
        self.p.start()
        
        self.timer.Start(100)            
        
        
            
    def update(self, event):
        self.imitator.AppendText( self.p.result )
        self.timer.Start(100)
        
            
            
class HelloApp(wx.App):
    def OnInit(self):
        frame = LaucherFrame()
        frame.Show(True)
        return True
if __name__ == '__main__':
    app = HelloApp()
    app.MainLoop()

Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version