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()
我不是一個有經驗的程序員,並希望任何幫助。
我之前在這裏發佈的答案是錯誤的。問題是你的線程在等待串行線路狀態變化的ioctl上阻塞。您可以使用TIOCMGET簡單地讀取串口狀態位,並立即從ioctl返回,睡眠100ms,然後再次檢查。這樣,你將能夠阻止你的線程,因爲它永遠不會無限期地阻塞。 – smichak
好的謝謝你花時間看這個。我會嘗試你的建議,看看它是如何發展的。 – corky