Fün Fin Fir

kindle glitch’d jpg’d

kindle-glitchd-jpgd

Using standard icons in Qt Designer and Qt Creator

With Qt 4.8 it has become fairly easy to use icons from the standard icon theme on buttons. Simply use the label from the freedesktop.org icon naming specification as theme name.

Using standard icons in Qt Designer

Fun fact: This does not work on Windows!

Get Stoked on Web Typography


Eine Präsentation von @samanthatoy. Großartig!

Konsolenapplikationen mit urwid Teil 1

Will man mit Python eine Anwendung entwickelt, welche über ein Text User Interface (TUI) verfügt, so hat man im Großen und Ganzen zwei vernünftige Möglichkeiten:

curses

Der große Vorteil an curses ist, dass es mit Python unter Linux mitgeliefert wird. Ansonsten ist es sehr sehr Umständlich mit dieser Bibliothek zu arbeiten, da quasi nichts an Widgets mitgeliefert wird. Standardmäßig gibt es quasi nur ein Eingabefeld für Text und die Möglichkeit gezeichnete Boxen zu umrahmen.

Hat man vor ein Projekt mit einer gewissen Größe im Frontend umzusetzen, sollte man sich im Klaren sein, dass man mit curses ein ziemlich großes Stück Arbeit vor sich hat. Wer sich dennoch interessiert, der kann sich in diesem Wikibook ansehen, wie man mit curses umgeht. Wenigstens ist der Code recht übersichtlich und gut lesbar.

urwid

Urwid selbst basiert auf curses und ist eine Bibliothek zum einfacheren und schnelleren Erstellen von TUIs. Es existiert ein Basissatz von oft benötigten Widgets (Buttons, Inputs, Checkboxen…) und einfache Möglichkeiten diese zu platzieren. Zusätzlich kann man auch anhand des Basiswidgets eigene Widgets erstellen. Leider gibt es keine oder nur wenige vernünftige Tutorials zu urwid und die Dokumentation ist auch etwas dürftig, womit man schnell auf der Strecke bleiben kann, wenn man an einer der vielen Eigenheiten der Bibliothek hängen bleibt.

(urwid ist bei Archlinux sowie Ubuntu unter dem Namen »python-urwid« in der Paketverwaltung zu finden)

Erste Schritte

Für jede gewünschte Aktion stellt urwid eine Methode bereit, die man ausführen muss. Nach dem Import erstellen wir also ein Textwidget. Danach wird es in einen Filler gesteckt, der den Platz oberhalb und unterhalb des Widgets ausfüllt, und somit eine eindeutige Positionierung des Widgets ermöglicht.

Mit urwid erstellte Programme laufen, wie von vielen anderen Nutzeroberflächen schon bekannt, in einer MainLoop. Diese wird mit unserem Widget befüllt und danach gestartet. Unser erstes Programm ist fertig!

Wem beim Abschreiben des ersten Codes Fehler unterlaufen sind, der wird einen weiteren großen Nachteil an urwid erkannt haben: Die Fehlermeldungen sind kaum nützlich bis völlig unbrauchbar.

import urwid

text = urwid.Text("Hello World")
text = urwid.Filler(text)
loop = urwid.MainLoop(text)
loop.run()

Eingaben behandeln

Sämtliche Eingaben kann man abfangen, indem der MainLoop das Argument »unhandled_input=eine_funktion« übergibt. Somit wird der Funktion eine_funktion die gedrückte Taste übergeben. Urwid gibt Sondertasten wie Enter brauchbare und lesbare Aliase, was den Umgang erheblich erleichtert.

import sys
import urwid

def handle_input(input):
    if input == "esc":
        sys.exit(0)
    pass

text = urwid.Text("Hello World")
text = urwid.Filler(text)
loop = urwid.MainLoop(text, unhandled_input=handle_input)
loop.run()

Es kommt Farbe ins Spiel

Farben werden über eine Palette realisiert, in der für jeden Farbsatz jeweils eine Vordergrundfarbe und eine Hintergrundfarbe definiert werden muss. Mittels der Methode AttrWrap() weist man einem Widget eine Farbe zu.

