Shellscripting met KDE-dialoogvensters

Auteur: Brad Hards
Vertaling: Tom Verbreyt
Herziening 0.1
Copyright © 2004 KDE-nl team

Dit document toont aan de hand van voorbeelden hoe je in shell-scripts gebruik kan maken van KDE-dialoogvensters, dankzij kdialog. De vertaler maakte gebruik van Qt 3.2 en KDE 3.2.

Inhoudsoverzicht

  1. Inleiding en bereik van dit document
  2. kdialog gebruiken
  3. Dialoogvenstertypes
  4. Licenties en verdiensten

1 Inleiding en bereik van dit document

Een veelgehoorde misvatting over KDE is dat het een uitsluitend grafische omgeving zou zijn. Ofschoon KDE natuurlijk een schitterende desktop-omgeving biedt, wordt ook de Unix-erfenis van commandoregels en scripts erg goed ondersteund in KDE. Concreet betekent dat dat KDE-toepassingen vanop de commandoregel bediend kunnen worden en dat shellscripts gebruik kunnen maken van tal van grafische elementen van KDE.

Om deze korte handleiding te kunnen volgen, moet je enigszins vertrouwd zijn met de basisvaardigheden van werken op de commandoregel en je zou je minstens bewust moeten zijn van het bestaan van shellscripts. Om efficiënt shellscripts te kunnen schrijven is een grondige kennis van de programmeeromgeving onontbeerlijk, net zoals dat voor andere programmeertalen het geval is. Toch zou je ook met beperkte kennis ten minste de voorbeelden halvelings moeten kunnen begrijpen. Een nadeel van die aanpak is dat deze handleiding deels redundant is, als je kennis van shellscripting wat uitgebreider is.

In de tutorial gaan we ervan uit dat je GNU's bash-shell gebruikt, of een andere shell die er helemaal compatibel mee is. Gebruik je een andere shell, dan kan het nodig zijn de voorbeelden ietwat aan te passen om ze correct te laten werken (zeker in het geval van csh en zijn varianten).

Qua techniek en aanpak is shellscripting erg gevarieerd. Soms moet een script enkel door het systeem gedraaid worden (bijvoorbeeld als cronjob), maar evengoed kunnen scripts soms echte toepassingen zijn, bedoeld om door een gebruiker opgestart te worden. KDE biedt je de mogelijheid om een deel van zijn functionaliteit in je shellscript te gebruiken. Dat kan je heel wat werk besparen; bovendien geeft het je script een mooi, met de desktop geïntegreerd uiterlijk.

Neem nu bijvoorbeeld iets als een wachtwoord-dialoogvenster. Als je van de gebruiker een wachtwoord nodig hebt, dan kan je daar makkelijk vanuit je script voor vragen, zodat het er als volgt uitziet:

voorbeeld 1: dialoogvenster voor een wachtwoord
wachtwoord-dialoogvenster

2 kdialog gebruiken

Een toepassing met de naam kdialog maakt het je mogelijk om KDE-dialoogvensters in te zetten in je shellscripts. Om een wachtwoorddialoog zoals hierboven te genereren, geef je op een commandoregel dit in:

kdialog --password "Geef je wachtwoord voor deze server op:"

Laten we de code uit dat eerste voorbeeld even van naderbij bekijken. De argumenten die je kdialog kan meegeven, dienen ertoe het type van dialoogvenster te bepalen, samen met de parameter(s) van dat venster. In het geval van een wachtwoord-dialoogvenster gebruik je dus --password om het dialoogtype te bepalen, gevolgd door de parameter, in dit geval de tekst die in het dialoogvenster weergegeven moet worden.

Elke keer als je kdialog (of eender welke andere toepassing, trouwens) opstart, wordt er een bepaalde waarde teruggegeven (een return value dus), die aangeeft of de toepassing naar verwachting gebruikt kon worden, of net op de een of andere manier foutliep. Die return value zit in de variabele $?, zoals het volgende volgende voorbeeld illustreert:

voorbeeld 2: teruggegeven waarde van een shellscript
[tom@zukunft ~]$ kdialog --password "Hier wat tekst."
hallo
[tom@zukunft ~]$ echo $?
0

