关闭线程循环

发布于 2024-12-28 13:09:53 字数 1814 浏览 7 评论 0原文

我正在编写的代码需要在 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

凑诗 2025-01-04 13:09:53

对于任何可能找到这篇文章并对我如何让事情按照我想要的方式工作感兴趣的人:

我不想像 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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文