4

我在 amazon ec2 ubuntu 12.04 的 xvfb 服务器上运行以下 pyqt 应用程序,我从 qt 应用程序得到正确的输出,但是当应用程序完成时我总是得到上述错误。为什么我会收到此错误?我认为这可能是因为 xvfb 服务器没有正确终止,但我不确定。

import sys
from PyQt4.QtGui import *
from PyQt4.QtCore import *
from PyQt4.QtWebKit import *
from xvfbwrapper import Xvfb


args = {"nolisten":"tcp"}
vdisplay = Xvfb(**args)
vdisplay.start()
app = QApplication(sys.argv)
def update():
    print "upd"
t = QTimer()
t.start(500)
t.timeout.connect(update)
stopTimer = QTimer(timeout=app.quit,singleShot=True)
stopTimer.start(4000)
app.exec_()
print "done with app"
vdisplay.stop()
4

3 回答 3

3

对我来说@urim 的解决方案不起作用,因为如果你不使用,脚本退出时vdisplay.stop()Xvfb 进程不会被杀死,这是一个问题。我的解决方案是在一段时间后通过后台调用显式终止该进程:

# Workaround for a problem preventing vdisplay.stop() to work
# normally, because apparently Qt is still keeping its handle on X
# at this point.
import os
os.system('(sleep 5 && kill -9 %d) &' % vdisplay.proc.pid)
于 2015-12-29T15:20:13.470 回答
1

只要QApplication实例处于活动状态,您就会收到错误消息。一种解决方案是将Xvfb.stop()调用推到离程序出口更近的地方,例如使用atexit模块:

import atexit

# ...

def main():
    vdisplay = Xvfb()
    vdisplay.start()
    atexit.register(vdisplay.stop)

    # ...
于 2018-04-27T15:05:33.543 回答
1

解决此问题的另一种丑陋方法是将所有内容包装在另一个子进程中:

import xvfbwrapper
import sys
import subprocess as sub

with xvfbwrapper.Xvfb():
    p = sub.Popen(
        ["python", "yourscript.py"] + sys.argv[1:],
        stdout=sub.PIPE, stderr=sub.PIPE
    )
    stdout, stderr = p.communicate()
    print stdout
    print >> sys.stderr, stderr
    sys.exit(p.returncode)
于 2016-08-23T18:04:21.123 回答