De $?-variabele wordt elke keer wanneer een proces op de voorgrond afgesloten wordt bijgewerkt. Heb je de variabele later nog nodig, dan moet je hem ergens bewaren.

In het bovenstaande voorbeeld was de teruggegeven waarde nul. Als er op de Annuleren-knop gedrukt zou worden (en dus niet op OK), dan was de waarde één. Normaalgezien duiden negatieve cijfers op fouten, maar de shell trekt de cijfers af van 256. Als je een verplicht argument vergeet mee te geven, dan zal je systeem -2 teruggeven, dus de variabele $? wordt dan 254.

Deze aanpak is verschillend van de regels die voor de onderliggende grafische elementen gelden. Als je vertrouwd bent met Qt, dan kan dat wat verwarrend zijn, maar het is belangrijk de standaarden omtrent shellscripts na te leven.

voorbeeld 3: teruggegeven waarde van een shellscript, met fout
[tom@zukunft ~]$ kdialog --password
kdialog: '<text>' ontbreekt.
kdialog: Gebruik  --help voor een overzicht van de beschikbare commandoregelopties.
[tom@zukunft ~]$ echo $?
254

In een shellscript is het een goed idee om steeds de teruggegeven waarde na te kijken.

voorbeeld 4: wachtwoord-dialoogvenster, nagekeken op teruggegeven waarde
	kdialog --password "Geef je wachtwoord voor deze server op:"
	if [ $? = 0 ] then
		echo "je koos 'OK'"
	else
		echo "je koos 'Annuleren'"
	fi

Naast de teruggegeven waarde krijg je natuurlijk ook het paswoord zelf (ervan uitgaande dat er op OK geklikt werd). Een wachtwoord-dialoogvenster is immers vrij zinloos als je het niet kan gebruiken om een paswoord te krijgen... Dit type dialoogvenster, alsook de andere dialoogvensters die je met behulp van kdialog kan weergeven en in staat zijn tot het ontvangen van input, zendt zijn output naar standaard output. Zo kan je de input dus omleiden naar een bestand of naar een ander programma. In het geval van het wachtwoord-dialoogvenster zal de tekst die ingetikt wordt gewoon op de commandoregel verschijnen (cf. voorbeeld 2), tenzij je hem ergens anders heen stuurt.

voorbeeld 5: wachtwoord-dialoogvenster en omleiding van input
$ kdialog --password "Geef je wachtwoord op." > wachtwoord.bestand
$ cat wachtwoord.bestand
SDijE7q

Je kan ook altijd gebruik maken van een shell-variabele, in plaats van het resultaat op te slaan in een bestand. Merk op dat je backtick-notatie moet gebruiken, een enkel accent, maar dan afhellend naar rechts (zoals bijvoorbeeld in het Franse woord"thème"). Je vindt de juiste toets meestal links bovenaan op Engelse (Britse of Amerikaanse) toetsenborden, boven de "7"-toets op Franse toetsenborden en bovenaan rechts op Duits vormgegeven toetsenborden. Een Belgisch toetsenbord heeft de backtick op de toets links naast de enter-toets, onderaan (je krijgt hem door te combineren met Alt+Gr). En op Nederlandse toetsenborden? Wilbert? Fab?

voorbeeld 6: wachtwoord-dialoogvenster, met gebruik van een shell-variabele
$ password=`kdialog --password "Geef het wachtwoord."`
$ echo $password
SDijE7q

In de voorgaande voorbeelden werd het trouwens niet getoond, maar je kan ook de --title-parameter meegeven om de titel van het dialoogvenster te bepalen.

voorbeeld 7: wachtwoord-dialoogvenster, met titel
$ kdialog --title "CIA HQ -- login" --password "Geef je wachtwoord op:"
wachtwoord-dialoogvenster met titel

3 Dialoogvenstertypes

Een wachtwoord-dialoogvenster is maar eentje van de vele dialoogvensters die je met kdialog op het scherm kan toveren. Deze sectie belicht kort de verschillende mogelijkheden en beschrijft telkens de argumenten die je nodig hebt.

