关闭线程循环
我正在编写的代码需要在 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()
我不是一个经验丰富的程序员,希望得到任何帮助。
The code I am working on needs to use a serial port event (connecting pins 5 and 8 with a contact switch) to trigger a function (playing music), within a GUI application. I have created a loop to monitor the serial port and have this running within a separate thread from the pygtk GUI.
I an testing this from the command line. When the GUI is closed, the monitoring thread does not immediately close. It stays open until the event is triggered (the contact switch pressed) again then it will close.
I do not want users to need to press a switch to properly close a program!
A simplified version of the code is:
#!/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()
I am not an experienced programmer and would appreciate any help with this.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
对于任何可能找到这篇文章并对我如何让事情按照我想要的方式工作感兴趣的人:
我不想像 smichak 建议的那样使用轮询。然而,我尝试使用线程运行 TIOCMIWAIT 循环失败了,因为它干扰了 GUI 循环。
我所做的是编写一个单独的 python 脚本来使用 TIOCMIWAIT 循环监视串行端口,并将该脚本作为主 GUI 程序的子进程运行。这样,脚本会在 GUI 打开时启动,并在 GUI 关闭时终止。当在串行端口上建立连接时,脚本使用 dbus 与 GUI 通信并运行所需的功能。
For anybody who might find this post and is interested in how I got things to work the way I wanted:
I did not want to use polling as smichak suggested. However my attempts to use threads to run the TIOCMIWAIT loop failed as it interfered with the GUI loop.
What I have done is to write a separate python script to watch the serial port with the TIOCMIWAIT loop and to run this script as a subprocess from the main GUI program. This way the script is launched when the GUI is opened and it is killed when the GUI is closed. When a connection is made on the serial port, the script uses dbus to communicate to the GUI and run the required function.