如何在非 GUI 应用程序中使用 QWebPage
Posted
技术标签:
【中文标题】如何在非 GUI 应用程序中使用 QWebPage【英文标题】:how to use QWebPage in a non-GUI application 【发布时间】:2012-02-09 15:00:35 【问题描述】:我想在非 GUI Qt 应用程序中使用QWebPage
。我的意思是我根本不想与窗口服务器通信。不过,使用 QtGui 不是问题。
QWebPage
在内部创建一些 QWidget
实例。因此,无法使用QCoreApplication
。
虽然在创建 QApplication
实例时,我已经立即获得了 MacOSX 停靠图标。我不希望那样。这也意味着它以某种方式在 Cocoa 中将自己注册为 GUI 应用程序。
我的问题不仅限于 Mac。我想知道 Qt 是否有“官方”的方式来做到这一点。只有在没有的情况下,我才想知道执行此操作的具体方法,例如现在在 Mac 上。
关于 Mac 的更具体一点:
还有LSBackgroundOnly 属性,可以为应用程序包设置,并朝着我想要的方向发展(因此我仍然不确定它是否真的是真正的控制台专用,例如也可以工作没有石英等)。但是,我根本没有 App 包。它只是一个简单的二进制文件(用作 shell 中的命令行工具)。
目前,我有一个小解决方法来隐藏停靠图标,但这非常难看,因为它首先弹出然后消失:(Python 代码,但这并不重要......)
def hideMacDockIcon():
# http://***.com/a/9220857/133374
import AppKit
# https://developer.apple.com/library/mac/#documentation/AppKit/Reference/NSRunningApplication_Class/Reference/Reference.html
NSApplicationActivationPolicyRegular = 0
NSApplicationActivationPolicyAccessory = 1
NSApplicationActivationPolicyProhibited = 2
AppKit.NSApp.setActivationPolicy_(NSApplicationActivationPolicyProhibited)
app = QApplication(sys.argv)
if sys.platform == "darwin":
hideMacDockIcon()
另外,我不确定它是否也适用于其他环境,可能作为系统守护程序等。
【问题讨论】:
【参考方案1】:您可以使用 QPA 做到这一点。这恰好是 PhantomJS 实现无头的方式。修改了 QT 预配置文件以指定 QPA:
QT_CFG +=' -qpa' # X11-less with QPA (aka Lighthouse)
还有一些关于 QMinimalWindowSurface 的内容。
https://github.com/ariya/phantomjs/commit/6c8a1c2dc1 https://github.com/ariya/phantomjs/commit/c78ae190a9
【讨论】:
我很难找到有关此的更多信息。 Here 是 Lighthouse 的初始公告。它似乎从 Qt 4.8 开始包含在内。但是(为什么)你需要编译器配置选项?那不是(Qt Platform Abstraction)总是存在的东西,因为它是一种抽象吗?另外,一路上,我还发现了node-chimera。 @kanzure 您能否提供有关 phantomjs 如何使用 qpa 实现此功能的更多详细信息。关于它的文档并不多。 对不起,我真的不太了解这个。我记得在 PhantomJS 邮件列表的某处发现有人谈论启用或禁用 QPA/Lighthouse。那里可能有更多细节?【参考方案2】:QApplication 初始化 QWidgets 使用的静态变量。因此,在创建 QApplication 实例之前,您将无法创建任何小部件。
如果您需要浏览器,请尝试使用Webkit、Chromium、Berkelium、Awesomium(商业)或chromiumoffscreenrenderer(LGPL fork)
【讨论】:
嗯,是的,这就是我想要的,但这里是题外话,因为我专门询问QWebPage
。另外,我不介意我使用QApplication
还是QCoreApplication
。我只是不想进行任何 GUI 交互。但我目前有,如果我使用QApplication
,它会创建一个 MacOSX 停靠图标,而我不希望那样。
@Albert,你应该问另一个问题:How to not spawn app icon on Mac in my Qt GUI application.
我不确定这是否真的是唯一的事情。这是迄今为止可见的东西。可能还有其他东西,例如该应用程序可以获得焦点等。我想确保我也可以在任何环境中运行它,例如当 Quartz 未运行时。【参考方案3】:
您是否尝试过将“no gui”标志传递给 QApplication?
QApplication ( int & argc, char ** argv, bool GUIenabled )
【讨论】:
是的,不起作用。我还在某处读过(也许是文档,也许是 Qt 源代码,不记得了)在很多情况下都没有效果,尤其是。在 MacOSX 上。【参考方案4】:恐怕没有不使用QtGui的简单方法。如果您查看source code of QWebPage,您会看到使用了 QPainter,作为从 QtGui 导出的一些方法\对象。这是意料之中的,因为您在 API 中有 QWidget* QWebPage::view() const
之类的函数。
您可以考虑破解源代码,但您的 Qt 库是独一无二的且不兼容的。这是一种负担。
【讨论】:
嗯,使用QtGui真的不是问题。我只是不想创建任何窗口或其他任何东西,根本不想与窗口服务器通信。 在不显示窗口之前,您不会与窗口服务器通信。 @KamilKlimek:确实如此。它会在QApplication
实例化后立即创建一个 MacOSX 停靠图标。
然后你应该将 Info.plist 文件嵌入到你的可执行文件中。在 Info.plist 文件中,您可以设置该应用程序没有停靠图标。在您的链接器标志中,您应该添加 -sectcreate __TEXT __info_plist PATH/TO/Info.plist【参考方案5】:
你想用 QWebPage 做什么? 也许有一个更适合您需求的课程? 如果没有:从 QWebPage 的源代码复制和粘贴是一个选项。
更新: 你想创建类似命令行浏览器的东西吗?或者只是看起来像 Web 服务器的浏览器? 在这些情况下,您可能只是隐藏 QWidget,因此停靠栏中不会出现任何内容(不确定这是否是它在 OS X 上的工作方式;在 Windows 上,可能有没有任务栏条目的窗口,我认为)。
【讨论】:
我需要一些对象,它可以加载一些网页,也许可以渲染它,具有所有常见的浏览器功能,如历史记录、cookie 等。 我看不出复制 QWebPage 源代码有什么帮助。似乎 WebCore 本身正在创建小部件。也许 WebKit 只需要小部件。但接下来的问题是:如何在非 GUI 应用程序中做到这一点?还是有一些虚拟的 GUI? 我不明白您将如何在非 GUI 应用程序中呈现网页......您是否希望您的应用程序生成已呈现网页的图像或类似的东西?跨度> 没关系。现在,我根本不需要渲染。如果我以后需要它,我只需要它在内存中。 隐藏是什么意思?无论如何,在那之前,在QApplication
实例化之后,我已经得到了 MacOSX 停靠图标。【参考方案6】:
PyPhantomJs 是使用 pyqt 的无头网页浏览器,甚至 IT 也使用 QApplication:http://code.google.com/p/phantomjs/source/browse/python/pyphantomjs/pyphantomjs.py?name=4ec8df3a84&r=4dc051a60ec3d59bf125838a5caa2a24d59bd0ee
您始终可以只使用使应用程序作为系统托盘应用程序运行的各种窗口标志
更新
因为我看到您使用的是 osx,所以您可以将此设置添加到您的应用程序列表中,以使其作为没有图标的系统服务启动:http://www.cocoadev.com/index.pl?LSBackgroundOnly
我将它用于位于顶部任务栏中并提供聚光灯样式界面的应用程序
【讨论】:
从该代码来看,它似乎不是无头的(以我在这里要求的方式 - 即没有窗口,没有停靠图标,什么都没有)。它甚至设置了一个窗口图标。 这并不意味着它不是无头的,因为它有一个应用程序图标。 Phantomjs 是一个通过 javascript 或 Python 驱动的无头浏览器。没有窗口或内容的任何视觉表示 我很确定setWindowIcon
设置了 MacoSX 停靠图标。或者,如果它根本不可见,为什么要设置它?关于您的更新:是的,我已经阅读过它。这接近我想要的。但是,它需要在 App bundle Info 文件中。就我而言,我不会有一个可以放入其中的应用程序包——它只是一个简单的命令行实用程序。
好吧,我的朋友,我认为你陷入了僵局。您需要使用 qapplication。祝你的解决方案好运!
顺便说一句,PhantomJS 从 1.5 版开始转变为不需要窗口服务器(通过 QPA/lighthouse)。但是,由于某些 pyqt4 的原因,pyphantomjs 不包含这些更改。以上是关于如何在非 GUI 应用程序中使用 QWebPage的主要内容,如果未能解决你的问题,请参考以下文章
如何从 QWebPage 使用的 QNetworkReply 读取数据?
在非 gui 线程中获取文件图标 (QFileIconProvider::icon)