Difference between revisions of "Development/Languages/Python/Using PyKDE 4"

Jump to: navigation, search
m (Text replace - "<code cpp>" to "<syntaxhighlight lang="cpp">")
m (Text replace - "<code python>" to "<syntaxhighlight lang="python">")
 
(One intermediate revision by one user not shown)
Line 6: Line 6:
 
All PyKDE4 modules are included in a single Python package named (oddly) "PyKDE4". That means that to import a PyKDE4 module, you must also include the package name as a prefix:  
 
All PyKDE4 modules are included in a single Python package named (oddly) "PyKDE4". That means that to import a PyKDE4 module, you must also include the package name as a prefix:  
  
<code python>
+
<syntaxhighlight lang="python">
 
from PyKDE4.kdeui import KApplication
 
from PyKDE4.kdeui import KApplication
 
...
 
...
 
app = KApplication ()
 
app = KApplication ()
</code>
+
</syntaxhighlight>
 
or
 
or
<code python>
+
<syntaxhighlight lang="python">
 
import PyKDE4.kdeui
 
import PyKDE4.kdeui
 
...
 
...
 
app = PyKDE4.kdeui.KApplication
 
app = PyKDE4.kdeui.KApplication
</code>
+
</syntaxhighlight>
  
 
There are other forms of the import statement that will also work. All of the PyKDE4 examples and tutorials use the first form shown above. We recommend you do not use:  
 
There are other forms of the import statement that will also work. All of the PyKDE4 examples and tutorials use the first form shown above. We recommend you do not use:  
  
<code python>
+
<syntaxhighlight lang="python">
 
from PyKDE4.kdeui import *
 
from PyKDE4.kdeui import *
</code>
+
</syntaxhighlight>
  
 
although we expect many users will. It will work in most, but probably not all cases, as there may be name clashes between objects in the different PyKDE4 modules.
 
although we expect many users will. It will work in most, but probably not all cases, as there may be name clashes between objects in the different PyKDE4 modules.
Line 37: Line 37:
 
==KCmdLineArgs, KAboutData==
 
==KCmdLineArgs, KAboutData==
 
The notable exceptions to the above rule about constructing a KApplication object before using any other PyKDE4 object are the KCmdLineArgs and KAboutData classes.  
 
The notable exceptions to the above rule about constructing a KApplication object before using any other PyKDE4 object are the KCmdLineArgs and KAboutData classes.  
<code python>
+
<syntaxhighlight lang="python">
 
import sys
 
import sys
 
from PyKDE4.kdecore import ki18n, KAboutData, KCmdLineArgs
 
from PyKDE4.kdecore import ki18n, KAboutData, KCmdLineArgs
Line 63: Line 63:
  
 
app = KApplication ()
 
app = KApplication ()
</code>
+
</syntaxhighlight>
 
You can, of course, substitute you own values for the KAboutData arguments.
 
You can, of course, substitute you own values for the KAboutData arguments.
  
Line 79: Line 79:
  
 
First, under PyQt4 and PyKDE4, a slot may be any Python callable - a function, or class method. The general form for connecting a signal to a slot is:  
 
First, under PyQt4 and PyKDE4, a slot may be any Python callable - a function, or class method. The general form for connecting a signal to a slot is:  
<code python>
+
<syntaxhighlight lang="python">
 
self.connect (self.button, SIGNAL ("clicked ()"), self.buttonClicked)
 
self.connect (self.button, SIGNAL ("clicked ()"), self.buttonClicked)
 
self.connect (self.tree, SIGNAL ('itemClicked (QTreeWidgetItem *, int)'),
 
self.connect (self.tree, SIGNAL ('itemClicked (QTreeWidgetItem *, int)'),
Line 89: Line 89:
 
def treeItemClicked (self, item, n):
 
def treeItemClicked (self, item, n):
 
   ...
 
   ...
</code>
+
</syntaxhighlight>
 
'self.button' and 'self.tree' are concrete instances of the objects that emit the signals. The example assumes that the "self" used with "connect" is a subclass of QObject - any subclass, or even QObject itself, since "connect" is a static method (there is basically a single 'connect' method shared by all QObject descendants).  
 
'self.button' and 'self.tree' are concrete instances of the objects that emit the signals. The example assumes that the "self" used with "connect" is a subclass of QObject - any subclass, or even QObject itself, since "connect" is a static method (there is basically a single 'connect' method shared by all QObject descendants).  
  
Line 104: Line 104:
 
The namespace name ("Solid" in this case) is a required prefix for all of the namespace's objects.  
 
The namespace name ("Solid" in this case) is a required prefix for all of the namespace's objects.  
  
<code python>
+
<syntaxhighlight lang="python">
 
from PyKDE4.solid import Solid
 
from PyKDE4.solid import Solid
 
...
 
...
Line 131: Line 131:
 
                                   "%i MB" % (volume.size ()/1024/1024),
 
                                   "%i MB" % (volume.size ()/1024/1024),
 
                                   usageType2Str [volume.usage ()]])
 
                                   usageType2Str [volume.usage ()]])