palette = [('p1', 'light green', 'black'),
           ('p2', 'white', 'dark red')]

text = urwid.Text("Hello World")
text = urwid.AttrWrap(text, "p1")
text = urwid.Filler(text)
loop = urwid.MainLoop(text, palette)
loop.run()

Komplexere Layouts

Um mehr Information auf den Bildschirm zu bringen ist das Filler-Widget vielleicht etwas zu starr und unpraktisch. Hierfür bietet sich eher das Frame-Widget an. Es besteht aus einem Header, einem Body und einem Footer. In unserem Beispiel möchten wir einen starren Header und Footer haben, der Bodybereich soll jedoch scrollbar sein.

Dazu erstellen wir zunächst ein wenig Dummyinhalt. Dieser wird vom Widget Divider() voneinander getrennt. Der Inhalt für den Body wird dann in einer Liste zusammengefasst:

t0 = urwid.Divider()
t1 = urwid.AttrWrap(urwid.Text("Hello World"), "p1")
t2 = urwid.Divider("+")
t3 = urwid.AttrWrap(urwid.Text('''Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas porta porta nunc eget dignissim. Morbi ante nibh, varius vitae rhoncus id, fermentum in nisl. Curabitur metus diam, pharetra vel varius non, vulputate eget lectus. Sed et nisl sed nisi sollicitudin egestas. Curabitur in ligula elit. Duis tristique porttitor porttitor. Cras rutrum lectus quis sem rutrum vulputate suscipit orci bibendum. Nam consectetur turpis purus, at suscipit tellus. Aenean diam lorem, tristique vel consequat in, rhoncus ac felis. Nam scelerisque justo nunc.

Suspendisse ut dolor vehicula felis gravida egestas. Nullam porttitor pulvinar mauris id tempor. Ut eu risus eu tellus laoreet pulvinar vitae ac nisl. Fusce bibendum consequat mauris, a lacinia turpis hendrerit eu. Nunc a arcu eget ante cursus dignissim vestibulum in magna. Nunc tempor accumsan augue eget cursus. Nullam interdum arcu eget metus placerat tempus. Morbi id lacus et diam tempus auctor. Morbi vehicula mi id mauris faucibus vitae pharetra purus rhoncus. Aliquam erat volutpat. Vestibulum nisi dolor, tincidunt quis interdum vitae, mattis quis nunc. Maecenas velit tortor, luctus non aliquet vel, euismod non arcu. Nunc ante lorem, bibendum eget pretium id, accumsan id odio. Aliquam odio lectus, porttitor dignissim egestas eget, vestibulum ut sapien. Pellentesque neque dolor, ultrices vel eleifend in, tincidunt vel libero.

Aliquam pulvinar est sit amet ligula viverra eleifend. Nullam porttitor sem sit amet massa egestas at ultricies lorem vestibulum. Donec eu libero dui. Sed in fringilla arcu. Nunc porta tincidunt lorem, eu dignissim lorem tempus ut. Integer faucibus magna non libero varius elementum blandit dolor lobortis. Maecenas a pharetra neque. Sed massa augue, placerat a varius eget, lobortis in nunc. Praesent non leo neque, non imperdiet felis. Aenean sed orci quis justo rutrum ornare vel nec erat. Vestibulum posuere elementum justo, in cursus neque varius a. In vel blandit nunc. Mauris blandit ligula eget felis lacinia at faucibus sem adipiscing. Sed malesuada lorem eget neque ornare eget condimentum nunc scelerisque.'''), "p1")
t4 = urwid.Divider("-")
t5 = urwid.AttrWrap(urwid.Text("Hello Arch!"), "p1")
t6 = urwid.Divider("8")

header = urwid.AttrWrap(urwid.Text("Dies ist der Header!"), "p2")
footer = urwid.AttrWrap(urwid.Text("Under hier ist der Footer!"), "p2")

content = [t0, t1, t2, t3, t4, t5, t6]

