Закрытие резьбовой петли - PullRequest
1 голос
/ 23 января 2012

Код, над которым я работаю, должен использовать событие последовательного порта (подключение контактов 5 и 8 с помощью контактного переключателя) для запуска функции (воспроизведения музыки) в приложении с графическим интерфейсом. Я создал цикл для отслеживания последовательного порта, и он работает в отдельном потоке от графического интерфейса pygtk.

Я тестирую это из командной строки. Когда графический интерфейс пользователя закрыт, поток мониторинга не сразу закрывается. Он остается открытым до тех пор, пока событие снова не сработает (нажат контактный выключатель), а затем закроется.

Я не хочу, чтобы пользователи нажимали переключатель, чтобы правильно закрыть программу!

Упрощенная версия кода:

#!/usr/bin/python2

import sys
import subprocess
import pygtk
pygtk.require('2.0')
import gtk
import threading
import gobject
from serial import Serial
from fcntl import  ioctl
from termios import (
    TIOCMIWAIT,
    TIOCM_RNG,
    TIOCM_DSR,
    TIOCM_CD,
    TIOCM_CTS
)

ser = Serial('/dev/ttyS0')
wait_signals = (TIOCM_RNG |
                TIOCM_DSR |
                TIOCM_CD  |
                TIOCM_CTS)

def startplaying():
    #for testing
    print('Start playing the track!')

gobject.threads_init()

class SerialWatch(threading.Thread):

    def __init__(self):
        super(SerialWatch, self).__init__()
        self._stop = threading.Event()

    def run(self):
        if __name__ == '__main__':
            while not self._stop.isSet():
                ioctl(ser.fd, TIOCMIWAIT, wait_signals)
                startplaying()

    def stop(self):
        self._stop.set()

    def stopped(self):
        return self._stop.isSet()

class MusicManager():

    def delete_event(self, widget, event, data=None):
        return False

    def destroy(self, widget, data=None):
        gtk.main_quit()

    def __init__(self):
        self.window = gtk.Window(gtk.WINDOW_TOPLEVEL)
        self.window.connect("delete_event", self.delete_event)
        self.window.connect("destroy", self.destroy)
        self.window.show_all()    

    def main(self):
        gtk.main()

sw = SerialWatch()
sw.start()

print __name__
if __name__ == "__main__":
    music_manager =  MusicManager()
    music_manager.main()

sw.stop()

Я не опытный программист и буду признателен за любую помощь в этом.

1 Ответ

1 голос
/ 28 сентября 2012

Для тех, кто может найти этот пост и интересуется, как я заставил вещи работать так, как я хотел:

Я не хотел использовать опрос, как предложил smichak.Однако мои попытки использовать потоки для запуска цикла TIOCMIWAIT не увенчались успехом, поскольку они мешали циклу GUI.

Я написал отдельный скрипт на python для наблюдения за последовательным портом с помощью цикла TIOCMIWAIT и запуска этогоскрипт как подпроцесс из основной программы с графическим интерфейсом.Таким образом, скрипт запускается при открытии графического интерфейса и уничтожается при закрытии графического интерфейса.Когда устанавливается соединение через последовательный порт, сценарий использует dbus для связи с GUI и запускает требуемую функцию.

...