我正在尝试使用PyQt / PySide在Django应用程序中实现屏幕截图渲染器,我将在其中将一串HTML直接提供给QWebPage并渲染mainFrame。我已经测试过并且能够将其作为一个独立的python脚本(下图)。
然而,Django / Apache / mod_wsgi服务器挂起并且在尝试呼叫QApplication([])
时不会响应。 (注意:我已经尝试了PyQt和PySide并且得到了相同的结果)。
我怀疑wsgi无法启动Qt应用程序的问题。
这里或多或少是wsgi设置的范围:
WSGIDaemonProcess site processes=2 threads=4 maximum-requests=10 inactivity-timeout=0.5
WSGIProcessGroup site
WSGIPassAuthorization On
WSGIScriptAlias / /etc/apache2/site.wsgi
这是Django应用程序中的视图文件:
from __future__ import unicode_literals, division
import sys
from PySide import QtWebKit
from PySide.QtNetwork import (
QNetworkRequest, QNetworkAccessManager, QNetworkCookieJar,
QNetworkDiskCache, QNetworkProxy, QNetworkCookie)
from PySide import QtCore
from PySide.QtCore import (
QSize, QByteArray, QUrl, QDateTime, QtCriticalMsg, QtDebugMsg, QtFatalMsg,
QtWarningMsg, qInstallMsgHandler)
from PySide.QtGui import QApplication, QImage, QPainter, QPrinter
from django.views.generic.base import View
from django.core.urlresolvers import resolve
from app.views.common import *
log = logging.getLogger(__name__)
class Renderer(QtWebKit.QWebPage):
def __init__(self, html):
log.debug('getting application')
"""
This is where the application hangs!!!!
"""
self.app = QApplication(sys.argv)
log.debug('app %s', self.app)
super(QtWebKit.QWebPage, self).__init__()
self.url = QUrl(url)
self.mainFrame().setHtml(html)
self.loadFinished.connect(self.render)
self.app.exec_()
def render(self, result):
self.frame = self.mainFrame()
self.app.quit()
class StaticImageView(View):
def get(self, request):
view_func, args, kwargs = resolve(request.GET.get('path'))
html = view_func(self.request, *args, **kwargs)
r = Renderer(html)
size = QSize(1200, 800)
r.setViewportSize(size)
image = QImage(size, QImage.Format_ARGB32_Premultiplied)
painter = QPainter(image)
r.frame.render(painter)
painter.end()
image.save('/tmp/foo.png')
return render(request, 'pages/success.html', {})
以下是直接调用时可以运行的脚本。 https://gist.github.com/paularmstrong/7472484
所以,我的问题是:在Django中通过mod_wsgi在HTTP请求中调用时,为什么QApplication([])
会挂起?
答案 0 :(得分:1)
您可以尝试添加:
WSGIApplicationGroup %{GLOBAL}
但我怀疑问题在于,由于Web应用程序作为特殊的Apache用户运行,而不从您的个人用户环境继承任何内容,因此它对如何与您的UI会话进行交互一无所知。