Eenvoudige berichtvensters

Eenvoudige berichtvensters worden gebruikt om kort informatie te geven over een bepaalde status. Er is variatie mogelijk, al naargelang van de mate van belang van het bericht (informatie, waarschuwing, foutmelding). In alle gevallen is het argument de tekst die getoond moet worden, zoals uit volgende voorbeelden mag blijken.

voorbeeld 8: informatief berichtvenster
$ kdialog --msgbox "Wachtwoord in orde.\nVerbinden met server..."
informatief berichtvenster
voorbeeld 9: "helaas"-berichtvenster
$ kdialog --sorry "Wachtwoord onjuist.\nGeen verbinding."
helaas-berichtvenster
voorbeeld 10: foutmelding
$ kdialog --error "Verbinding met server mislukt."
foutmelding

De teruggegeven waarde van deze eenvoudige berichtvensters is nul. Opnieuw kan je overigens de --title-parameter gebruiken om de venstertitel in te stellen; die optie kan immers voor alle dialoogvensters dienen.

Meer berichtvensters

Vaak heb je wat meer nodig dan enkel een eenvoudig berichtvensters. Misschien is er een handeling vereist die niet geheel vrij is van enig risico en wil je dus de gebruiker de mogelijkheid geven zich te bedenken. Of je moet een beslissing nemen op basis van wat informatie -- eender wat, kdialog voorziet hulpmiddelen die wel eens van pas zouden kunnen komen.

Een --yesno-dialoogvenster is het eenvoudigste dialoogvenster uit deze categorie. Net als de eenvoudige berichtvensters hogerop is enkel een tekst-string nodig, die in het dialoogvenster weergegeven wordt.

voorbeeld 11: --yesno-berichtvenster
$ kdialog --title "Verbinding maken?" --yesno "Er is momenteel geen verbinding.\nWilt u nu aanmelden?"
--yesno-berichtvenster

Een variatie op het type --yesno is --warningyesno, dat het dialoogvenster er ietwat anders doet uitzien.

voorbeeld 12: --warningyesno-berichtvenster
$ kdialog --title="Alle bestanden verwijderen?" --warningyesno "Bent u zeker dat u al dat harde werk zomaar wil verwijderen?"
--warningyesno-berichtvenster

Een andere variatie op hetzelfde thema is --warningcontinuecancel: vrijwel identiek, maar dan met andere knoppen en dus misschien in bepaalde situaties beter geschikt.

voorbeeld 13: --warningcontinuecancel-berichtvenster
$ kdialog --title="Alle bestanden verwijderen?" --warningcontinuecancel "Bent u zeker dat u al dat harde werk zomaar wil verwijderen?"
--warningcontinuecancel-berichtvenster

Een derde --yesno-achtig dialoogvenster is --yesnocancel.

voorbeeld 14: --yesnocancel-berichtvenster
$ kdialog --title="Absolute zelvernietiging?" --yesnocancel "U bent root. Wilt u desondanks eens 'rm -rf /' proberen?quot;
--yesnocancel-berichtvenster

Er is ook een --warningyesnocancel:

voorbeeld 15: --warningyesnocancel-berichtvenster
$ kdialog --title="Wijzigingen opslaan?" --warningyesnocancel "Het programma wordt afgesloten.\nWilt u uw wijzigingen opslaan?"
--warningyesnocancel-berichtvenster

De teruggegeven waarde ($?) is voor alle bovenstaande dialoogvensters gebaseerd op hetzelfde patroon. Ja, OK of Doorgaan geeft nul terug. Nee is één, Annuleren is twee.

Weergave van een dialoogvenster onderdrukken

Soms zal je kdialog in een lus willen gebruiken, of in een situatie die anderszins vereist dat een bericht meerdere malen weergegeven wordt. Je zou bijvoorbeeld door een lijstje met bestanden aan het bladeren kunnen zijn en je wil daarbij een foutmelding weergeven voor elk bestand dat je niet kan openen door een gebrek aan permissies. De gebruikerservaring laat op zo'n moment te wensen over, omdat de foutmelding keer op keer op keer op keer op het scherm komt te staan.