Um den Body scrollbar zu machen, wird der Inhalt zuerst in einen SimpleListWalker gesteckt, danach in eine ListBox. Dies hat das Ergebnis, dass der Fokus Widget für Widget verschoben werden kann. Danach wird ein Framewidget erstellt, welches standardmäßig den Body als erstes Widget annimmt. Danach werden Header und Footer übergeben und das FrameWidget in die MainLoop gesteckt.

content = urwid.ListBox(urwid.SimpleListWalker(content))

main_frame = urwid.Frame(content)

main_frame.set_header(header)
main_frame.set_footer(footer)

loop = urwid.MainLoop(main_frame, palette)
loop.run()

Urwid SimpleListWalker

Weiter geht es…

…im nächsten Teil mit Formularen, wo urwid seine Stärken ausspielen kann. Kommentare oder Anregungen? Ab in die Kommentare!

Pino: Release early, release often!

Mit dem Ende des Augusts diesen Jahres konnten wir uns nicht nur vom Sommer verabschieden, sondern auch von Basic Auth in Twitter, einer Methode um sich als Nutzer zu identifizieren.

Basic Auth wurde durch OAuth abgelöst, warum genau ist hier nicht weiter interessant, interessant ist nämlich was mit der Software geschieht, die bis zum ersten September nicht auf OAuth aktualisiert wurde: sie funktioniert einfach nicht mehr.

So geschehen mit dem schlanken und grundsätzlich auch einigermaßen großartigen Twitter-Client Pino, der im AUR zu Hause ist und bereits eine langsame aber stetige Entwicklung hinter sich hat. Die Version 0.3 (mit OAuth-Unterstützung!) ist seit einiger Zeit angekündigt, es gibt auch schon einige Screenshots, aber greifbar ist noch nichts. Dumm nur, dass der erste September nun schon vorbei ist, und alle Pino-Nutzer dumm dastehen.

Dazu fiel mir ein Programmierparadigma wieder ein, nämlich »release early, release 0ften«.  Wenn die aktuellste Version von Pino verfügbar wäre, könnte man entweder sehen, dass sie bereits mit OAuth schön funktioniert und vielleicht noch ein paar Fehler drin sind – oder dass von hinten bis vorne nichts klappt. Auf jeden Fall könnte die Intelligenz der Masse benutzt werden, um das Problem zu lösen. Hier bleibt nichts anderes übrig als zu warten was als nächstes passiert.

Update: Wenn man sich über http://www.supertweet.net/ anmeldet und deren Seite als Proxy in Pino angibt, kann man das Problem bis zur Aktualisierung umgehen. Ist zwar nicht schön, aber klappt einwandfrei.

Tiny Tiny RSS in Thunderbird

Ganz kurz und ein bisschen Cpt. Obvious:

Tiny Tiny RSS lässt sich genauso wie Google Wave in Thunderbird einbauen, man muss folgenden Code in der Error-Konsole (»Tools/Error Console«) ausführen, natürlich noch die eigene URL einfügen:

Components.classes['@mozilla.org/appshell/window-mediator;1'].getService(Components.interfaces.nsIWindowMediator).getMostRecentWindow("mail:3pane").document.getElementById("tabmail").openTab("contentTab", {contentPage: "http://example.com"});

via fixmbr

XMonad, Slim und Networkmanager

Auf meinem neuen Notebook läuft XMonad und als Loginmanager verwende ich Slim.
Für mein Netzwerk wollte ich den Networkmanager verwenden. Das nm-applet benötigt allerdings den gnome-keyring, welcher mit meiner Konfiguration nicht so richtig will, denn der Networkmanager speicher keine Passwörter. Nach ein paar Tagen mit der Behelfslösung wicd habe ich nochmal gesucht und endlich hier: http://bbs.archlinux.org/viewtopic.php?pid=736320 eine Lösung gefunden:

Changing /usr/share/dbus-1/services/org.gnome.keyring.service to:

[D-BUS Service]
Name=org.freedesktop.secrets

Fixed it for me

Vielleicht hilft es ja jemandem!