当我的 PySide 应用程序通过在~/.config/autostart
.
通过以下实验,我得出的结论是 PySide/Qt 存在问题。
首先,我创建了一个简单的 Python 脚本,它捕获 TERM 信号并打印确认然后退出。这是代码。
import signal
import sys
import time
def on_quit(*args):
print 'here', args
sys.exit(0)
for i in [x for x in dir(signal) if x.startswith('SIG')]:
try:
signum = getattr(signal, i)
if i == 'SIGCHILD' or i == 'SIGCHLD':
continue
signal.signal(signum, on_quit)
except Exception, m:
print 'Skipping %s' % i
time.sleep(1000000)
for 循环只是在所有可能的信号上注册 on_quit 方法。
在终端中调用它并通过杀死它来发送 TERM 信号,我可以确认它正在被脚本捕获和处理。
然后,我尝试通过在~/.config/autostart
. 该条目类似于以下内容:
[Desktop Entry]
Version=1.0
Type=Application
Name=Test
GenericName=Test
Comment=Test
Exec=strace -T -f -tt -o run_test.strace run_test
Terminal=false
StartupNotify=false
我使用 strace 跟踪脚本的系统调用,以另一种方式确认它正在捕获 TERM 信号。strace 的选项告诉它包括花费在系统调用上的时间,跟随分叉,以微秒打印一天中的时间,并按run_test.strace
该顺序将输出发送到。
run_test
只是一个调用 Python 脚本的 bash 脚本;之所以包含它,是因为这就是我最初的 PySide 应用程序的调用方式。它的代码是:
#!/bin/bash
python test.py &>out.test
我通过将桌面条目添加到~/.config/autostart
,重新启动计算机,然后将其关闭来继续对其进行测试。run_test.strace
包含行“--- SIGTERM (Terminated) @ 0 (0) ---”,它确认 SIGTERM 已发送并被捕获。out.test
还包含进一步证实它的预期输出。
然后我尝试用信号处理测试一个简单的 PySide 应用程序。代码如下。
import signal
import sys
import time
from PySide.QtGui import QApplication
from PySide.QtCore import QTimer
app = QApplication([])
timer = QTimer()
timer.start(500)
timer.timeout.connect(lambda: None)
def on_quit(*args):
print 'here', args
sys.exit(0)
for i in [x for x in dir(signal) if x.startswith('SIG')]:
try:
signum = getattr(signal, i)
if i == 'SIGCHILD' or i == 'SIGCHLD':
continue
signal.signal(signum, on_quit)
except Exception, m:
print 'Skipping %s' % i
app.exec_()
QTimer 对于允许信号处理程序执行是必不可少的。
在终端中运行上述脚本并向其发送 TERM 信号,输出仍然确认 TERM 信号正在被捕获和处理。通过 strace 运行它还会显示“--- SIGTERM (Terminated) @ 0 (0) ---”行。
但是,在启动期间运行它时,输出显示未调用 on_quit 方法,在 strace 输出中也没有指示它已发送 TERM 信号。
有人可以帮忙吗?如果需要,我可以提供 strace 输出。系统是 Ubuntu 12.04 32 位。
编辑:进一步的实验表明它发生在 QApplication 而不是 QCoreApplication。那可能与GUI相关?