In de normale gang van zaken biedt KDE de gebruiker een manier om het bericht in de toekomst niet langer weer te geven, door een aankruisvakje te selecteren. In kdialog kan je dat doen met de --dontagain-optie. De optie krijgt een bestandsnaam en een term als parameter. Wanneer de gebruiker het vakje aanvinkt, wordt de term in het opgegeven bestand weggeschreven, zodat de keuze behouden blijft.

Neem bijvoorbeeld een informatief berichtvenster dat een ontbrekend bestand meldt:

voorbeeld 16: informatief berichtvenster, met --dontagain
$ kdialog --dontagain mijnScript:bestandOntbreektBericht --msgbox "Bestand ontbreekt."
berichtvenster met --dontagain

Zoals gezegd werd, wordt de term weggeschreven naar een bestand wanneer de gebruiker het vakje aankruist:

voorbeeld 17: --dontagain
$ cat .kde/share/config/mijnScript
[Notification Messages]
bestandOntbreektBericht=false

Zo wordt ervoor gezorgd dat de combinatie mijnScript/bestandOntbreektBericht in de toekomst geen berichtvensters meer oplevert. Dat geldt voor alle KDE-toepassingen, dus denk even na voor je een bestandsnaam kiest.

Dialoogvensters voor invoer van gebruikers

Er zijn twee eenvoudige dialoogtypes voor gebruikersinvoer: --inputbox en --password. In een vorige sectie zijn we uitgebreid op --password ingegaan (cf. kdialog gebruiken). Wat --inputbox betreft: dat dialoogtype vereist minstens één parameter, die als tekst zal dienen.

voorbeeld 18: --inputbox-dialoogvenster
$ kdialog --title="Kies een naam..." --inputbox "Welke naam wilt u gebruiken?"
--inputbox

Vaak is het een goed idee een standaard antwoord te voorzien. Dat kan je doen met een optionele tweede parameter:

voorbeeld 19: --inputbox-dialoogvenster met standaard antwoord
$ kdialog --title=""Kies een naam..." --inputbox "Welke naam wilt u gebruiken?" "Bassie"
--inputbox met standaard antwoord

De teruggegeven waarde hangt opnieuw af van de aangeklikte knop. OK geeft nul, Annuleren één. De tekst die ingegeven wordt (of gewijzigd of aanvaard wordt wanneer je een standaard antwoord aanbiedt) wordt naar standaard-uitvoer geworpen. Kiest de gebruiker om te Annuleren, dan wordt er natuurlijk gewoon geen uitvoer verzonden.

Bestanden weergeven

Vaak wil je vanuit je shellscript een bestand weergeven. Dat kan met kdialog door middel van een --textbox. Er is daarbij één verplichte parameter, namelijk de naam van het bestand dat weergegeven moet worden. Er zijn verder twee optionele parameters, waarmee je de breedte en de hoogte van het dialoogvensters kan bepalen (in pixels). Heb je daarover geen bijzondere eisen, dan wordt een grootte van 100 op 100 pixels gebruikt.

voorbeeld 20: --textbox-dialoogvenster
$ kdialog --textbox kdialog.html
--textbox zonder meer
voorbeeld 21: --textbox-dialoogvenster met afmetingen
$ kdialog --textbox kdialog.html 450 250
--textbox met afmetingen

Dialoogvensters met menu's en dialoogvensters voor selectie

Deze sectie beschrijft dialoogvensters met eenvoudige menu's, aankruislijsten, radio-knoppen en combo-boxes, allemaal dingen die goed bruikbaar zijn om een reeks van mogelijke keuzes aan te bieden.

Een menu is er om één keuze te maken uit een reeks mogelijkheden. Elke optie wordt omschreven met twee argumenten, die je kan vergelijken met een klassiek key/label-paar. Een voorbeeld:

voorbeeld 22: --menu-dialoogvenster
$ kdialog --menu "Kies een taal:" a "Nederlands (Nederland)" b "Nederlands (België)" c Duits d Engels
--menu-dialoogvenster

