Na čem aktuálně pracují vývojáři GNOME a KDE Plasma? Pravidelný přehled novinek v Týden v GNOME a Týden v KDE Plasma.
Byla vydána nová verze 0.4.15 (𝕏) svobodného operačního systému ReactOS (Wikipedie), jehož cílem je kompletní binární kompatibilita s aplikacemi a ovladači pro Windows. Přehled novinek i s náhledy v oznámení o vydání.
Byl představen rpi-image-gen, tj. oficiální nástroj pro vytváření vlastních softwarových obrazů pro zařízení Raspberry Pi.
Byla vydána nová major verze 8.0, aktuálně 8.0.1, softwaru pro správu elektronických knih Calibre (Wikipedie). Přehled novinek v poznámkách k vydání. Vypíchnuta je lepší podpora Kobo KEPUB formátu nebo integrovaný lokálně běžící engine Piper pro převod textu na řeč používaný pro čtení nahlas (již od verze 7.18).
Společnost OpenAI rozšířila své API o nové audio modely. Nový model pro převod textu na řeč (text-to-speech model) lze bez přihlašování vyzkoušet na stránce OpenAI.fm.
Příspěvek Bezpečnost paměti pro webové fonty na blogu Chrome pro vývojáře rozebírá, proč se pro zpracování webových fontů v Chrome místo FreeType nově používá v Rustu napsaná Skrifa z Fontations.
V pátek 21. a v sobotu 22. března proběhnou Arduino Days 2025, tj. každoroční „narozeninová oslava“ platformy Arduino. Na programu je řada zajímavých přednášek. Sledovat je bude možné na YouTube. Zúčastnit se lze i lokálních akcí. V sobotu v Praze na Matfyzu.
Komunitná konferencia Bratislava OpenCamp, ktorá sa uskutoční už o tri týždne 5. 4. 2025 na FIIT STU pozná svoj program – návštevníkom ponúkne 3 paralelné behy prednášok a workshopov na rôzne témy týkajúce sa otvoreného softvéru či otvorených technológií.
Časopis MagPi od nakladatelství Raspberry Pi se s číslem 151 přejmenoval na Raspberry Pi Official Magazine. I pod novým názvem zůstává nadále ve formátu pdf zdarma ke čtení.
Japonská SoftBank Group kupuje firmu Ampere Computing za 6,5 miliardy dolarů. Ampere Computing vyrábí 32-128jádrové procesory Ampere Altra a 192jádrové procesory AmpereOne.
Skript v Kommanderu je běžný textový SGML soubor. Můžeme jej tedy editovat ve svém oblíbeném editoru (například ve vimu), Většina lidí ale asi využije spíše prostředí Kommander Editoru. Příkaz Edit Kommander Text nás zavede do editačního okna, které jsme viděli v předchozím dílu (Kommander - 1 (Skriptované GUI)). Teď si je popíšeme podrobněji.
initialization
. To znamená, že daný kód se provede při
inicializaci okna formuláře.Toto okno je velmi praktické, protože vám umožňuje snadno proniknout do hlubin Kommanderu a jeho funkcí. Příkazy jsou rozděleny do sedmi skupin:
@if,
@exec, ...
).Ve sloupci Parameters vidíme parametry dané funkce a poslední sloupec obsahuje krátký popis funkce a její syntaxe. Tlačítko s velkou modrou šipkou pak vloží text do spodního textového pole a stiskem OK dojde k vložení funkce do kódu. Vzhledem k této skutečnosti je zbytečné psát referenční příručku ke Kommanderu, vše potřebné máte v okně Functions Browser. Ale pokud byste na ní trvali, tak ji naleznete na docs.kde.org. Dále raději píšu o věcech, které takto nezjistíte - a některé z nich mi daly pořádně zabrat, než jsem na ně přišel.
Každý widget má množinu akcí, které může vykonat. Nejčastější akce jsou
default
a population
. Nejčastěji používanou je
právě default
, která třeba u tlačítka značí jeho stisknutí.
Formuláře navíc mají initialization
a destroy
,
které se provádí při statu a ukončení aplikace.
Akce default
se spouští při zavolání prvku. Nejjednodušším
příkladem je rozbalovací seznam ComboBox1
, který v této akci
má napsáno @widgetText
. Tím dojde k tomu, že budou následující
ekvivalentní.
@ComboBox1
@ComboBox1.text
Samozřejmě může být v oné akci napsán jakýkoliv kód, například transformace textu na něco jiného.
Check Boxy (přepínače) a Radio buttony (skupinové přepínače) nemají akci
default
. Namísto toho mají checked
,
semichecked
a unchecked
. Kód se spouští, pokud je
tlačítko vybráno, napůl vybráno (pokud je třetí stav povolen) nebo
nevybráno. Díky tomu nemusíme stav tlačítek zjišťovat, stačí potřebný kód
napsat do odpovídajících sekcí.
Původně jsem chtěl pro demonstraci vlastností jazyka Kommanderu použít některou z existujících aplikací, ale nakonec jsem si ji musel sám napsat. Nedělá sice nic užitečného, ale je jednoduchá a přizpůsobena tomuto seriálu. Můžete si jí stáhnout a vyzkoušet.
Pokud, stejně jako já, považujete proměnné za základ všech (tedy alespoň procedurálních) programovacích jazyků, pak asi zažijete menší šok. Práce s proměnnými je v Kommanderu docela zamotaná a co víc, dokumentace (které není mnoho) o tomto tématu mlčí.
Takže mi nezbývalo nic jiného, než se ponořit do čtení zdrojových kódů aplikací napsaných v Kommanderu. Tak jsem objevil čtyři způsoby, jak Kommander pracuje s proměnnými:
@exec(echo $FOO)
. Dnes již
Kommander obsahuje funci @env(FOO)
.@setGlobal(foo, hodnota)
a
@global(foo)
. Jak už jsem říkal, každý obslužný skript běží
samostatně, a proto proměnné, které potřebujeme i jinde v programu, musíme
převést na globální.Proměnné v cyklech - jazyk Kommanderu obsahuje i svoje speciální cykly a v nich se používají proměnné. K těmto proměnným se přistupuje pomocí znaku @.
@for(i,1,5,1)
@Message.info(@i)
@endif
Na tomto by snad nebylo nic tak těžkého, kdyby... Naprosto neřešitelným
problémem pro mě bylo, jak použít proměnnou shellu jako parametr některé z
funkcí. Vysvětlím na malém příkladě. Mám proměnnou foo
a chci
její obsah uložit do widgetu label
. Kód, který by asi každý
napsal nějak takto:
foo="Hello, world!"
@label.setText($foo) # nic se nestane
@label.setText(@foo} # chyba, @foo není definován
nefunguje. Nakonec se mi podařilo najít řešení v podobě výrazu:
foo="Hello, world!"
dcop @dcopid KommanderIf setText label $foo
Tedy řešení. Po tomto zjištění jsem se pokorně vrátil ke globálním proměnným. Zůstala jedna výhoda. Alespoň teď vidíme, jak přesně starý parser Kommanderu pracuje.
@Widget.názevFunkce(Obsah) # se převede na volání
dcop @dcopid KommanderIf názevFunkce Widget Obsah
Pokud neznáte DCOP (Desktop COmmunication Protocol), potom vězte, že se
jedná o rozhraní, kterým spolu mohou programy (nejčastěji v KDE)
komunikovat. Prvním parametrem na příkazovém řádku je identifikační číslo
běžícího skriptu. Dále následuje jméno rozhraní, jméno funkce. Potom
následují parametry pro funkci setText
, a to jméno widgetu
a text, který se má vložit. Více o DCOP naleznete v článku KDE: tipy a triky -
III (DCOP a KDialog).
Přiznám se, že konceptu klíčových slov Kommanderu příliš nerozumím.
Jistě, je dobré mít příkazy jako @dcopid
, který vrací
identifikaci běžícího okna. A nebo příkazy pro práci s globálními
proměnnými a podobně.
Ovšem smysl příkazů @if
, @for
a
@while
mi uniká. Přesto jsou součástí jazyka. Jenže jejich
implementace je více než podivná! První nevýhodou je, že není
možné tyto příkazy zanořovat! Kód
@if ( ...)
@if ( ... )
@endif
@endif
skončí chybovým hlášením Unknow special: endif
! No a věc,
která mě dostala ještě více, je nepřítomnost klíčového slova
@else
. Díky tomu je tato podmínka prakticky nepoužitelná.
Dalším aspektem, který snižuje použitelnost výrazu @if
jsou
neexistující konvence pro návratové hodnoty. Pravdivost příkazu
@if
je definována jako nenulové číslo, anebo neprázdný
řetězec. Jenže taková funkce @String.find
vrací při neúspěchu
-1. Funkce @String.compare
vrací při rovnosti řetězců 0, pokud
je řetězec menší, tak -1, jinak 1. Což je implementace vhodná pro řazení
řetězců, ale ne pro porovnávání rovnosti řetězců v podmínce. Pokud máte
možnost, vyhněte se těmto funkcím, protože je evidentní, že je to celé šité
horkou jehlou!
Velkým rozdílem oproti klasickým skritpům je, že každý obslužný skript
běží odděleně. U větších objektů potřebujeme udělat dekompozici a opakující
se (nebo logické) části dát jinam. Řešením je widget ScriptObject.
Tam si můžeme vložit potřebný kód a zavoláním @ScriptObject
jej vykonáme. Tyto skripty trpí dvěma nevýhodami. Jednak netuším, zda vůbec
podporují parametry (nikde jsem to nenašel). Dalším problémem je, že ač
nevizuální, dělají problémy při používání správce rozložení.
Na druhou stranu jsou potřebné při používání signálů a slotů (více
dále). Pokud chceme sofistikovanější funkce, nezbyde nám nic jiného, než
použít klasický shellový způsob
'./cesta/k/souboru/knihovna.sh'
. Tím bohužel přijdeme o výhodu
Kommanderu, že je vše v jednom skriptu.
Signály a sloty je způsob, kterým spolu widgety z knihovny Qt mohou komunikovat (více viz Začínáme KProgramovať - I). A protože používáme Qt widgety, používáme i signály a sloty. V Editoru propojujeme patřičné signály se sloty v okně Edit Connections.
Tento koncept se mi bez příkladu špatně vysvětluje. V demo aplikaci máte
záložku Signály a sloty, kde máte příklad. Máme rozbalovací seznam
(ComcoBox) jménem Partitions
, který obsahuje seznam oddílů.
Ten naplníme při startu příkazem
@Partitions.insertItems(@exec(df | awk '/^\/dev/ {print substr($1,6)}' |
sort),0)
Tento kód nám naplní seznam všech oddílů bez úvodního
/dev/
. Nyní chceme zobrazit informace o celkové kapacitě,
volném a použitém místě. V této chvíli využijeme ScriptObject
z předchozí části, protože ten bude zjišťovat velikosti a vypisovat
je.
@Space.setText(Kapacita @exec(df --block-size 1K -h /dev/@Partitions.text \
| awk '/dev/ {print $2}')B)
Zjištění jiných hodnot než celkové velikosti je už analogické. Stačí
změnit parametr příkazu print
.
Tento kód se bude provádět při startu, po naplnění seznamu. A dále po
změně widgetu Partitions
. K tomu je nutné správně propojit
patřičný signál a slot, jak ukazuje tento obrázek.
Odesílatelem je widget Partitions
, který vyšle signál
widgetTextChanged(const QString&)
(textWidgetuZměněn).
Příjemcem je objekt Size
, respektive jeho slot
execute
(proveď se). Tím dojde při výběru jiného disku k
aktualizaci hodnot.
Při psaní kódu se nemusíte omezovat (ne)možnostmi shellu. Kommander nabízí snadnou integraci s jiným programovacím jazykem. V dokumentaci jsem nenašel, které jsou podporované. Osobně jsem zkusil Perl, Python a Ruby, ale předpokládám, že bude stačit, aby interpret dokázal načítat vstup ze standardního jazyka. Ostatně můžete vyzkoušet svůj oblíbený interpret (třeba interpret jazyka C?) a o výsledku poreferovat v diskuzi. Pro Pythonisty mám dobrou zprávu, Kommander zachovává odsazení, takže jeho používání nic nebrání.
@execBegin(python)
import os
def hello():
os.system('kdialog --msgbox "Hello from Python!"')
hello()
@execEnd
Jak vidíte, kód v Pythonu je uzavřen mezi
@execBegin(python)
a @execEnd
. Uvnitř už můžete
používat libovolné konstrukce Pythonu, případně Kommanderu. Podle
dokumentace není doporučené psát tento kód v událostních skriptech
jednotlivých widgetů kvůli možným problémům s návratovými hodnotami.
Kommander rovněž neklade žádná omezení na počet použitých jazyků.
V Perlu i Ruby má zavináč syntaktický význam. Proto je nutné tyto výrazy uvodit ještě jedním zavináčem, aby je parser snadno poznal od svých výrazů.
@execBegin(perl)
open(MTAB, "/etc/mtab");
@@foo = <MTAB>;
foreach (@@foo) {
print $_;
}
@execEnd
Dnes jsme se seznámili s používáním Kommander Editoru. Zjistili jsme, co je to akce (omlouvám se za neoficiální překlad). Zkusili si nevýhody starého parseru Kommanderu (práce s proměnnými). Díky čemuž už víme, jak Kommander pracuje uvnitř. Dále známe potíže s některými klíčovými slovy a funkcemi. To, vše bylo motivací k tvorbě nového parseru.
Dále jsme se, pokud jsme už neprogramovali v Qt, seznámili s komunikací mezi widgety - signály a sloty. Za třešničku na dortu potom můžeme považovat možnost použít prakticky jakýkoliv jiný skriptovací jazyk. V dalším díle opustím starý parser a budu se věnovat tomu novému.
Nástroje: Tisk bez diskuse
Tiskni
Sdílej:
if (!strcmp(....))
, což znamená, že řetězce jsou stejné. Možná trochu matoucí, ale dá se na to zvyknout.