0

我正在尝试使用 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

所以,我的问题是:为什么QApplication([])在通过 Django 中的 mod_wsgi 进行 HTTP 请求期间调用时会挂起?

4

1 回答 1

1

您可以尝试添加:

WSGIApplicationGroup %{GLOBAL}

但我怀疑问题在于,由于 Web 应用程序作为特殊的 Apache 用户运行,没有从您的个人用户环境中继承任何东西,它对如何与您的 UI 会话进行交互一无所知。

于 2013-11-14T21:43:38.787 回答