4

I want to use QWebPage in a non-GUI Qt application. By that, I mean that I don't want to communicate with the window server at all. Using QtGui is not a problem, though.

QWebPage internally creates some QWidget instances. Thus, using QCoreApplication is not possible.

When creating a QApplication instance though, I already immediately get a MacOSX dock icon. And I don't want that. It also means that it somehow registers itself in Cocoa as a GUI application.

My question is not Mac-only. I would like to know if there is an "official" way for Qt to do this. Only if there is not, I would like to know specific ways to do this, e.g. on Mac for now.


Somewhat more specific about Mac:

There is also the LSBackgroundOnly property which can be set for an App bundle and which goes into the direction to what I want (whereby I'm still not sure if it is really truly console-only, e.g. would also work without Quartz, etc.). However, I don't have an App bundle at all; it's just a simple binary (to be used as a command-line-tool in shells).

For now, I have a small workaround to hide the dock icon but that is quite ugly as it first pops up and then goes aways: (Python code but that doesn't really matter...)

def hideMacDockIcon():
    # http://stackoverflow.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()

Also, I'm not sure if it also works in other environments, maybe as a system daemon or so.

Albert
  • 65,406
  • 61
  • 242
  • 386

6 Answers6

5

You can do this with QPA. This happens to be how PhantomJS achieved headlessness. The QT preconfig file was modified to specify QPA:

QT_CFG +=' -qpa' # X11-less with QPA (aka Lighthouse)

Also something about QMinimalWindowSurface.

https://github.com/ariya/phantomjs/commit/6c8a1c2dc1 https://github.com/ariya/phantomjs/commit/c78ae190a9

kanzure
  • 1,331
  • 11
  • 15
  • 2
    I had some trouble finding more information about this. [Here](http://blog.qt.digia.com/blog/2011/05/31/lighthouse-has-grown-up-now/) is the initial announcement of Lighthouse. It seems that it is included since Qt 4.8. But (why) do you need the compiler config option? Isn't that (Qt Platform Abstraction) something which is always there as it is an abstraction? Also, along the way, I also found [node-chimera](https://github.com/deanmao/node-chimera). – Albert Mar 18 '13 at 13:29
  • 1
    @kanzure can you please give more details about how phantomjs implemented this using qpa. There is not many documentation about it. – Emil Condrea Sep 16 '14 at 17:36
  • Sorry, I really don't know much about this. I remember finding someone talking about enabling or disabling QPA/Lighthouse somewhere in the PhantomJS mailing list. There may be more details there? – kanzure Sep 16 '14 at 23:01
4

QApplication initializes static variables that are used by QWidgets. So you will not be able to create any widgets until you create an QApplication instance.

If you need a browser try using Webkit, Chromium, Berkelium, Awesomium(commersial) or chromiumoffscreenrenderer(LGPL fork)

Dmitriy
  • 5,357
  • 8
  • 45
  • 57
  • Well, yea, this is what I want but this is off-topic here because I'm asking specifically about `QWebPage`. Also, I don't really mind wether I use `QApplication` or `QCoreApplication`. I just don't want to have any GUI interaction. But I currently have, it creates a MacOSX dock icon if I use `QApplication` and I don't want that. – Albert Feb 19 '12 at 01:53
  • @Albert, you should ask another question: How to not spawn app icon on Mac in my Qt GUI application. – Dmitriy Feb 19 '12 at 08:01
  • I'm not sure if that is really the only thing. That is the visible thing so far. There might be other things, e.g. the app can get focus, etc. I want to be sure that I can also run it in any environment, when Quartz is not running, for example. – Albert Feb 19 '12 at 15:38
1

Have you tried passing the 'no gui' flag to QApplication?

QApplication ( int & argc, char ** argv, bool GUIenabled )
Tim Sutton
  • 661
  • 5
  • 4
  • 1
    Yes, doesn't work. I also read somewhere (maybe docs, maybe Qt source, don't remember anymore) that is has no effect in many cases, esp. on MacOSX. – Albert Feb 24 '12 at 22:55
0

What is it that you want to use QWebPage for? Maybe there is a class better suited for your needs?
If not: Copy and pasting from QWebPage's source code is an option.

Update:
Do you want to create something like a command line browser? Or just something that looks like a browser to a web server?
In these cases you might just hide the QWidget so nothing appears in the dock bar (not sure if this is how it works on OS X; on Windows it's possible to have windows with no task-bar entry, I think).

foraidt
  • 5,519
  • 5
  • 52
  • 80
  • I need some object which can load some web page, maybe render it, has all the usual browser functionality like history, cookies, etc. – Albert Feb 09 '12 at 15:22
  • I don't see how copying the QWebPage source should help. It seems that the WebCore itself is creating widgets. Maybe WebKit just needs widgets. But then the question is: How can I do that in a non GUI-application? Or is there some dummy GUI? – Albert Feb 09 '12 at 15:23
  • I don't see how you would render a web page in a non-GUI application... do you want your application to generate an image of the rendered web page or something like that? – foraidt Feb 09 '12 at 19:08
  • Doesn't matter. Right now, I don't need rendering at all. And if I need it later, I would only need it in memory. – Albert Feb 09 '12 at 22:49
  • What do you mean by hiding? Anyway, much before that, right after the `QApplication` instantiation, I already get the MacOSX dock icon. – Albert Feb 19 '12 at 01:56
0

I am afraid there is no simple way of not using QtGui. If you look at the source code of QWebPage, you see that a QPainter is used, as some exported methods\objects from QtGui. This was expected as you have functions like QWidget* QWebPage::view() const in the API.

You can hack the source code thought but then your Qt libraries are unique and incompatible .That is a burden.

UmNyobe
  • 22,539
  • 9
  • 61
  • 90
  • Well, it is not really a problem of using QtGui. I just don't want to create any windows or anything else and not communicate with the window server at all. – Albert Feb 09 '12 at 15:36
  • You won't communicate with window server until you won't show window. – Kamil Klimek Feb 11 '12 at 13:39
  • @KamilKlimek: It does. It creates a MacOSX dock icon right after the instantiation of `QApplication`. – Albert Feb 19 '12 at 01:54
  • 1
    Then you should embed Info.plist file into your executable. In Info.plist file you can set that application has no dock icon. To your linker flags you should add -sectcreate __TEXT __info_plist PATH/TO/Info.plist – Kamil Klimek Feb 20 '12 at 09:15
0

PyPhantomJs is a headless webrowser using pyqt, and even IT uses QApplication: http://code.google.com/p/phantomjs/source/browse/python/pyphantomjs/pyphantomjs.py?name=4ec8df3a84&r=4dc051a60ec3d59bf125838a5caa2a24d59bd0ee

You can always just Use the various window flags that make the app run as a system tray app

update

since I see you are using osx, you can add this setting to your apps plist to make it launch as a system service with no icons: http://www.cocoadev.com/index.pl?LSBackgroundOnly

I use this for an app that sits in the taskbar on the top and provides a spotlight style interface

jdi
  • 90,542
  • 19
  • 167
  • 203
  • 1
    From that code, it doesn't seem to be headless (in the way I am asking for here - i.e. no window, no dock icon, nothing). It even setups a window icon. – Albert Feb 18 '12 at 23:34
  • That does not mean it isnt headless just because it has an app icon. Phantomjs is a headless browser that is driven via javascript or Python. There is no window or any visual representation of the content – jdi Feb 19 '12 at 05:16
  • 1
    I'm quite sure `setWindowIcon` sets the MacoSX dock icon. Or if it would never ever be visible at all, why set it? About your update: Yes, I already read about it. This comes close to what I want. However, it's needed to be in the App bundle Info file. In my case, I will not have an app bundle where I can put it in -- it's a simple command line only utility. – Albert Feb 19 '12 at 15:47
  • Well my friend I think you are at an impass. You need to use qapplication. Good luck on your solution! – jdi Feb 19 '12 at 16:12
  • Btw, PhantomJS transitioned to not requiring a window server as of version 1.5 (through QPA/lighthouse). However, pyphantomjs does not include these changes because of some pyqt4 reasons. – kanzure Mar 18 '13 at 07:05