PyQt4 & flask:无法为不同线程中的父级创建子级

Posted

技术标签:

【中文标题】PyQt4 & flask:无法为不同线程中的父级创建子级【英文标题】:PyQt4 & flask : Cannot create children for a parent that is in a different thread 【发布时间】:2013-11-07 08:09:15 【问题描述】:

我正在尝试将 http 请求上的页面图像保存到烧瓶服务器。

这是我在运行这个东西时得到的信息 QObject:无法为不同线程中的父级创建子级。

这是我的代码

import sys
import time
from PyQt4.QtCore import *
from PyQt4.QtGui import *
from PyQt4.QtWebKit import *
import Image
from flask import Flask, Response, jsonify,request
app=Flask(__name__)


class Screenshot(QWebView):
    def __init__(self):
        self.app = QApplication(sys.argv)
        QWebView.__init__(self)
        self._loaded = False
        self.loadFinished.connect(self._loadFinished)

    def capture(self,url,width,output_file):
        self.resize(width,300)
        self.load(QUrl(url))
        self.wait_load()
        # set to webpage size
        frame = self.page().mainFrame()
        self.page().setViewportSize(frame.contentsSize())
        # render image
        image = QImage(self.page().viewportSize(), QImage.Format_ARGB32)
        painter = QPainter(image)
        frame.render(painter)
        painter.end()
        print 'saving', output_file
        image.save(output_file)

    def wait_load(self, delay=0):
        # process app events until page loaded
        while not self._loaded:
            self.app.processEvents()
            time.sleep(delay)
        self._loaded = False

    def _loadFinished(self, result):
        self._loaded = True





if __name__=='__main__':
    s = Screenshot()

    @app.route('/image', methods=['GET','POST'])
    def getPicture():

        #reading args
        url=request.args.get('url')
        screenWidth=int(request.args.get('sw'))
        top=int(request.args.get('top'))
        left=int(request.args.get('left'))
        width=int(request.args.get('width'))
        height=int(request.args.get('height'))

        #cropping image
        s.capture(url,screenWidth,"temp.png")
        img=Image.open("temp.png")
        box=(left, top, left+width, top+height)
        area=img.crop(box)
        area.save("output","png")
        return "output.png"

        @app.route('/')
        def api_root():
            return 'Welcome'

    app.run(host='0.0.0.0',port=3000,debug=True)

每当我使用

curl http://0.0.0.0:3000/image?url=googlecom&sw=1920&top=100&left=100&width=200&height=200

我收到以下错误消息,

QObject: Cannot create children for a parent that is in a different thread.
(Parent is Screenshot(0x7f9dbf121b90), parent's thread is QThread(0x7f9dbdb92240), current thread is QThread(0x7f9dbf11ed50)
QPixmap: It is not safe to use pixmaps outside the GUI thread
QPixmap: It is not safe to use pixmaps outside the GUI thread

【问题讨论】:

【参考方案1】:

我不确定是不是这个原因,但我在Screenshot.__init__() 中没有看到self.app.exec_() 呼叫。没有它,QApplication 实例永远不会进入主循环。顺便说一句,我会在 Screenshot 之外实例化 QApplication ,但在你的“主要”部分的某个地方。不确定在这种特殊情况下是否重要,但可能。

【讨论】:

以上是关于PyQt4 & flask:无法为不同线程中的父级创建子级的主要内容,如果未能解决你的问题,请参考以下文章

PyQt4 QProcess 状态始终为 0,各种插槽也无法正常工作

PyQt4中QWebView的多线程

在 PyQt4 中使用 QThread 运行线程时更新变量值

python3 & pyqt4 & cx_freeze:没有名为“sip”的模块

PyQt4:如何获取 QlistWidget 的可见项目列表?

flask 上下文管理 &源码剖析