2012-01-23 159 views
1

我正在使用的代碼需要在GUI應用程序中使用串行端口事件(連接引腳5和8與觸點開關)以觸發函數(播放音樂)。我創建了一個循環來監視串行端口,並在pygtk GUI的一個單獨線程中運行。關閉線程循環

我從命令行測試了這個。當GUI關閉時,監視線程不會立即關閉。它一直保持打開狀態,直到事件被觸發(接觸開關按下)再次關閉。

我不希望用戶需要按開關來正確關閉程序!

代碼的簡化版本是:

#!/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() 

我不是一個有經驗的程序員,並希望任何幫助。

+0

我之前在這裏發佈的答案是錯誤的。問題是你的線程在等待串行線路狀態變化的ioctl上阻塞。您可以使用TIOCMGET簡單地讀取串口狀態位,並立即從ioctl返回,睡眠100ms,然後再次檢查。這樣,你將能夠阻止你的線程,因爲它永遠不會無限期地阻塞。 – smichak

+0

好的謝謝你花時間看這個。我會嘗試你的建議,看看它是如何發展的。 – corky

回答

1

對於任何人誰可能會發現這篇文章,有興趣我是如何得到的東西的工作我想要的方式:

我不想使用輪詢作爲smichak建議。但是我嘗試使用線程來運行TIOCMIWAIT循環失敗,因爲它干擾了GUI循環。

我所做的是編寫一個單獨的python腳本來觀察具有TIOCMIWAIT循環的串口,並將該腳本作爲主GUI程序的子流程來運行。這樣,腳本在GUI打開時啓動,並在GUI關閉時被終止。當在串口上建立連接時,腳本使用dbus與GUI進行通信並運行所需的功能。