嘿,伙计们,我对Kivy大概有10分钟的新鲜感,随意地染上了Python色。你知道吗
我试图创建一个按钮,调用我编写的bash脚本来启动radio
接收器(rtlsdr)。单独调用它会导致GUI冻结,所以我决定使用线程。这工作得很好,但后来我发现我无法停止我的进程(rtl\u fm)-这是我需要做的事情,以便调用另一个频率。你知道吗
我决定使用Kivy中的on_press
和on_release
方法来停止我所有的无线电进程,并尝试启动一个新的频率线程-理论上工作得很好,但是kill进程花费的时间太长,我认为它在有机会启动之前就杀死了我的on_release
进程。我得按两次按钮。(将两个os.system
进程放在一个线程中没有帮助,使用threading
库中的Timer
方法也没有帮助)这就是我设置它的方式-我可能不需要killRadio()
中的线程,但我正在抓住救命稻草(事先很抱歉):
(使用subprocess.call
也不起作用)
主电源.kv
FloatLayout:
size_hint: 1, 1
Label:
markup: True
text: '[size=25]This app is for testing purposes.[/size]'
pos: 0, 0
MDRaisedButton:
text: "106.9"
font_size: 25
on_press: app.killRadio()
on_release: app.tuneRadio("106.9M")
pos: 20, 255
size_hint: .3, .3
MDRaisedButton:
text: "93.3"
font_size: 25
on_press: app.killRadio()
on_release: app.tuneRadio("93.3M")
pos: 305, 255
size_hint: .3, .3
主.py
def killRadio(obj):
de = Thread(target = lambda: os.system("kill -9 $(ps -ef | grep rtl_fm | grep -v grep | awk '{print $2}')"))
try:
de.start()
except:
print ("can't kill")
def tuneRadio(obj, station):
th = Thread(target = lambda: os.system('radio ' + station))
# time.sleep(.3)
th.start()
电台狂欢节
#!/bin/sh
if [ "$1" = "stop" ] #thought this would kill the script - it just frees the cmd line
then
echo "Stopping Radio Playback"
exit 0
fi
if [ "$#" -gt 0 ]
then
echo "playing {$1}"
rtl_fm -f $1 -M wbfm -g 42 -s 200000 -r 192000 - | aplay -D hw:1,0 -c 2 -r 48000 -f S32_LE
else
exit 0
fi
使用Clock.schedule_once
并添加延迟似乎会冻结GUI,因此当按下另一个按钮时,我无法测试它是否工作。对不起,上面的代码是一个绝望的尝试一切-我只是想一个按钮,以杀死收音机,如果它的开启,并呼吁另一个频率。你知道吗
我厌倦了阅读Kivy和Python文档-有人看到遗漏了什么吗?我肯定我做错了什么。。。你知道吗
谢谢
编辑
def control_radio(self, *args):
global radio
radio_lock = threading.Lock() # a mutex for the radio control
if radio_lock.acquire(False): # make sure other threads silently fail
print("aquired")
print(args)
if radio and radio.poll() is None: # kill the radio process if running
print("radio and poll")
radio.kill() # use radio.terminate() for a milder version
if args[0] == "tune": # start the new radio process if requested
print("tuning")
radio = subprocess.Popen(["radio", args[1]])
radio_lock.release() # release the lock
我将@zwer控制函数修改为以下内容,以使它在我的主类中工作。你知道吗
首先,您应该真正使用^{} ,这样您就可以真正控制您的进程,而不必依赖脆弱的外部命令,最基本的方法是:
旁注:我会将整个
.sh
脚本转换为Python,以便更快地执行和更容易地控制,而不会有孤立进程的危险。现在,问题是^{} 和^{} 都是阻塞方法,因此在进程分别启动和终止之前,函数不会返回。你可以使用fire和forget线程,就像你尝试的那样,但是你会在轮到你的时候运行很多线程(加上你必须处理排队),所以你需要决定当用户发出太多命令时应该怎么做-在进程启动/终止之前禁用他们的控件可能是最好的,否则你的应用程序会代表用户进行假设。你知道吗
这完全取决于你如何布置你的控件和应用程序GUI,tho,所以我建议的唯一的其他选择(除了排队命令)就是忽略对底层无线电的调用,不管是调谐还是终止,而它已经开始/正在终止。比如:
我仍然不鼓励这样的使用,因为如果你强行关闭你的应用程序或者你不等待radio kill的执行,它可能会以一个操作过程结束。在退出应用程序时,至少要添加一个阻塞
if radio and radio.poll() is None: radio.terminate()
调用,以确保生成的子进程被终止。你知道吗相关问题 更多 >
编程相关推荐