2012-01-23 297 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进行通信并运行所需的功能。