Als je de eerste optie selecteert (i.c. "Nederlands (Nederland)") en je keuze met OK bevestigt, dan zal kdialog de met die keuze geassocieerde "sleutel" (i.c. de letter a) naar standaard-uitvoer zenden. Merk op dat de sleutel geen kleine letter hoeft te zijn, je kan evengoed cijfers, hoofdletters, strings of zelfs shell-variabelen gebruiken.

Net zoals bij de vorige voorbeelden geeft OK een nul en Annuleren een één terug.

Een aankruislijst (checklist) lijkt erg op een menu, maar de gebruiker kan nu meer dan één optie selecteren. Bovendien kan je een setje keuzes als standaard aangeven. Je werkt nu met drie argumenten, een sleutel en een label zoals bij het menu en ook nog een standaard-status.

voorbeeld 23: --checklist-dialoogvenster
$ kdialog --checklist "Kies je talen:" 1 "Nederlands (Nederland)" off 2 "Nederlands (België)" on 3 Duits on 4 Engels off
--checklist-dialoogvenster

Het resultaat kan dus meer dan één string bevatten. Normaalgezien staan alle resultaten op een enkele lijn, maar met --separate-output krijg je een carriage return na elke selectie. Dat wordt in onderstaand voorbeeld geïllustreerd: in beide gevallen werden alle mogelijkheden geselecteerd.

voorbeeld 24: --checklist-dialoogvenster
$ kdialog --checklist "Kies je talen:" 1 "Nederlands (Nederland)" off 2 "Nederlands (België)quot; on 3 Duits on 4 Engels off
"1" "2" "3"
$ kdialog --separate-output --checklist "Kies je talen:" 1 "Nederlands (Nederland)" off 2 "Nederlands (België)" on 3 Duits on 4 Engels off
1
2
3

Opnieuw hangt de teruggegeven waarde af van de gebruikte knoppen (OK: nul, Annuleren: één).

Een radio-lijst heeft veel weg van een aankruislijst, maar de gebruiker kan slechts één optie selecteren.

voorbeeld 25: --radiolist-dialoogvenster
$ kdialog --radiolist "Kies een standaardtaal:" 1 Nederlands on 2 Engels off 3 Duits off 4 Frans off
--radiolist-dialoogvenster

Merk op dat alleen de laatst-geselecteerde optie doorgegeven wordt, als je probeert om toch meerdere opties aan te geven. Selecteer je geen enkele optie en de gebruiker vertikt het evenzeer om er eentje aan te duiden, dan zal kdialog een assertion omhoogsmijten. Laat het dus niet zover komen.

Een combo-box is weer wat anders: er wordt geen gebruik gemaakt van sleutelwaarden, maar de geselecteerde tekst wordt eenvoudigweg doorgegeven:

voorbeeld 26: --combobox-dialoogvenster
$ kdialog --combobox "Kies je favoriete drug:" "Weed" "Hasj" "LSD" "Cocaïne" "Heroïne" "Andere"
LSD
--combobox-dialoogvenster

Dialoogvensters voor selectie van bestanden

Deze sectie gaat over dialoogvensters waarmee bestanden geselecteerd kunnen worden om te openen en op te slaan. Deze dialoogvensters maken gebruik van de kracht van de onderhuidse "echte" KDE-dialogen (denk bijvoorbeeld aan gevorderde filtertechnieken). Ze kunnen zowel bestandspaden als URL's teruggeven.

Een dialoogvensters voor het openen van een bestand krijg je met --getopenfilename of --getopenurl. Deze commando's worden op dezelfde wijze gebruikt, enkel het formaat van het resultaat is anders. Daarom kan elk voorbeeld dat volgt op beide wijzen gebruikt worden. Je moet een startmap (directory) opgeven, eventueel vergezeld van een filter. Een eenvoudig voorbeeld zonder filter, dat de huidige directory betreedt:

voorbeeld 27: --getopenfilename-dialoogvenster
$ kdialog --getopenfilename .
--getopenfilename-dialoogvenster

De teruggegeven waarde volgt het intussen klassiek geworden recept.

Zoals reeds vermeld werd is het formaat van het resultaat afhankelijk van de gebruikte variant. In hetvolgende voorbeeld wordt hetzelfde bestand bedoeld:

