![]() |
Home | ![]() |
The QtBrowserPlugin solution makes it easy to write browser plugins that can be used in Netscape, Mozilla FireFox, Opera, and any other web browser supporting the "npruntime" API:
http://www.mozilla.org/projects/plugins/ http://www.mozilla.org/projects/plugins/npruntime.html
Current versions of Microsoft Internet Explorer do not support this API. However, you can use the ActiveQt framework to compile a single plugin library that works with all web browsers.
Since any QWidget or QObject subclass can be turned into a plugin with little effort it is usually easiest to do the development as a stand-alone Qt application - debugging plugins is cumbersome.
Make sure that the subclasses you want to export use the Q_OBJECT macro and provide a default constructor. Use the Q_CLASSINFO macro to specify a list of MIME types each of your classes supports, and export the classes through the QtNPFactory macros:
QTNPFACTORY_BEGIN("Qt-based Graph Plugin", "A Qt-based LiveConnected plug-in that graphs numeric data"); QTNPCLASS(Graph) QTNPFACTORY_END()
Include the qtbrowserplugin.pri in your .pro file, and regenerate the makefile with qmake. The resulting makefile will generate a shared library with a file name starting with "np" - this is required by all browsers to recognize the library as a plugin.
On Windows it is required to link a version resource into the plugin library. To do that, create an .rc file (a plain-text file) and add it to the RC_FILE variable of your project. The .rc file needs to contain a version description like here:
1 VERSIONINFO FILEVERSION 1,0,0,1 PRODUCTVERSION 1,0,0,1 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L #else FILEFLAGS 0x0L #endif FILEOS 0x4L FILETYPE 0x2L FILESUBTYPE 0x0L BEGIN BLOCK "StringFileInfo" BEGIN BLOCK "040904e4" BEGIN VALUE "Comments", "\0" VALUE "CompanyName", "Trolltech\0" VALUE "FileDescription", "grapher\0" VALUE "FileExtents", "g1n\0" VALUE "FileOpenName", "Graphable data (*.g1n)\0" VALUE "FileVersion", "1, 0, 0, 1\0" VALUE "InternalName", "grapher\0" VALUE "LegalCopyright", "Copyright 1997 Trolltech ASA\0" VALUE "LegalTrademarks", "\0" VALUE "MIMEType", "application/x-graphable\0" VALUE "OriginalFilename", "grapher.dll\0" VALUE "PrivateBuild", "\0" VALUE "ProductName", "Trolltech grapher\0" VALUE "ProductVersion", "1, 0, 0, 1\0" VALUE "SpecialBuild", "\0" END END BLOCK "VarFileInfo" BEGIN VALUE "Translation", 0x409, 1252 END END
To build a plugin project with ActiveX support, use ActiveQt's QAxServer module by adding the following line to your project:
CONFIG += qaxserver
Also, add the following line to your resource file
1 TYPELIB "thisfile.rc"
In your plugin code, use Q_CLASSINFO and the QAxFactory macros as usual.
When you build the plugin, then ActiveQt will perform the build steps required to turn the plugin library into an ActiveX control server which provides your plugin classes not only to browsers supporting the npruntime API, but also to browsers supporting ActiveX controls (i.e. Internet Explorer).
However, not that calling QtNPBindable APIs will not do anything when the browser does not support the npruntime API. In some cases, QAxBindable provides equivalent APIs (i.e. for reading incoming data).
On Unix/Linux, QtBrowserPlugin uses the XEmbed protocol. This is a fairly recent addition to the NPP plugin API. At the time of writing, it is not supported by the Opera and Konqueror browsers. Firefox and other Mozilla/Gecko-based browsers do support it.
To install the plugin, copy the file myplugin.so to the browser or system plugin directory, typically /usr/lib/browser-plugins.
There are two known issues that may cause the plugin to crash on initialization, possibly taking the browser down with it:
In addition, Firefox may emit this warning when initializing the plugin: _XEMBED_INFO property has wrong type. This is fixed in Qt 4.3.1 and later.
To build a browser plugin on Mac, two plain-text resource files are needed: an Info.plist file and a .r file. To create these files, it is easiest to use the ones provided with the QtBrowserPlugin examples as templates, editing as necessary. Then add them to your project (.pro file) like this:
QMAKE_INFO_PLIST = Info.plist REZ_FILES += grapher.r rsrc_files.files = grapher.rsrc rsrc_files.path = Contents/Resources QMAKE_BUNDLE_DATA += rsrc_files
Most browsers provide a UI to display all loaded plugins. Use this functionality to diagnose problems.
Windows: To install the plugin, copy the plugin library in the "plugins" directory of the browser. If the plugin is not loaded, then make sure that DLLs your plugin depends on (i.e. Qt) are located in a suitable directory in which the system searches for DLLs (note that this does usually not include the same directory as the plugin DLL).
Mac: The build will result in a directory called myplugin.plugin. To install, copy this directory with all contents to /Library/Internet Plugins.
Different browser support different embedding tags, but the following should work with Netscape, FireFox, Opera and Internet Explorer (if the plugin has been compiled as an ActiveX server as well).
Objects can be initialized with a data file, which will be delivered to the plugin at some point after plugin creation to the plugin through the QtNPBindable::readData() virtual function.
<object type="application/x-graphable" data="graph.g1n" width=50% height=300> Plugin not installed! </object>
<object data="http://doc.trolltech.com/3.3/graph.g1n" width=50% height=300>
Plugin not installed!
</object>
Note that some browsers will not display or immediately unload the plugin if the data file does not exist, while other browsers will display the plugin without ever calling readData().
<embed type="trivial/very" [property]=[value]>
For additional information, see http://devedge-temp.mozilla.org/library/manuals
Plugins embedded into browsers that support the respecive NPAPI extensions as well as ActiveX controls can be accessed from JavaScript in the HTML page.
Before the object can be accessed, some browsers require it to be located based on the id in the object tag.
<object id="ScriptableObject" TYPE=trivial/very WIDTH=200 HEIGHT=100 text="Very Scriptable!"> </object> <script language=JavaScript> var ScriptableObject = document.getElementById('ScriptableObject');
Object properties and public slots can then be accessed as usual. The QtBrowserPlugin implementation supports properties and slots that have parameters and types that QVariant can be convert to and from strings, or that are QObjects. Only public slots and scriptable properties are exposed. If the QObject class sets a "ToSuperClass" Q_CLASSINFO, then only slots and properties up to the specified superclass are exposed. See the QAxServer documentation provided with Qt for more information.
JavaScript functions can be connected to Qt signals emitted by the Qt plugin object.
ScriptableObject.text = 'This is some text' var oldText ScriptableObject.mouseDown = function() { oldText = ScriptableObject.text ScriptableObject.text = 'Mouse Down' } ScriptableObject.mouseMove = function(x, y) { ScriptableObject.text = 'Mouse at ' + x + ',' + y } ScriptableObject.mouseUp = function() { ScriptableObject.text = oldText } </script>
Assign a function to a property of the object with the same name as the signal. Overloads (i.e. two signal with the same name, but different parameters) are not possible.
<!-- Special hookup code required for Internet Explorer --> <script language=JScript> function ScriptableObject::mouseDown() { ScriptableObject.mouseDown() } function ScriptableObject::mouseMove(x, y) { ScriptableObject.mouseMove(x, y) } function ScriptableObject::mouseUp() { ScriptableObject.mouseUp() } </script>
Internet Explorer requires a special syntax that is not compatible with other browsers, but the IE-specific function can just call the other functions.
Plugin objects can be embedded as form elements. To specify which property value the plugin should report to the form upon submission, specify the name of the property as the DefaultProperty using a Q_CLASSINFO entry:
Q_OBJECT Q_CLASSINFO("MIME", "trivial/very:xxx:Trivial and useless") Q_CLASSINFO("DefaultProperty", "text")
In the HTML page, embed the object as usual:
<form method="get" action="http://www.server.com/search.asp">
<table>
<tr>
<td>Search:</td>
<td><object type="trivial/very" name="text" WIDTH=100 HEIGHT=20></object></td>
<td><input type="submit" value="Check"></td>
</tr>
</table>
</form>
Clicking the button will make the browser request a URL
http://www.server.com/search.asp?text=[value from object]
The property type needs to be convertible to a string.
Copyright © 2007 Trolltech | Trademarks | Qt Solutions |