12.7. Creating a KParts Application

If an application wants to use parts and the GUI merging feature, its own GUI needs to be defined in XML. The top level windows of the application will then use the class KParts::MainWindow.

Note that it's also possible to use a part in a standard application, using KTMainWindow, but then no GUI merging happens. In this case, only the functionality provided by the widget and by the part API are available, so the application has to create the GUI for part's functionality itself, or the part has to provide it through context menus. In any case, it is much less flexible.

As an example of a window based on KParts::MainWindow, you are going to create a PostScript viewer very easily, by embedding the part provided by KDE's PostScript viewer, KGhostView.

Note

You need to install the package kdegraphics if you want to test this example.

The first thing to look at is the mainwindow's GUI; an example is given in Listing 12.11.


Example 12.11. ghostviewtest_shell.rc: The Mainwindow's GUI

   1 
   2 <!DOCTYPE kpartgui SYSTEM "kpartgui.dtd">
   3 <kpartgui name="KGVShell" version="1">
   4 <MenuBar>
   5  <Menu name="file"><text>&amp;File</text>
   6   <Action name="file_open"/>
   7   <Merge/>
   8   <Action name="file_quit"/>
   9 </Menu>
  10 </MenuBar>
  11 <ToolBar name="KGV-ToolBar"><text>KGhostView</text>
  12  <Action name="file_open"/>
  13  <Action name="file_quit"/>
  14 </ToolBar>
  15 </kpartgui>
  16 				
  17 				
  18 				
  19 				
  20 				
  21 			

By analogy with a command line's shell, a main window is often called a shell. In its GUI you define the actions that will always be shown, whichever part is active. The listing for a simple KParts mainwindow is shown in Listing 12.12


Example 12.12. ghostviewtest.h: Header for a Simple KParts Mainwindow

   1 
   2  1: #include <kparts/mainwindow.h>
   3  2:
   4  3: class Shell : public KParts::MainWindow
   5  4: {
   6  5:   Q_OBJECT
   7  6: public:
   8  7:   Shell();
   9  8:   virtual ~Shell();
  10  9:
  11 10:   void openURL( const KURL & url );
  12 11:
  13 12: protected slots:
  14 13:   void slotFileOpen();
  15 14:
  16 15: private:
  17 16:   KParts::ReadOnlyPart *m_gvpart;
  18 17: };
  19 				
  20 				
  21 			

The mainwindow inherits KParts::MainWindow instead of KTMainWindow. Nothing else is required; the openURL() here is just so that main() can call openURL() on the window. The URL could be passed to the constructor instead.

The code for the mainwindow embedding the KGhostView part is part of the KParts examples, which can be found under kdelibs/kparts/tests/ghostview*, so Listing 12.13 only shows the relevant lines of ghostview.cpp.


Example 12.13. Excerpt of ghostviewtest.cpp: Implementation of the Simple KParts Mainwindow

   1 
   2  1: Shell::Shell()
   3  2: {
   4  3:   setXMLFile( "ghostviewtest_shell.rc" );
   5  4:
   6  5:   KAction * paOpen = new KAction( i18n( "&Open file" ), "fileopen", 0,
   7  6:             this, SLOT( slotFileOpen() ), actionCollection(), "file_open" );
   8  7:
   9  8:   KAction * paQuit = new KAction( i18n( "&Quit" ), "exit", 0,
  10  9:             this, SLOT( close() ), actionCollection(), "file_quit" );
  11 10:
  12 11:   // Try to find libkghostview
  13 12:   KLibFactory *factory = KLibLoader::self()->factory( "libkghostview" );
  14 13:   if (factory)
  15 14:   {
  16 15:     // Create the part
  17 16:     m_gvpart = (KParts::ReadOnlyPart *)factory->create( this, "kgvpart",
  18 17:                "KParts::ReadOnlyPart" );
  19 18:     // Set the main widget
  20 19:     setView( m_gvpart->widget() );
  21 20:     // Integrate its GUI
  22 21:     createGUI( m_gvpart );
  23 22:   }
  24 23:   else
  25 24:     kdFatal() << "No libkghostview found !" << endl;
  26 25: }
  27 26:
  28 27: Shell::~Shell()
  29 28: {
  30 29:   delete m_gvpart;
  31 30: }
  32 31:
  33 32: void Shell::openURL( const KURL & url )
  34 33: {
  35 34:   m_gvpart->openURL( url );
  36 35: }
  37 				
  38 				
  39 				
  40 				
  41 				
  42 			

A mainwindow is created much like a part, with an XML file and actions. To find a part, it uses KLibLoader to get the KLibFactory for the library. A flexible application would use .desktop files for this and KIO's trader for selecting the user's preferred component, but for the sake of simplicity, open the library by its name here. After the factory has been created, the mainwindow makes it create a ReadOnlyPart, and because here you have only one part in the window, the part's widget is set as the main widget of the window with setView. Then a mainwindow needs to call createGUI() to make the framework create the GUI, merging the actions of the mainwindow with those of the active part. A mainwindow with no part will simply call createGUI(0L).

Using this mainwindow, for instance from main(), is as simple as


   1 
   2 Shell *shell = new Shell;
   3 shell->openURL( url );
   4 shell->show();
   5 

Compile kdelibs/kparts/tests/ghostviewtest to test this simple example of how to embed a part.