voorbeeld 28: --getopenfilename versus --getopenurl
$ kdialog --getopenfilename .
/home/test/Desktop/kdialog/kdialog9.png
$ kdialog --getopenurl .
file:/home/test/Desktop/kdialog/kdialog9.png

Merk op dat de gebruiker enkel reeds bestaande bestanden kan selecteren met deze dialoogvensters.

Als je script veelvuldig vraagt om bestanden te openen, kan het nuttig zijn het dialoogvensters te laten starten in de meest recent betreden directory. Je zou die directory uit de bestandsnaam kunnen afleiden, maar er is een handig hulpmiddel dat gebaseerd is op labels:

voorbeeld 29: --getopenfilename-dialoogvenster met labels
$ kdialog --getopenfilename :label1
$ kdialog --getopenfilename :label1

Elke keer als je hetzelfde label gebruikt (met de dubbele punt ervoor), zal de laatst betreden directory als startpunt weergegeven worden, wat de gebruikerservaring positief beïnvloedt. Als een label nog niet gebruikt werd, wordt de home-directory van de gebruiker gekozen.

Merk op dat de dubbele punt de laatst betreden directory voor dat label kiest binnen kdialog en enkel daar. Als je twee dubbele punten gebruikt, vergroot het bereik van het label zich tot de hele KDE-omgeving. Dat is meestal niet de bedoeling, maar het wordt hier volledigheidshalve even vermeld.

Het kan zijn dat niet alle bestanden geldig zijn in de gegeven omstandigheden. In zo'n geval wil je de lijst met weergegeven bestanden beperken. Dat kan met een optioneel filter-argument. De beste manier om zoiets te doen is gebaseerd op MIME-types.

voorbeeld 30: --getopenfilename-dialoogvenster met MIME-filter
$ kdialog --getopenfilename /home/test/Desktop/kdialog "image/png text/html text/plain"
--getopenfilename-dialoogvenster met MIME-filter

Als het niet mogelijk is om met MIME-types te werken, dan kan je een reeks jokertekens en optioneel een label weergeven:

voorbeeld 31: --getopenfilename-dialoogvenster met jokerteken-filter
$ kdialog --getopenfilename . "*.cpp *.cc *.c |C en C++ broncodebestanden"

De --getsavefilename- en --getsaveurl-dialoogvensters zijn volkomen analoog aan de dialoogvensters om bestanden mee te openen. Een verschil is wel dat de dialoogvensters voor het bewaren van bestanden het de gebruiker toestaan een bestandsnaam op te geven die nog niet bestaat. Verder moet opgemerkt worden dat ook dit type de notatie met dubbele punt toestaat, alsook filters met MIME-types en met jokertekens:

voorbeeld 32: --getsavefilename-dialoogvenster
$ kdialog --getsavefilename :label1 "*.cpp *.cc *.c|C en C++ broncodebestanden"

Soms wil je geen bestandsnaam specificeren, maar een map (directory). Je kan weliswaar een "inode/directory"-filter opgeven, maar vaak is het beter om gebruik te maken van --getexistingdirectory:

voorbeeld 33: --getexistingdirectory-dialoogvenster
$ kdialog --getexistingdirectory /usr/share/doc
--getexistingdirectory-dialoogvenster

Het is niet mogelijk om filters te gebruiken met --getexistingdirectory. Je kan er echter wel de startplek mee beïnvloeden, ook met de dubbele-punt-aanpak.

4 Licenties en verdiensten

De originele tutorial over KDialog is van de hand van Brad Hards. Je vindt hem op developer.kde.org. De vertaler heeft het origineel vooral naar het einde toe enigszins ingekort, vanwege een al te repetitief karakter (de howto, niet de vertaler).

Het is toegestaan dit document te kopiëren, te verdelen en/of te wijzigen onder de voorwaarden van de GNU vrije-documentatielicentie, versie 1.1 of een latere versie gepubliceerd door de Free Software Foundation; zonder invariante paragrafen, zonder vooromslagteksten, en zonder achteromslagteksten.

Over deze site | Laatst gewijzigd: 23 april 2004, 23:30 door: Tom Verbreyt