QtWebkit 和 hasPendingEvents() 始终为真
我在Linux上使用一个叫做webkit2png的项目(稍微做了一些修改)来截屏。这个项目在运行最新版本的QtWebkit和Python 2.6的服务器上。
在某些网站上(比如118114.cn),程序会一直卡住,无法继续。调试时发现问题出在这段代码上:
while self.__loading:
if timeout > 0 and time.time() >= cancelAt:
raise RuntimeError("请求在 %s 超时" % url)
while QApplication.hasPendingEvents():
QCoreApplication.processEvents()
完整的源代码可以在 这里 找到(第270-275行)
不知怎么的,加载事件卡住了,hasPendingEvents一直为真。
大部分截图都能正常生成,但有时由于某些网址的问题,我的应用程序会崩溃 :(
有没有人知道怎么解决这个问题,以及为什么事件会卡住呢?
3 个回答
可能有一个重复的定时器?比如说,页面上闪烁的光标会让一些事件(像定时器启动、视图失效、绘制等等)不断发生。
你可能需要加一个超时的逻辑,这样如果循环运行时间太长,就能让它退出。
我升级了libqtcore4,但这并没有解决我的问题。我不得不按照Jeremy的建议对webkit2png.py进行一些修改。
# aptitude show libqtcore4
Package: libqtcore4
State: installed
Automatically installed: no
Version: 4:4.7.2-0ubuntu6.1
在大约第230行,有两个地方调用了hasPendingEvents()。
229 while time.time() < waitToTime:
230 #while QApplication.hasPendingEvents():
231 QApplication.processEvents()
232
233 # Paint this frame into an image
234 #self._window.repaint()
235 #while QApplication.hasPendingEvents():
236 QApplication.processEvents()
processEvents()会处理所有待处理的事件,最多持续3秒。目前对我来说一切正常。之前无法显示的网站现在都能正常出现了。如果你需要超过3秒的时间(可能是服务器忙?),那么第235行的while循环需要设置一个超时时间。
我也在使用 webkit2png 和 Linux,遇到了你描述的问题,当我在我的 MacBook Pro 上进行本地测试时,问题出现了。看起来是 QApplication.hasPendingEvents() 错误地返回了 True,导致 while 循环卡住了。我通过去掉这个 while 循环来解决了这个问题:
while self.__loading:
if timeout > 0 and time.time() >= cancelAt:
raise RuntimeError("Request timed out on %s" % url)
QCoreApplication.processEvents()
注意,你还需要在 __WebkitRendererHelper.render 的几个地方做这个修改。做完这些改动后,一切都正常了,祝你好运。
补充:我最开始在 Linux 上解决这个问题是通过升级底层的 QT 库。Ubuntu 10.04 LTS 默认的版本(4.6.2)有一个 bug,而在后来的版本中这个问题被修复了。以下是我的安装信息:
Package: libqtcore4
State: installed
Automatically installed: yes
Version: 4:4.7.0-0ubuntu2~lucid1~ppa1
Priority: optional
Section: libs
Maintainer: Kubuntu Developers <kubuntu-devel@lists.ubuntu.com>
Uncompressed Size: 7,471k
Depends: libc6 (>= 2.9), libgcc1 (>= 1:4.1.1), libglib2.0-0 (>= 2.12.0), libstdc++6 (>= 4.1.1), zlib1g (>= 1:1.1.4)
Breaks: libqt4-core (< 4.4.0~beta1-1), libqt4-gui (< 4.4.0~beta1-1)
Replaces: libqt4-core (< 4.4.0~beta1-1), libqt4-gui (< 4.4.0~beta1-1)
Description: Qt 4 core module
Qt is a cross-platform C++ application framework. Qt's primary feature is its rich set of widgets that provide standard GUI
functionality.
The QtCore module contains core non-GUI functionality.