Форум сайта python.su
скажу сразу код упростил дабы лишнее не мешало разобраться как все должно работать .
вкратце оно выглядит так : 2 класса , в первом чтение из устройств в /dev , во втором гуй . первый должен отправлять данные гую а тот их выводить юзеру , важен тот момент что это именно 2 раздельных класса + гуй не виснет пока происходит чтение и вывод данных при помощи бесконечного цикла (последнее сделано при помощи мультипроцессинга)
короче меньше слов больше кода :
#!/usr/bin/python #-*-coding:utf-8-*- # gui imports import pygtk pygtk.require('2.0') import gtk import os , re import multiprocessing as mult from encodings import hex_codec class evdev(object): def __init__(self, fname=None): self._fd = None self._eventq = list() self._all = list() if fname: self.open(fname) def _fill(self , bufsize): try: raw = os.read(self._fd, bufsize) except EOFError: self.close() else: if raw: for i in range(len(raw)): self._eventq.append(raw[i]) self._all.append(raw[i]) def open(self, filename): self._fd = os.open(filename, os.O_RDWR) def close(self): if self._fd is not None: os.close(self._fd) self._fd = None def read(self , bufsize = 1): if not self._eventq: self._fill(bufsize) try: return self._eventq.pop() except: pass def get_all(self , as_list = False): if as_list: return self._all else: try: return ''.join(self._all) except: pass @staticmethod def test_dev(*args): print args tmp = evdev(args[0]) while True: tmp.read(args[1]) ret = tmp.get_all() codr = hex_codec.Codec() args[2]( str(codr.encode(ret)[0][-8:-1])) # вызов метода show_output из класса gui tmp.close() return ret class gui: def __init__(self): wnd = gtk.Window() wnd.set_size_request(500 , 500) wnd.show() wnd.connect('delete_event' , gtk.main_quit) lay = gtk.Layout() lay.set_size_request(500 , 500) lay.show() wnd.add(lay) # код с выбором устройства из /dev/input опускаю он работает исправно # в рабочем варианте юзер должен увидеть выхлоп из устройства startb = gtk.Button('start') stopb = gtk.Button('stop') for x in [startb , stopb] : x.set_size_request(100 , 25) x.show() lay.put(startb , 5 , 10) lay.put(stopb , 110 , 10) startb.connect('clicked' , self.start) stopb.connect('clicked' , self.stop) self.vihlop = gtk.Entry() self.vihlop.set_size_request(400 , 25) self.vihlop.show() lay.put(self.vihlop , 5 , 50) def show_output(self , vih): """функция передаеться в качестве параметра статическому методу класса evdev дабы тот записал данные в self.vihlop""" self.vihlop.set_text(vih) # пытаемся писать но безуспешно print vih # в консоли будет видно что функция исправно вызываеться и выхлоп есть def start(self , w): """метод запускает в отдельном процессе чтение из устройства /dev/input/mouse0 (в оригинальном коде юзер выбирает устройство , здесь для упрощения я убрал выбор) во время чтения статический метод evdev.test_dev вызывает метод self.show_output передавая ей в качестве параметра то что нужно вывести юзеру в self.vihlop реализация в отдельном процессе с той целью что-бы во время чтения/записи данных не вис основной процесс в котором гуй """ self.test = mult.Process(target = evdev.test_dev , args = ( '/dev/input/mouse0' , 10 , self.show_output )) self.test.start() def stop(self , w): """метод останавливает процесс запущенный в методе self.start""" self.test.terminate() lol = gui() gtk.main()
Отредактировано @cckyi_boxxx (Янв. 25, 2013 19:56:12)
Офлайн
часть вопроса решил , удалось прикрутить треды вместо мультипроцессинга таким-вот способом
gtk.gdk.threads_init() gtk.gdk.threads_enter() # здесь код запуска треда gtk.gdk.threads_leave()
Офлайн
вопрос снят , решение оказалось простым , создал а главном потоке очередь и передал ее в требуемый поток , затем торможу бесконечный цикл как только что-то попадает в очередь ( Queue.empty() == False )
Офлайн