<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>dennogumi.org &#187; pykde</title>
	<atom:link href="http://www.dennogumi.org/tag/pykde/feed" rel="self" type="application/rss+xml" />
	<link>http://www.dennogumi.org</link>
	<description>On the web since 1999</description>
	<lastBuildDate>Fri, 06 Jan 2012 14:56:54 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>PyKDE4: Queries with Nepomuk</title>
		<link>http://www.dennogumi.org/2011/06/pykde4-queries-with-nepomuk</link>
		<comments>http://www.dennogumi.org/2011/06/pykde4-queries-with-nepomuk#comments</comments>
		<pubDate>Wed, 29 Jun 2011 19:27:42 +0000</pubDate>
		<dc:creator>Einar</dc:creator>
				<category><![CDATA[KDE]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[pykde]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://www.dennogumi.org/?p=924</guid>
		<description><![CDATA[In one of my previous blog posts I dealt with tagging files and resources with Nepomuk. But Nepomuk is not only about storing metadata, it is also about retrieving&#160;and interrogating data. Normally, this would mean querying the metadata database directly, &#8230; <a href="http://www.dennogumi.org/2011/06/pykde4-queries-with-nepomuk">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>In one of my previous blog posts I dealt with <a href="http://www.dennogumi.org/2010/10/pykde4-tag-and-annotate-files-using-nepomuk">tagging files and resources with Nepomuk</a>. But Nepomuk is not only about storing metadata, it is also about <i>retrieving</i>&nbsp;and <i>interrogating </i>data. Normally, this would mean querying the metadata database directly, using queries written in SPARQL. But this is not intuitive, can be inefficient (if you do things the wrong way) and error prone (oops, I messed up a parameter!).&nbsp;
<p>Fortunately, the Nepomuk developers have come up with a high level API to query already stored metadata, and today&#8217;s post will deal with querying tags in Nepomuk. As per the past tutorials, the full source code is available <a href="https://projects.kde.org/projects/kde/kdeexamples/repository/revisions/master/changes/bindings/python/nepomuk/nepomuk_tag_query_example.py">in the kdeexamples module</a>.</p>
<p>Let&#8217;s start off with the basic imports:</p>
<pre class="brush: python; title: ; notranslate">
import sys

import PyQt4.QtCore as QtCore

import PyKDE4.kdecore as kdecore
import PyKDE4.kdeui as kdeui
from PyKDE4.kio import KIO
from PyKDE4.nepomuk import Nepomuk
from PyKDE4.soprano import Soprano
</pre>
<p>Then let&#8217;s create a simple class that wil be used for the rest of this exercise:</p>
<pre class="brush: python; title: ; notranslate">
class NepomukTagQueryExample(QtCore.QObject):

    def __init__(self, parent=None):

        super(NepomukTagQueryExample, self).__init__(parent)
</pre>
<p>__init__ is just used to construct the instance, nothing more. The bulk of the work is in the query_tag() function, which we&#8217;ll take a look at in parts.</p>
<pre class="brush: python; title: ; notranslate">
    def query_tag(self, tag):

        &quot;&quot;&quot;Query for a specific tag.&quot;&quot;&quot;

        tag = Nepomuk.Tag(tag)
</pre>
<p>First of all we convert the tag we want to query into a proper Nepomuk.Tag() instance. Of course we should use an already existing tag: even if Nepomuk.Tag() automatically creates new tags, it makes little sense to query for a newly created tag, doesn&#8217;t it?</p>
<p>For our job, we need to use <i>properties</i>&nbsp;which define the terms of our query. As we&#8217;re looking for tags, we&#8217;ll use Soprano.Vocabulary.NAO.hasTag():</p>
<pre class="brush: python; title: ; notranslate">
        soprano_term_uri = Soprano.Vocabulary.NAO.hasTag()
        nepomuk_property = Nepomuk.Types.Property(soprano_term_uri)
</pre>
<p>The first call generates an URI pointing to a specific RDF resource for this specific term, which is then wrapped as a Nepomuk.Types.Property in the second call. While the C++ API docs don&#8217;t show this, I found it to be necessary, or the Python interpreter would raise a TypeError. Notice that this is not the only term we can use: aside for tags, there are a lot of other URIs we can use for querying, <a href="http://api.kde.org/kdesupport-api/kdesupport-apidocs/soprano/html/namespaceSoprano_1_1Vocabulary_1_1NAO.html">listed in the Soprano API docs</a>.</p>
<p>Once we have our property set up, it&#8217;s time to define which kind of query we&#8217;re going to use. In this case, since we want to check for the presence of tags, we use a Nepomuk.Query.ComparisonTerm, which is a query term used to match values of specific properties (in our case, tags):</p>
<pre class="brush: python; title: ; notranslate">
        comparison_term = Nepomuk.Query.ComparisonTerm(nepomuk_property,
                Nepomuk.Query.ResourceTerm(tag))
</pre>
<p>Our tag is wrapped in a ResourceTerm, which is used exactly for the purpose. Now we make the proper query: in this specific case, we want to look up <i>files </i>tagged, so we use a FileQuery. We could also get other items, such as mails (in Akonadi): in that case we could use a a Nepomuk.Query.Query():</p>
<pre class="brush: python; title: ; notranslate">
        query = Nepomuk.Query.FileQuery(comparison_term)
</pre>
<p>Lastly, we want to get some <i>results</i> out of this query. There are different methods, but for this tutorial we&#8217;ll use the tried-and-tested KIO technology:</p>
<pre class="brush: python; title: ; notranslate">
        search_url = query.toSearchUrl()
        search_job = KIO.listDir(kdecore.KUrl(search_url))
        search_job.entries.connect(self.search_slot)
        search_job.result.connect(search_job.entries.disconnect)
</pre>
<p>First we convert the query to a nepomuksearch:// url, which then we pass to KIO.listDir, to list the entries. Unlike <a href="http://www.dennogumi.org/2011/01/pykde4-retrieve-data-using-kio">my previous post on KIO</a>, this job emits entries() every time one is found, so we connect the signal to our search_slot method. We also connect the job&#8217;s result() signal in a way that it will disconnect the job once it&#8217;s over.</p>
<p>Finally, let&#8217;s take a look at the search_slot function:</p>
<pre class="brush: python; title: ; notranslate">
    def search_slot(self, job, data):

        # We may get invalid entries, so skip those
        if not data:
            return

        for item in data:
            print item.stringValue(KIO.UDSEntry.UDS_DISPLAY_NAME)
</pre>
<p>Entries are emitted as <a href="http://api.kde.org/4.x-api/kdelibs-apidocs/kio/html/classKIO_1_1UDSEntry.html">UDSEntries</a>: to get something at least understandable, we turn them into the file name, which is obtained by the stringValue() call using KIO.UDSEntry.UDS_DISPLAY_NAME.</p>
<p>That&#8217;s it. As you can see, it was pretty easy. Of course there&#8217;s more than that. For further reading, take a look at <a href="http://api.kde.org/4.x-api/kdelibs-apidocs/nepomuk/html/namespaceNepomuk_1_1Query.html">Nepomuk&#8217;s Query API docs</a>, and <a href="http://api.kde.org/4.x-api/kdelibs-apidocs/nepomuk/html/examples.html#examples_query">Query Examples</a>. Bear in mind however that to the best of my knowledge, the &#8220;fancy operators&#8221; mentioned there will not work with Python.</p>
<p>Happy Nepomuk querying!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.dennogumi.org/2011/06/pykde4-queries-with-nepomuk/feed</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>PyKDE4: Retrieve data using KIO</title>
		<link>http://www.dennogumi.org/2011/01/pykde4-retrieve-data-using-kio</link>
		<comments>http://www.dennogumi.org/2011/01/pykde4-retrieve-data-using-kio#comments</comments>
		<pubDate>Sat, 01 Jan 2011 21:09:26 +0000</pubDate>
		<dc:creator>Einar</dc:creator>
				<category><![CDATA[KDE]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[pykde]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://www.dennogumi.org/?p=810</guid>
		<description><![CDATA[One of the greatest strengths of KDE is undoubtedly the asynchronous and network-transparent I/O access, employed by the so-called &#8220;I/O&#8221; slaves, part of the KIO class. If you are developing an application that requires file or network access, those classes &#8230; <a href="http://www.dennogumi.org/2011/01/pykde4-retrieve-data-using-kio">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>One of the greatest strengths of KDE is undoubtedly the asynchronous and network-transparent I/O access, employed by the so-called &#8220;I/O&#8221; slaves, part of the KIO class. If you are developing an application that requires file or network access, those classes make things incredibly simple to do, and they don&#8217;t freeze your GUI when you are in the middle of a process.
<div></div>
<div>In this post I&#8217;ll show how to use KIO to retrieve files from network resources using PyKDE4. The whole example is also available <a href="http://websvn.kde.org/trunk/KDE/kdeexamples/bindings/python/kio/">in the kdeexamples module</a>.</p>
<p>Our first step is to create a simple UI to show how KIO works. It will be a text edit along with two buttons to retrieve and clear items. Here&#8217;s how it looks in Designer (the ui file and its compiled Python version are available at the above link):</p>
<div style="text-align: center;"><img width="400" height="300" title="Example form" src="http://www.dennogumi.org/wp-content/uploads/2011/01/kio_tutorial.png?cda6c1" alt="Image of the example form"/></div>
<p>Once this is done, we turn our attention to code. We start customary imports:</p>
<pre class="brush: python; title: ; notranslate">
#!/usr/bin/env python
import sys
import PyQt4.QtCore as QtCore
import PyQt4.QtGui as QtGui
import PyKDE4.kdecore as kdecore
import PyKDE4.kdeui as kdeui
from PyKDE4.kio import KIO</pre>
<p>These will provide for everything we need. Then we set up our widget:</p>
<pre class="brush: python; title: ; notranslate">

from ui_textbrowser import Ui_Form

class TextArea(QtGui.QWidget, Ui_Form):

    &quot;&quot;&quot;Example class used to show how KIO works.&quot;&quot;&quot;

    def __init__(self, parent=None):

        super(TextArea, self).__init__(parent)
        self.setupUi(self)

        self.downloadButton.clicked.connect(self.start_download)
        self.clearButton.clicked.connect(self.textWidget.clear)
</pre>
<p>Nothing strange in the initializer here. We simply make two connections, one to the clear() slot of the clear button, and the other to start the KIO process, that is the retrieval of the index from www.kde.org. Let&#8217;s take a look at the start_download slot:</p>
<pre class="brush: python; title: ; notranslate">
    def start_download(self):
        kdeui.KMessageBox.information(self.parent(),
                                      &quot;Now data will be retrieved from &quot;
                                      &quot;www.kde.org using KIO&quot;)

        # KIO wants KUrls
        data_url = kdecore.KUrl(&quot;http://www.kde.org&quot;)
        retrieve_job = KIO.storedGet(data_url, KIO.NoReload, KIO.HideProgressInfo)
        retrieve_job.result.connect(self.handle_download)
</pre>
<p>What do we do here? We show a KMessageBox, just for informational purposes. Once this is done, we prepare the actual KIO &nbsp;job. KIO wants KUrls so we first of all wrap the URL we want to download from in that. Then we create the actual job: in this case it&#8217;s KIO.storedGet, that is we retrieve the data in full from our URL and store it in a QByteArray. This is a common use case, but you have to keep in mind that for large files this may be impractical. In such a case, we would be better off using KIO.get followed by a connection to the &#8220;data&#8221; signal, to get the data in chunks.</p>
<p>A KIO job can have many flags: here we set to remove the progress information, so that you won&#8217;t get a notification in the Plasma notifier. For small operations, this should be always present. For longer downloads, it&#8217;s likely not a good idea. More information are available in the <a href="http://api.kde.org/4.5-api/kdelibs-apidocs/kio/html/namespaceKIO.html">KIO namespace page (C++ version).</a></p>
<p>As a last step, we connect the result signal (emitted when the job is complete) to a slot to handle the download. This is what makes KIO useful, because it&#8217;s asynchronous, so you can perform long downloads without blocking the user interface of your program</p>
<p>Lastly, we see the &#8220;handle_download&#8221; slot:</p>
<pre class="brush: python; title: ; notranslate">

    def handle_download(self, job):

        # Bail out in case of errors
        if job.error():
            return

        print &quot;This slot has been called. The job has finished its operation.&quot;

        data = job.data()
        self.textWidget.setPlainText(QtCore.QString(data))
</pre>
<p>This slot&#8217;s signature include a KJob instance, that is what we&#8217;ll use to get the data. In fact, using the data() function we can obtain the QByteArray containing what we have retrieved. Then, in this case we simply use setPlainText to put the downloaded data into the text edit.</p>
<p>What if something goes wrong? We can check for errors if job.error() returns True: in that case we can perform recovery, or simply tell our user that something went wrong. Especially with networked resources, this should always be present in your code.</p>
<p>So that&#8217;s all for now. As you can see, it was pretty simple, and also very effective.</p></div>
]]></content:encoded>
			<wfw:commentRss>http://www.dennogumi.org/2011/01/pykde4-retrieve-data-using-kio/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Learning by example</title>
		<link>http://www.dennogumi.org/2010/01/learning-by-example</link>
		<comments>http://www.dennogumi.org/2010/01/learning-by-example#comments</comments>
		<pubDate>Wed, 13 Jan 2010 21:37:38 +0000</pubDate>
		<dc:creator>Einar</dc:creator>
				<category><![CDATA[KDE]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[pykde]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://www.dennogumi.org/?p=744</guid>
		<description><![CDATA[With my brand-new SVN account, I just committed some code to kdeexamples, KDE&#8217;s example code module. In particular, I committed a simple example which shows how to use KConfigXT via PyKDE4, a simplified version of what I wrote about here. &#8230; <a href="http://www.dennogumi.org/2010/01/learning-by-example">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>With my brand-new SVN account, <a href="http://lists.kde.org/?l=kde-commits&#038;m=126342017923323&#038;w=2" title="SVN commit">I just committed some code</a> to kdeexamples, KDE&#8217;s example code module. In particular, I  committed a simple example which shows how to use KConfigXT via PyKDE4, a simplified version of <a href="http://www.dennogumi.org/2009/10/howto-kconfigxt-with-pykde4" title="HOWTO: KConfigXT with PyKDE4">what I wrote about here</a>.</p>
<p>As most of KDE is C++, and the Python API docs are translated directly from the C++ API docs, it is essential to have good examples to help newcomers learn faster.  There are some PyKDE4 examples in the kdebindings module already, but I put mine in kdeexamples for a number of reasons:</p>
<ul>
<li><em>Clear purpose</em>: kdeexamples is meant exactly for this &#8211; example code;</li>
<li><em>Visibility:</em> A central place to find KDE examples even for bindings is optimal, makes easier to find what one is looking for.</li>
</ul>
<p>Visibility is also important as currently the examples are rather buried inside kdebindings, and as far as I know they aren&#8217;t included in the packages of some distributions (at least not openSUSE; YMMV). </p>
<p>I decided to take this route because PyKDE4 is basically the job of one person (Simon Edwards): he does already a great job, but the work is too much for a single person to handle. And due to shortage of human resources, PyKDE4 lacks examples and documentation, and thus it&#8217;s not always easy to understand how to use the C++ API in Python. Writing snippets of working code, with extensive comments, is a step in the good direction. And also an opportunity to contribute back to KDE after all these years!</p>
<p>For now there&#8217;s just KConfigXT,  but I plan on tackling KIO next, as soon as I have time. Of course, help is welcome!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.dennogumi.org/2010/01/learning-by-example/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Danbooru Client &#8211; a client for Danbooru based sites</title>
		<link>http://www.dennogumi.org/2009/10/danbooru-client-a-client-for-danbooru-based-sites</link>
		<comments>http://www.dennogumi.org/2009/10/danbooru-client-a-client-for-danbooru-based-sites#comments</comments>
		<pubDate>Sun, 25 Oct 2009 20:16:50 +0000</pubDate>
		<dc:creator>Einar</dc:creator>
				<category><![CDATA[Anime]]></category>
		<category><![CDATA[KDE]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[danbooru]]></category>
		<category><![CDATA[pykde]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://www.dennogumi.org/2009/10/danbooru-client-a-client-for-danbooru-based-sites</guid>
		<description><![CDATA[A while ago I presented &#8220;danbooru2nepomuk&#8221;, a small program to tag images coming from Danbooru-based image boards. Today I want to present the evolution of that program, that is a PyKDE4 client for those boards. Danbooru? Is it something you &#8230; <a href="http://www.dennogumi.org/2009/10/danbooru-client-a-client-for-danbooru-based-sites">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>A while ago I presented <a href="http://www.dennogumi.org/2009/10/danbooru2nepomuk-a-nepomuk-tagger-for-danbooru-images" title="danbooru2nepomuk entry">&#8220;danbooru2nepomuk&#8221;</a>, a small program to tag images coming from <a href="http://en.wikipedia.org/wiki/Imageboard#Danbooru-style_boards" title="Wikipedia link">Danbooru-based image boards</a>. Today I want to present the evolution of that program, that is a PyKDE4 client for those boards.</p>
<p><span id="more-708"></span></p>
<h1>Danbooru? Is it something you eat?</h1>
<p>Well, aside from the Wikipedia link above, I think a small introduction is in order, at least for the readers coming from PlanetKDE. Danbooru is a kind of image board which structures its data semantically, by having tags attached to images (along with other things, such as favorites, rating, etc.). It can be browsed normally (newest posts, etc.) or by using tags and other properties. Some boards are quite popular in the anime-viewing community. The neat thing about Danbooru (which is by itself a Ruby on Rails application) is the fact that it can provide a REST and POST API to access data. So. it&#8217;s technically possible to access such boards programmatically: the API permits not only retrieving posts, but also upload, tag, and perform other operations.</p>
<p>The API could be technically used also for client applications, in order to free the user from using a browser. That is what Danbooru Client is aiming to do.</p>
<h1>Introducing Danbooru Client</h1>
<p>Danbooru Client fits exactly these needs by providing a GUI to (part of) the Danbooru API.</p>
<p><strong>Features:</strong></p>
<ul>
<li> Connect to any Danbooru board (three predefined)</li>
<li>Download up to 100 images with selectable tags;</li>
<li>Download or view images with the KDE preferred image viewer;</li>
<li>Tag semantically the images using Nepomuk.</li>
</ul>
<p><strong>Requirements:</strong></p>
<ul>
<li>PyQt (at least version 4.5)</li>
<li>PyKDE4 (tested with PyKDE 4.3 only)</li>
<li>(optional) Nepomuk</li>
<li>Python (at least version 2.5)</li>
</ul>
<p><strong>Screenshots</strong></p>
<p align="center"><a href="http://www.dennogumi.org/wp-content/uploads/2009/10/danb_client1.png?cda6c1"><img src="http://www.dennogumi.org/wp-content/uploads/2009/10/danb_client1_resized.png?cda6c1" /></a> <a href="http://www.dennogumi.org/wp-content/uploads/2009/10/danb_client2.png?cda6c1"><img src="http://www.dennogumi.org/wp-content/uploads/2009/10/danb_client2_resized.png?cda6c1" /></a></p>
<p align="center">(click to enlarge)</p>
<h2>Download &amp; Installation</h2>
<p>You can obtain Danbooru Client <a href="http://www.kde-apps.org/content/show.php/Danbooru+Client?content=114343">from kde-apps.org</a>. For the bleeding edge people (but are there such users for such an application?) there is a <a href="http://gitorious.org/danbooru-client/danbooru-client">git repository set up at Gitorious</a>. Once downloaded, you need to use CMake to install the files. Unfortunately due to the way CMake is set up, you&#8217;ll need the KDE development headers and a working C++ compiler, even though you won&#8217;t need them for the installation.</p>
<p>The installation process is very straightforward:</p>
<p><pre class="brush: bash; title: ; notranslate">cd /path/to/source
mkdir build; cd build
cmake -DCMAKE_INSTALL_PREFIX=`kde4-config --prefix` ../
make # This just byte-compiles Python files
sudo make install</pre>
</p>
<p>Then, just launch &#8220;danbooru_client&#8221;.</p>
<h2>Known limitations</h2>
<p>There are plenty for now, it&#8217;s just version 0.1:</p>
<ul>
<li>Zero documentation (although it&#8217;s kind of straightforward to use)</li>
<li>Empty cells are created when a row is not filled with images</li>
<li>No support for multi-download</li>
<li>Untested login/password access</li>
<li>The interface may be horrid</li>
<li>Danbooru does not support rating filtering via API, so it&#8217;s not currently possible to do so</li>
</ul>
<p>The client is licensed under the GPL v2 or later. The artwork for the splash screen is also under the GPL and was made by <a href="http://www.melissaadkins.com">Melissa Adkins</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.dennogumi.org/2009/10/danbooru-client-a-client-for-danbooru-based-sites/feed</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
		<item>
		<title>HOWTO: KConfigXT with PyKDE4</title>
		<link>http://www.dennogumi.org/2009/10/howto-kconfigxt-with-pykde4</link>
		<comments>http://www.dennogumi.org/2009/10/howto-kconfigxt-with-pykde4#comments</comments>
		<pubDate>Mon, 19 Oct 2009 21:43:10 +0000</pubDate>
		<dc:creator>Einar</dc:creator>
				<category><![CDATA[KDE]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[pykde]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://www.dennogumi.org/?p=687</guid>
		<description><![CDATA[If you read around the KDE Techbase, or if you develop KDE applications, you may have heard about KDE&#8217;s KConfigXT. This is an extension of KDE&#8217;s KConfig, and can be used to generate nice configure dialogs with multiple pages with &#8230; <a href="http://www.dennogumi.org/2009/10/howto-kconfigxt-with-pykde4">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>If you read around the <a href="http://techbase.kde.org">KDE Techbase</a>, or if you develop KDE applications, you may have heard about KDE&#8217;s <a href="http://techbase.kde.org/Development/Tutorials/Using_KConfig_XT">KConfigXT</a>. This is an extension of KDE&#8217;s KConfig, and can be used to generate nice configure dialogs with multiple pages with minimal effort, also taking care of saving and applying settings. In short, something really neat! But there are problems when using it with interpreted language bindings (such as PyKDE, which is the one I use):</p>
<ul>
<li>KConfigXT requires an XML file and an INI-like file to be compiled by kconfig_compiler in order to produce C++ files</li>
<li>There is no such a tool (at least to my knowledge) that does the same job for bindings</li>
</ul>
<p>So what to do? Either give up on the niceness of KConfigXT, or work around the issue. I chose the latter. </p>
<p><span id="more-687"></span></p>
<h2>Bypassing the kconfig_compiler limitation</h2>
<p>What kconfig_compiler does is basically generate the KConfigSkeleton sublcass needed for KConfigXT. So, we can create our own subclass by hand: a little more work is involved but nothing too hard. The following snippets, taken from a GPL application I&#8217;m working on, will demonstrate how to do it. </p>
<pre class="brush: python; title: ; notranslate">
from PyQt4.QtCore import *
from PyQt4.QtGui import *
from PyKDE4.kdeui import *

#UI stuff - see later
from ui_generalpage import Ui_GeneralPage

class Preferences(KConfigSkeleton):

    &quot;&quot;&quot;Class to handle preferences.&quot;&quot;&quot;

    def __init__(self, *args):
        super(Preferences, self).__init__(self, *args)
        self.setCurrentGroup(&quot;General&quot;)
        self._danbooru_boards_list = QStringList()
        self._danbooru_boards = self.addItemStringList(&quot;danbooruUrls&quot;,
                                                       self._danbooru_boards_list,
                                                       QStringList())
</pre>
<p>Here we set up a KConfigSKeleton subclass. The first thing we set up after that is the config group we want to use: we can have several, for example &#8220;General&#8221;, &#8220;Services&#8221;, and so on. Of course an empty group makes nothing, so we populate it, in this case with a QStringList configuration item (<a href="http://api.kde.org/4.3-api/kdelibs-apidocs/kdecore/html/classKCoreConfigSkeleton.html">see the API docs</a> (KCoreConfigSkeleton, but KConfigSkeleton is a subclass of that) for more types you can use). You&#8217;ll notice that we assign an empty QStringList to a variable, which is then used in the addItemStringList call later. That&#8217;s because KConfigSkeleton (in C++) wants a pointer to the type of content, and since in Python we don&#8217;t have pointers, we pass a reference (and by binding it to our class instance, we make sure it won&#8217;t be garbage-collected). </p>
<p>The addItemStringList (and other addItem*) methods use three parameters: a string with the name of the option (remember this!), the reference to the item, and a default value (in this case an empty QStringList).. Once we&#8217;ve set the options, we call readConfig() in the initializer to make sure the values are read from the config (or default values created).</p>
<p>I set all the attributes as &#8220;hidden&#8221; to prevent direct manipulation. To access them, I set up properties (following the example of minirok, another PyKDE4 application). </p>
<pre class="brush: python; title: ; notranslate">
    @property
    def boards_list(self):
        return self._danbooru_boards.value()
</pre>
<p>As you can see, the value of the configuration items is accessed via the value() function. Once tihs is done, we&#8217;re done with regards to the KConfigSkeleton part.</p>
<h2>KConfigDialog</h2>
<p>Of course now we want to create the config dialog. We do so by subclassing KConfigDialog. First, though, we must create the page contents. We do so in Qt Designer. We first create a widget, and then we place our configuration widgets on it. It is <strong>essential</strong> that the widget that will store our configuration details have the name <em>kcfg_CONFIGOPTION</em>, where CONFIGOPTION is the name you specified as a string in the KConfigSkeleton initializer. Once done, we save the ui file, compile with pykdeuic4, we set it in the imports of our preferences file and we&#8217;re good to go. </p>
<p>The following is an example of a general configuration page widget (the UI_* is the pykdeuic4 generated file):</p>
<pre class="brush: python; title: ; notranslate">
class GeneralPage(QWidget, Ui_GeneralPage):

    def __init__(self, parent=None, preferences=None):
        super(GeneralPage, self).__init__(parent)
        self.setupUi(self)

        self.kcfg_danbooruUrls.insertStringList(preferences.boards_list)
</pre>
<p>As you can see, we pass the preferences instance in the initializer, so we can populate the widgets (which are indeed named kcfg_danbooruUrls, just like the config option I set earlier) . Of course you can connect signals and whatnot to slots in case you want to do something with your widgets. I didn&#8217;t have the need, so no need to. </p>
<p>And once we have this set up, we can finally create the KConfigDialog! </p>
<pre class="brush: python; title: ; notranslate">
class PreferencesDialog(KConfigDialog):

    def __init__(self, parent=None, name=None, preferences=None):
        super(PreferencesDialog, self).__init__(parent, name, preferences)

        self.setButtons(KDialog.ButtonCode(KDialog.Ok |KDialog.Apply |
                                            KDialog.Cancel))

        self.general_page = GeneralPage(self, preferences)
        self.general_page_item = self.addPage(self.general_page, 'General')
</pre>
<p>In the initializer, we pass the preferences instance, the name (used later to determine if a page is already open, since KConfigDialog is non-modal), and of course, the parent widget. We then set the buttons (using bitwise ORs) we want to show. Finally, we instantiate our page widget and add it to the dialog, specifying a name that will appear on the side. Using the setIcon method you can also set an icon for your page. In case you want to perform checks and other things, reimplement slotButtonClicked in your subclass with (self, button) as parameters. But dont&#8217; forget to call the original KConfigDialog.slotButtonClicked(button) in that case.</p>
<h2>Wrapping it up: calling KConfigDialog</h2>
<p>Finally, how to call your dialog? First of all, you need to instantiate your preferences object, for example in your main window application code:</p>
<pre class="brush: python; title: ; notranslate">self.preferences=preferences.Preferences()</pre>
<p>Then, in your code, you do something like this:</p>
<pre class="brush: python; title: ; notranslate">
if KConfigDialog.showDialog(&quot;Preferences dialog&quot;):
    return
else:
    dialog = preferences.PreferencesDialog(self, &quot;Preferences dialog&quot;,
                                           self.preferences)
    dialog.show()
</pre>
<p>The first if ensures that if there is already one dialog open, it won&#8217;t open another. If that&#8217;s not the case, we instantiate the dialog, passing it the name (which must be the same as the if above), the parent, and the preferences instance. </p>
<p>Voila&#8217;. In the end, you&#8217;ll get something like this (slightly different):</p>
<p align="center"><img src="http://www.dennogumi.org/wp-content/uploads/2009/10/kconfigdialog_small.jpg?cda6c1" title="Example KConfigDialog" alt="Image of the example KConfigDialog" /></p>
<p>I know my own UI sucks here, but it&#8217;s something I&#8217;m still experimenting&#8230;</p>
<p>For this tutorial, thanks go to Pino &#8220;pinotree&#8221; Toscano, who pointed me to the &#8220;minirok&#8221; project, which makes use of KConfigXT, and Adeodato Simò, the author of minirok.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.dennogumi.org/2009/10/howto-kconfigxt-with-pykde4/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
	</channel>
</rss>

<!-- Performance optimized by W3 Total Cache. Learn more: http://www.w3-edge.com/wordpress-plugins/

Minified using xcache (Feed is rejected)
Page Caching using xcache
Database Caching using xcache
Object Caching 519/542 objects using xcache

Served from: www.dennogumi.org @ 2012-02-05 06:08:10 -->