</code>
+
</syntaxhighlight>
  
 
==Version Information==
 
==Version Information==
 
Information about the installed versions of KDE and PyKDE4 is programmatically available from global functions in the PyKDE4.kdecore module. For example:  
 
Information about the installed versions of KDE and PyKDE4 is programmatically available from global functions in the PyKDE4.kdecore module. For example:  
<code python>
+
<syntaxhighlight lang="python">
 
         import PyKDE4.kdecore as kdecore
 
         import PyKDE4.kdecore as kdecore
 
         print kdecore.version ()
 
         print kdecore.version ()
</code>
+
</syntaxhighlight>
 
The following table lists the available functions and the result they return (using KDE 4.0.2 or PyKDE 4.0.2 as an example)  
 
The following table lists the available functions and the result they return (using KDE 4.0.2 or PyKDE 4.0.2 as an example)  
  
Line 164: Line 164:
 
<syntaxhighlight lang="cpp">
 
<syntaxhighlight lang="cpp">
 
virtual int someMethod (int x, int y) = 0;
 
virtual int someMethod (int x, int y) = 0;
</code>
+
</syntaxhighlight>
 
is the C++ representation of a pure virtual method (the "= 0" is the defining characteristic, along with the virtual modifier on the front end).  
 
is the C++ representation of a pure virtual method (the "= 0" is the defining characteristic, along with the virtual modifier on the front end).  
  

Latest revision as of 20:43, 29 June 2011

PyKDE4 includes many example programs and several tutorials to help you begin writing KDE4 applications using Python. The documentation has also been enhanced. The easiest way to begin with PyKDE4 is to copy some of the examples or tutorial code to your home directory, and then examine and experiment with the code provided.

PyKDE4 development is also made considerably easier by the use of an integrated environment, like eric4, or at least through the use of a debugger which can single step and allow you to examine values as your program executes.

Contents

[edit] Importing Modules

All PyKDE4 modules are included in a single Python package named (oddly) "PyKDE4". That means that to import a PyKDE4 module, you must also include the package name as a prefix:

from PyKDE4.kdeui import KApplication
...
app = KApplication ()

or

import PyKDE4.kdeui
...
app = PyKDE4.kdeui.KApplication

There are other forms of the import statement that will also work. All of the PyKDE4 examples and tutorials use the first form shown above. We recommend you do not use:

from PyKDE4.kdeui import *

although we expect many users will. It will work in most, but probably not all cases, as there may be name clashes between objects in the different PyKDE4 modules.

[edit] KApplication Required

Nearly every KDE4 (and consequently PyKDE4) application requires a KApplication object be constructed before using most other PyKDE4 (KDE4) objects in your program. KApplication also runs the event loop that allows PyKDE4 objects to communicate with each other.Nearly every example provided with PyKDE4 includes the basic code necessary to create an application using KApplication.

QApplication is not a substitute for KApplication in programs that use KDE4 objects.

A KUniqueApplication object is a subclass of KApplication and will also work. You may also subclass your own classes from KApplication.

See the next section for code that creates a KApplication instance.

[edit] KCmdLineArgs, KAboutData

The notable exceptions to the above rule about constructing a KApplication object before using any other PyKDE4 object are the KCmdLineArgs and KAboutData classes.

import sys
from PyKDE4.kdecore import ki18n, KAboutData, KCmdLineArgs
from PyKDE4.kdeui import KApplication
 
...
 
 
appName     = "KApplication"
catalog     = ""
programName = ki18n ("KApplication")
version     = "1.0"
description = ki18n ("KApplication/KMainWindow/KAboutData example")
license     = KAboutData.License_GPL
copyright   = ki18n ("(c) 2007 Jim Bublitz")
text        = ki18n ("none")
homePage    = "www.riverbankcomputing.com"
bugEmail    = "jbublitz@nwinternet.com"
 
aboutData   = KAboutData (appName, catalog, programName, version, description,
                        license, copyright, text, homePage, bugEmail)
 
 
KCmdLineArgs.init (sys.argv, aboutData)
 
app = KApplication ()

You can, of course, substitute you own values for the KAboutData arguments.

Even if you don't plan on passing command line arguments to your program, KApplication still requires KCmdLineArgs (or one of several equivalents) be used to pass the command line arguments to KApplication.

Also, KAboutData does more than set the data for your "about application" dialog on the help menu. The appName or programName values are used to define your application in other areas, especially by DBUS. DBUS apparently doesn't like dots (".") in the appName or programName values, so leave the ".py" extension off in those places, or replace the dots with an underscore ('_' - for example, application_py)

The use of ki18n as shown is virtually required. The KAboutData constructor requires KLocalizedString types in the four locations shown, and there is almost no way to create an object of KLocalizedString type except by using ki18n. i18n (without the leading 'k') will not work.

Many of the arguments to the KAboutData constructor are optional - see the KAboutData docs for the complete Python signature.

[edit] Signals and Slots

The PyQt4 docs have a more complete explanation of signals and slots. There are several points that deserve notice.

First, under PyQt4 and PyKDE4, a slot may be any Python callable - a function, or class method. The general form for connecting a signal to a slot is:

self.connect (self.button, SIGNAL ("clicked ()"), self.buttonClicked)
self.connect (self.tree, SIGNAL ('itemClicked (QTreeWidgetItem *, int)'),
    self.treeItemClicked)
 
def buttonClicked (self):
   ...
 
def treeItemClicked (self, item, n):
   ...

'self.button' and 'self.tree' are concrete instances of the objects that emit the signals. The example assumes that the "self" used with "connect" is a subclass of QObject - any subclass, or even QObject itself, since "connect" is a static method (there is basically a single 'connect' method shared by all QObject descendants).

Note also that the argument to SIGNAL is a string which represents the C++ signature of the signal, without variable names, but *with* argument types, including any 'const', '*', '&' or other decoration. The C++ signatures are reproduced in the PyKDE4 class documentation, so you can just cut and paste them into your code.

The slot named must have a signature which matches the number of arguments in the signal signature. The types of the arguments passed into the slot when the signal is emitted will match the types in the C++ signature (but in this case without the effect of any decorations).

It's important to write both the connect and slot methods carefully, as signal/slot errors will often fail silently - without any error or exception being produced, but also without your code working as expected. If signals appear to be not connecting to slots, check the syntax in the connect statement and slot argument list first.

[edit] Namespaces

For PyKDE4 objects which are enclosed in a (C++) namespace. importing the namespace also gets you all of the objects in the namespace. For example, the objects "StorageVolume", "DeviceInterface", "DeviceInterface.StorageVolume", and "Device", in the code snippet below all reside in the "Solid" namespace. All were imported via the single import statement shown.

The namespace name ("Solid" in this case) is a required prefix for all of the namespace's objects.

from PyKDE4.solid import Solid
...
# convert enum values to strings for display
    usageType2Str = { Solid.StorageVolume.Other : "Other",\
                      Solid.StorageVolume.Unused : "Unused",\
                      Solid.StorageVolume.FileSystem : "File System",
                      Solid.StorageVolume.PartitionTable : "Partition Tbl",\
                      Solid.StorageVolume.Raid : "Raid",\
                      Solid.StorageVolume.Encrypted : "Encrypted"
                    }
 
    # retrieve a list of Solid.Device for this machine
    deviceList = Solid.Device.allDevices ()
 
    # filter the list of all devices and display matching results
    # note that we never create a Solid.StorageVolume object,
    # but receive one from the 'asDeviceInterface" call
    for device in deviceList:
        if device.isDeviceInterface (Solid.DeviceInterface.StorageVolume):
        volume = device.asDeviceInterface (Solid.DeviceInterface.StorageVolume)
        QTreeWidgetItem (display, [device.product (),
                                   volume.fsType (),
                                   volume.label (),
                                   str (volume.isIgnored ()),
                                   "%i MB" % (volume.size ()/1024/1024),
                                   usageType2Str [volume.usage ()]])

[edit] Version Information

Information about the installed versions of KDE and PyKDE4 is programmatically available from global functions in the PyKDE4.kdecore module. For example:

        import PyKDE4.kdecore as kdecore
        print kdecore.version ()

The following table lists the available functions and the result they return (using KDE 4.0.2 or PyKDE 4.0.2 as an example)

Returns KDE PyKDE example
int version() pykde_version() 212646L (or 0x040002)
int versionMajor() pykde_versionMajor() 4
int versionMinor() pykde_versionMinor() 0
int versionRelease() pykde_versionRelease() 2
string versionString() pykde_versionString() "4.0.2" [note 1]

Note 1: The *versionString functions will return a string that begins with a string representation of the version number,but may also return additional information in the string, such as build or release number, packager, etc.

[edit] Abstract Classes

An abstract class is a base class that cannot be instantiated itself, but can be used as a base class for other classes. You can't create an instance of an abstract class.

Abstract classes are denoted in C++ by having one or more 'pure virtual' methods.

virtual int someMethod (int x, int y) = 0;

is the C++ representation of a pure virtual method (the "= 0" is the defining characteristic, along with the virtual modifier on the front end).

In order to derive a class from an abstract class, you have to 'overload' or define (with code) all of the pure virtual methods. So in the example above, your Python class derived from an abstract class would have to contain 'def somemethod (self, x, y)' along with code for the method to execute. The argument list must match the argument list in the pure virtual method (with the addition of 'self').

The PyKDE4 docs clearly label all abstract classes, and label their pure virtual methods as well.



This page is copyright 2007-2008 Jim Bublitz and licensed under Commons Attribution-Share Alike 3.0 Unported.


This page was last modified on 29 June 2011, at 20:43. This page has been accessed 16,630 times. Content is available under Creative Commons License SA 3.0 as well as the GNU Free Documentation License 1.2.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V.Legal