abclinuxu.cz AbcLinuxu.cz itbiz.cz ITBiz.cz HDmag.cz HDmag.cz abcprace.cz AbcPráce.cz
AbcLinuxu hledá autory!
Inzerujte na AbcPráce.cz od 950 Kč
Rozšířené hledání
×

dnes 01:44 | Zajímavý projekt

Kampaň na podporu chytrého telefonu Librem 5, jenž by měl respektovat bezpečnost, svobodu a soukromí uživatelů, úspěšně skončila. Bylo vybráno více než 2,1 milionu dolarů, tj. cíl kampaně byl splněn na více než 141 %. Objednáno bylo cca 3 000 telefonů. Telefon Librem 5 by měl být k dispozici v lednu 2019.

Ladislav Hagara | Komentářů: 3
včera 21:11 | Komunita

Ke zhlédnutí jsou videozáznamy přednášek z konferencí All Systems Go! (media.ccc.de) a GStreamer Conference 2017 (ubicast.tv) konaných o víkendu 21. a 22. října. All Systems Go! v Berlíně a GStreamer Conference 2017 v Praze.

Ladislav Hagara | Komentářů: 0
včera 20:33 | Komunita

MojeFedora.cz informuje (en), že Fedora 27 přináší snadný přístup k Red Hat Enteprise Linuxu. Virtualizační nástroj Boxy nyní umožňuje jednoduše stáhnout a nainstalovat Red Hat Enterprise Linux, který je pro vývojáře zdarma. Vytvořit lze neomezené množství virtuálních mašin s RHEL.

Ladislav Hagara | Komentářů: 2
včera 19:00 | Komunita

Konsorcium Linux Foundation oficiálně představilo licence pro komunitní otevřená data Community Data License Agreement (CDLA). První licence je copyleftová CDLA-Sharing a druhá permisivní CDLA-Permissive. Odpovědi na často kladené otázky ve FAQ.

Ladislav Hagara | Komentářů: 0
včera 13:55 | Pozvánky

Spolek OpenAlt zve příznivce otevřených technologií a otevřeného přístupu na 145. pražský sraz, který proběhne ve čtvrtek 26. října od 18:00 hodin v karlínském Pivovarském klubu. Najdete jej kousek od metra Florenc na adrese Křižíkova 17, Praha 8. Jedná se o poslední sraz před konferencí OpenAlt 2017, jež proběhne o víkendu 4. a 5. listopadu 2017 na FIT VUT v Brně. Běží registrace účastníků.

Ladislav Hagara | Komentářů: 0
včera 06:00 | Zajímavý software

Byla vydána verze 0.56 open source platformy Home Assistant (GitHub) pro monitorování a řízení inteligentní domácnosti naprogramované v programovacím jazyce Python verze 3 a bežící také například na Raspberry Pi. Pro vyzkoušení je k dispozici demo [reddit].

Ladislav Hagara | Komentářů: 0
22.10. 16:55 | Nová verze

Byla vydána verze 1.0 klienta F-Droid určeného pro instalaci aplikací do Androidu ze softwarového repozitáře F-Droid (Wikipedie), alternativy k Google Play, nabízející pouze svobodný a otevřený software. Podrobnosti v přehledu změn [Hacker News].

Ladislav Hagara | Komentářů: 8
22.10. 00:55 | Nová verze

Po téměř 13 měsících vývoje od verze 0.11.0 byla vydána verze 0.12.0 hardwarově nenáročného desktopového prostředí LXQt (Lightweight Qt Desktop Environment, Wikipedie) vzniklého sloučením projektů Razor-qt a LXDE. Přehled novinek v příspěvku na blogu.

Ladislav Hagara | Komentářů: 10
21.10. 12:33 | Zajímavý software

Článek ne Medium představuje nejnovější stabilní verzi 2.0 svobodné decentralizované mikroblogovací platformy a sociální sítě podobné Twitteru Mastodon (Wikipedie). Detailní přehled novinek na GitHubu [Hacker News].

Ladislav Hagara | Komentářů: 0
21.10. 06:00 | Komunita

V Praze na půdě Elektrotechnické fakulty ČVUT dnes probíhá RT-Summit 2017 – setkání vývojářů linuxového jádra a uživatelů jeho real-time verze označované jako preempt-rt. Přednášky lze sledovat online na YouTube.

Ladislav Hagara | Komentářů: 0
Jak se vás potenciálně dotkne trend odstraňování analogového audio konektoru typu 3,5mm jack z „chytrých telefonů“?
 (10%)
 (1%)
 (0%)
 (1%)
 (75%)
 (12%)
Celkem 246 hlasů
 Komentářů: 8, poslední 22.10. 23:02
    Rozcestník

    KDE pro programátory – KParts

    9. 2. 2011 | Dan Vrátil | Programování | 2809×

    KParts je jedna ze zajímavých technologií, která umožňuje do aplikací integrovat části z jiných programů. V tomto článku si ukážeme, jak se KParts používají, a v jeho druhé části, jak vytvořit vlastní KPart.

    KParts

    KParts lze přirovnat k velmi specifickým pluginům, které můžete načítat a odstraňovat za běhu. Společným rysem je, že obsahují zpravidla kompletní uživatelské rozhraní pro složitější operace a automatickou integraci do hlavního menu a panelu nástrojů hlavní aplikace.

    Zajímavým použitím KParts v KDE jsou například PIM aplikace. KMail, KOrganizer, KAddressBook a Akregator mají každý svou KPart, která implementuje veškerou funkcionalitu. KMail jako takový je pouze prázdné okno, která načíta KMailPart. Když spustíte Kontact, opět se jedná jen o jednoduché okno, které přepíná příslušné KParts.

    Pokud chcete zjistit, které KParts máte k dispozici, víceméně jediný způsob je pomocí

    ls /usr/share/kde4/services/*part.desktop
    

    Existují dva typy KParts: ReadOnlyPart a ReadWritePart. První zmíněný se používá na zobrazování (třeba Okular Part nebo Gwen Part), druhý se používá na editory (třeba Kate Part). Pro větší názornost ukážu vše na jednoduchém prográmku – správci souborů, který v pravém panelu bude pomocí KPart zobrazovat obsah souboru.

    Okno, které má zobrazovat KParts, musí být odvozené od KParts::MainWindow (třída odvozená od KXmlGuiWindow), jinak nic speciálního není potřeba.

    mainwindow.cpp

    // Konstruktor a destruktor - viz tarball se zdrojaky
    ...
    ...
    void MainWindow::openFilePreview(KUrl url)
    {
      // Pokud se zrovna zobrazuje nejaky KPart, tak ho odstrani
      if (m_kpart) {
        // Odebere z menu a toolbaru polozky, ktere tam naistalovala aktualni KPart
        createGUI(0);
        delete m_kpart;
        m_kpart = 0;
      }
      
      QFileInfo finfo(url.url());
      if (finfo.isDir()) return;
    
      // Podporovane KParts::ReadWritePart
      QMap<QString,QString> rwparts;
      rwparts["txt"] = "katepart";
      
      // Podporovane KParts::ReadParts
      QMap<QString,QString> roparts;
      roparts["gz"] = "ark_part";
      roparts["xz"] = "ark_part";
      roparts["zip"] = "ark_part";
      roparts["rar"] = "ark_parts";
      roparts["tar"] = "ark_parts";
      roparts["ttf"] = "kfontviewpart";
      roparts["patch"] = "komparepart";
      roparts["diff"] = "komparepart";
      roparts["ui"] = "kuiviewer_part";
      roparts["pdf"] = "okular_part";
      roparts["png"] = "gvpart";
      roparts["jpg"] = "gvpart";
      roparts["jpeg"] = "gvpart";
      roparts["html"] = "kwebkitpart";
    
      // Zjisti, jestli je vybrany soubor podporovany a jestli je to RW nebo RO Part
      QString partName;
      int partType = 0;
      if (rwparts.contains(finfo.suffix())) {
        partName = rwparts[finfo.suffix()];
        partType = 1;
      }
      
      if (roparts.contains(finfo.suffix())) {
        partName = roparts[finfo.suffix()];
        partType = 2;
      }
      
      if (partName.isEmpty()) {
        qDebug() << "Unsupported file format";
        return;
      }  
      
      // Nacte .desktop soubor prislusne KPart
      KService::Ptr service = KService::serviceByDesktopPath(partName+".desktop");
      if (!service) {
        qDebug() << "Failed to load service" << partName;
        return;
      }
      
      // Podle informaci z .desktop souboru vytvori prislousnou KPart
      if (partType == 1) {
        m_kpart = service->createInstance(0);
      } else {
        m_kpart = service->createInstance(0);
      }
      
      if (!m_kpart) {
        qDebug() << "Failed to create instance of " << partName;
        return;
      }
      
      // Prida KPart do splitteru
      m_splitter->addWidget(m_kpart->widget());
      m_kpart->widget()->setMinimumWidth(350);
    
      // Dulezita cast: tento prikaz nainstaluje toolbary, menu a klavesove zkraty nactene KPart do okna,
      // takze uzivatel nejenze vidi samotny soubor, ale muze s nim i pracovat
      createGUI(m_kpart); 
      setupGUI(ToolBar | Keys | StatusBar);
      
      // Otevre v KPart vybrany soubor
      m_kpart->openUrl(url);
     
    }
    

    Klíčovou částí programu je metoda openFilePreview(). V celku se načítání KPart skládá ze tří části: načtení informací z .desktop souboru pomocí KService::serviceByDesktopPath(), následně vytvoření instance KPart pomocí KService::Ptr::createInstance(). Dobré je poznamenanat, že pokud nepotřebujete speciální metody pro ukládání dat z KPart, můžete i pro editory (například kate_kpart) použít třídu KParts::ReadOnlyPart (ReadWritePart je jejím přímým potomkem). V tomto příkladu je tedy použítí ReadWritePart zbytečné, všechny používané metody jsou implementované v ReadOnlyPart.

    Nakonec se vytvořená KPart zobrazí pomocí createGUI() a toolbary a menu se nainstalují pomocí setupGUI(). Aby se menu a toolbary nainstalovaly správně, je potřeba přidat do .rc souboru tagy <merge/>:

    <?xml version="1.0"?>
    <!DOCTYPE gui SYSTEM "kpartgui.dtd">
    <gui version="1" name="filesviewer">
    <MenuBar>
      <Menu name="file">
        <text>Soubor</text>
        <Merge/>
        <Action name="file_quit"/>
      </Menu>
      <Merge/>
      <Menu name="help">
      </Menu>
    </MenuBar>
    </gui>
    

    Všimněte si pozice prvků <merge/>. Na tato místa nainstaluje KPart svoje části menu. Pokud vynecháte například merge v menu Soubor, umístí se položky KParts až nakonec, za Zavřít. Také doctype se liší, je potřeba změnit na kpartgui.dtd.

    Program bez načtené KPart GwenView Part Kate Part

    Úplně nakonec metodou openUrl() nacháme KPart načíst soubor.

    Drobná poznámka k Ark Part: pokud zavřete Ark Part v době, kdy načítá archiv, tak aplikace spadne. Jde o nahlášenou chybu v Ark Part, na kterou jsem nenašel žádný workaround (a vývojáři Arku zjevně také ještě ne).

    Pokud potřebujete v aplikaci pracovat s více KParts, může se vám hodit PartManager. Jedná se o třídu, do které se pomocí addPart() přidá instance všech KParts, které se budou v aplikaci používat a pak se pomocí setActivePart() aktivují. Hlavně u velkých KParts o ušetrí hodně režie, na druhou stranu aplikace bude paměťově náročnější. Pokud bychom příklad výše upravili aby používal PartManager, vypadalo by to asi takto:

    mainwindow.cpp

    MainWindow::MainWidow() 
    {
      ...
      ...
    
      // Vytvori toolbar, klavesove zkratky a nastavi geometrii okna podle XML souboru a konfigurace
      setupGUI(ToolBar | Keys | Create);
    
      // Vytvori managera 
      m_manager = new KParts::PartManager(this);
      QStringList parts;
      parts << "katepart" << "ark_part" << "kfontviewpart" << "komparepart" << "kuiviewer_part" << "okular_part" << "gvpart" << "kwebkitpart";
      for (int i = 0; i < parts.size(); i++) {
          KService::Ptr service = KService::serviceByDesktopPath(parts.at(i)+".desktop");
          if (!service) {
    	  qDebug() << "Failed to load service" << parts.at(i);
    	  continue;
          }
          KParts::ReadOnlyPart *kpart = service->createInstance(this);
          if (!kpart) {
    	  qDebug() << "Failed to create instance of " << parts.at(i);
    	  continue;
          }
          // Podle objectName budeme pozdeji pluginy vyhledavat
          kpart->setObjectName(parts.at(i));
       
          // Prida KPart do managera
          m_manager->addPart(kpart);
    
          // Skryje widget KPart
          kpart->widget()->hide();
      }
    

    setupGUI() je potřeba volat ještě před tím, než načteme všechny pluginy, jinak by se smixovala menu všech pluginů, které jsme načetli. Dále je potřeba volat hide(), protože addPart() automaticky volá show(), takže bychom jinak skončili s obrazovkou plnou prázdných KParts.

    Metoda pro zobrazení pluginu také bude vypadat jinak:

    void MainWindow::openFilePreview(KUrl url)
    {
      // Odinstaluje menu a toolbar stavajici KPart
      createGUI(0);
     
      QFileInfo finfo(url.url());
      if (finfo.isDir()) return;
    
      QMap<QString,QString> parts;
      parts["txt"] = "katepart";
      parts["gz"] = "ark_part";
      parts["xz"] = "ark_part";
      parts["zip"] = "ark_part";
      parts["rar"] = "ark_parts";
      parts["tar"] = "ark_parts";
      parts["ttf"] = "kfontviewpart";
      parts["patch"] = "komparepart";
      parts["diff"] = "komparepart";
      parts["ui"] = "kuiviewer_part";
      parts["pdf"] = "okular_part";
      parts["png"] = "gvpart";
      parts["jpg"] = "gvpart";
      parts["jpeg"] = "gvpart";
      parts["html"] = "kwebkitpart";
    
      QString partName;
      if (parts.contains(finfo.suffix()))
          partName = parts[finfo.suffix()];
      
      if (partName.isEmpty())
          return;
      
      // Projde vsechny KPart
      for (int i = 0; i < m_manager->parts().size(); i++)
      {
          KParts::ReadOnlyPart *part = static_cast&ly;KParts::ReadOnlyPart*>(m_manager->parts().at(i));
          // Pokusi se najit KPart, jejiz objectName odpovida te hledane
          if (part->objectName() == partName) {
    	// Aktivuje ji
    	m_manager->setActivePart(part);
    	// Odstrani ze splitteru a skryje starou KPart
    	if (m_splitter->count() > 1)
    	    m_splitter->widget(1)->setParent(NULL);
    	// Vlozi so splitteru novou KPart
    	m_splitter->addWidget(part->widget());
    	// Zobrazi ji
    	part->widget()->show();
    	
    	// Nainstaluje jeji menu a toolbary
    	createGUI(part); 
    	setupGUI(ToolBar | Keys | StatusBar);
    
    	// A otevre soubor
    	part->openUrl(url);
          }
      }
    }
    

    Pro zjednodušení jsem vynechal rozlišovaní na RO a RW parts, protože RW stejně nepotřebujeme. Pokud příklad vyzkoušíte, zjistíte, že přepínání mezi soubory je mnohem rychlejší, ale za cenu pomalého startu a vysoké paměťové náročnosti celé aplikace.

    Tvoříme KPart

    Občas se může hodit napsat si vlastní KPart, obvzlášť, když vytvoříte něco většího, co by eventuálně mohlo být zajímavé integrovat do jiných aplikací. My nebudeme tvořit nic velkého, převratného, ani extrémně užitečného. Cílem bude vytvořit KPart, která bude zobrazovat obrázky z XKCD. V článku jsou uvedné jen relevantní části, celý příklad najdete v příložených kódech.

    Každá KPart musí být odvozená od KParts::ReadOnlyPart nebo KParts::ReadWritePart. Kromě toho ale nevyžaduje žádné speciální zacházení, není ani potřeba reimplementovat žádné metody (pokud je nechcete používat):

    xkcd_part.h

    #ifndef PART_H
    #define PART_H
    
    #include <KParts/ReadOnlyPart>
    #include <KAction>
    
    #include <QObject>
    #include <QLabel>
    #include <QWebView>
    #include <QNetworkAccessManager>
    #include <QNetworkReply>
    
    class Part: public KParts::ReadOnlyPart
    {
        Q_OBJECT
        public:
          Part(QWidget *parentWidget, QObject *parent, const QVariantList &args);
          ~Part();
    
        private slots:
          void slotGetPreviousImage();
          void slotGetNextImage();
          void slotGetRandomImage();
          
          void slotPageLoaded(bool ok);
          void slotGotImage(QNetworkReply *reply);
          
          void disableGUI();
          void enableGUI();
          
          
        private:
          QLabel *m_label;
          QWebView *m_webView;
          
          QNetworkAccessManager *m_nam;
          
          KAction *m_previousImageAction;
          KAction *m_randomImageAction;
          KAction *m_nextImageAction;
          
          int m_comixID;
      
    };
    
    #endif // PART_H
    

    Konstruktor přijímá celkem 3 argumenty – prvním je widget, na který se data budou zobrazovat. Pozor, může se jednat o nulový ukazatel. Většinou se to dělá přesně opačně, tedy widget KPart se přiřazuje do centralWidgetu okna, ve kterém se KPart zobrazuje. Druhý je klasický vlastník a třetím argumentem lze z aplikace do KPart předat vlastní argumenty ve formě seznamu QVariant.

    V implementaci třídy není nic zajímavého až na dvě makra, která definují, že se jedná o KDE plugin:

    xkcd_part.cpp

    #include "xkcd_part.h"
    
    #include <KAction>
    ...
    ...
    
    // Vytvori KPluginFactory pro tridu Part
    K_PLUGIN_FACTORY(Factory, registerPlugin<Part>();)
    // Definuje hlavni tridu pluginu
    K_EXPORT_PLUGIN(Factory("xkcd_part", "XKCD Part"))
    
    Part::Part(QWidget *parentWidget, QObject *parent, const QVariantList& args):
            KParts::ReadOnlyPart(parent),
            m_comixID(0)        
    {
        Q_UNUSED(args)
        Q_UNUSED(parentWidget)
    
        // Publikuje informace o umisteni .rc souboru, KAboutData a dalsi informace
        setComponentData(Factory::componentData(), false);
        
        ...
        ...
    
        // Nastavi umisteni rc souboru
        setXMLFile("xkcd_part.rc");
    
        ...
        ...
    }
    ...
    ...
    

    První makro vytvoří KPluginFactory pro hlavní třídu pluginu. Druhé makro nastaví název komponenty a katalogový název (uživatelsky přívětivý) vytvořené factory a exportuje ji jako hlavní třídu pluginu. Alternativní možností je vynechat makro K_PLUGIN_FACTORY a implementovat statickou metodu createAboutData(), která bude vracet instanci třídy KAboutData s podrobnějšími informacemi o pluginu.

    Dále v konstruktoru voláme setXMLFile() s názvem XML souboru, který obsahuje informace o menu a toolbarech. V normální aplikaci by stačilo použít setupGUI, ale protože grafické rozhraní KPart vytváří až aplikace, která ji načítá, nemělo by to teď smysl. Touto metodou jen řekneme, kde se má XML soubor hledat, až o to bude KPart požádána.

    Aby bylo možné KPart načíst, musí existovat .desktop soubor se základními informacemi o KPart:

    xkcd_part.desktop

    [Desktop Entry]
    Icon=images
    Name=XKCD
    Comment=Program for downloading XKCD images
    X-KDE-ServiceTypes=Browser/View
    X-KDE-Library=xkcd_part
    Type=Service
    

    Hodnota X-KDE-Library by měla odpovídat názvu komponenty v makru K_EXPORT_PLUGIN, v každém případě musí odpovídat názvu výsledné knihovny.

    XML soubor s definicí menu a toolbarů je podobný jako u klasické aplikace, akorát místo tagu <gui> se používá <kpartgui<:

    xkcd_part.rc

    <!DOCTYPE kpartgui>
    <kpartgui name="xkcd_part" version="3">
    <MenuBar>
            <Menu name="file">
                    <Action name="previous_xkcd"/>
                    <Action name="random_xkcd"/>
                    <Action name="next_xkcd"/>
            </Menu>
    </MenuBar>
    <ToolBar name="mainToolBar">
            <text>Main Toolbar</text>
            <Action name="previous_xkcd"/>
            <Action name="random_xkcd"/>
            <Action name="next_xkcd"/>
    </ToolBar>
    </kpartgui>
    

    Název souboru nemusí odpovídat žádným konvencím, protože ho definujeme pomocí setXMLFile().

    Aplikace využívající XKCD Part

    Kompletní zdrojové kódy ke všem dnešním ukázkám jsou zde.

    Závěrem

    Pokud budete potřebovat ve své aplikaci zobrazovat třeba PDF soubor, můžete jednoduše využít kvalitní Okular Part. Určitě se jedná o nejlevnější a programátorsky nejméně náročný způsob, jak do aplikace integrovat sofistikovaný nástroj. KParts se navíc budou aktualizovat nezávisle na vaší aplikaci, ale díky tomu, že nemají téměř žádné API, se kterým aplikace pracuje, nehrozí, že by ze dne na den přestala fungovat nebo nešla přeložit.

    V příští části se podíváme, co to je KIO. Ukážeme si, jak si ulehčit přístup ke vzdáleným uložištím nebo emulovat virtuální filesystém pomocí KIO Slaves.

           

    Hodnocení: 100 %

            špatnédobré        

    Nástroje: Tisk bez diskuse

    Tiskni Sdílej: Linkuj Jaggni to Vybrali.sme.sk Google Del.icio.us Facebook

    Komentáře

    Vložit další komentář

    9.2.2011 08:00 petr_p | skóre: 59 | blog: pb
    Rozbalit Rozbalit vše Poněkud loptná práce se soubory
    Žonglování s názvy souborů je standardní způsob v KDE, nebo byl zde použit jen pro přehlednost? (Myslím tím jak service desktop, určení typu souboru, tak určení, která kpart umí, který druh souboru.)
    progdan avatar 9.2.2011 13:24 progdan | skóre: 34 | blog: Archař | Teplice/Brno
    Rozbalit Rozbalit vše Re: Poněkud loptná práce se soubory

    Bohuzel neexistuje moznost jak zjistit, jake typy souboru ktera KPart podporuje. Pristup pouzity v ukazce je jen pro zjednoduseni.

    Na vyssi urovni by se to dalo resit treba pomoci MIME typu: plain/* => kate_part, image/* => gvpart ...

    Collecting data is only the first step toward wisdom, but sharing data is the first step toward the community.
    progdan avatar 9.2.2011 13:26 progdan | skóre: 34 | blog: Archař | Teplice/Brno
    Rozbalit Rozbalit vše Re: Poněkud loptná práce se soubory

    A pokud nechcete pouzivat nejake spesl save() metody, nemusite ani resit, jestli je to ReadOnly nebo ReadWrite a muzete vsude pouzivat ReadOnlyPart.

    Collecting data is only the first step toward wisdom, but sharing data is the first step toward the community.
    9.2.2011 13:35 tm
    Rozbalit Rozbalit vše Re: Poněkud loptná práce se soubory
    Samozrejme že nie, neviem prečo to autor robil tak podivným spôsobom.

    http://techbase.kde.org/Development/Tutorials/Services/Introduction

    Ide o všeobecnejšiu vec, ale KParts sa tým dajú hľadať tiež.
    progdan avatar 9.2.2011 13:47 progdan | skóre: 34 | blog: Archař | Teplice/Brno
    Rozbalit Rozbalit vše Re: Poněkud loptná práce se soubory
    Vida, toto mi uniklo. Dekuji za doplneni.
    Collecting data is only the first step toward wisdom, but sharing data is the first step toward the community.
    Rezza avatar 9.2.2011 22:32 Rezza | skóre: 25 | blog: rezza | Brno
    Rozbalit Rozbalit vše Re: Poněkud loptná práce se soubory
    Pro ukazku je to fakt mozna prehlednejsi, ale zaroven doufam, ze si to nikdo nevezme k srdci :) Trosku jsem se lekl, kdyz jsem to tu videl.
    9.2.2011 20:52 2X4B-523P | skóre: 38 | blog: Zelezo_vs_Debian
    Rozbalit Rozbalit vše Re: KDE pro programátory – KParts
    vypdadl háček hned na začátku (četl jsem od konce): že nemají téměř zádné API

    Založit nové vláknoNahoru

    ISSN 1214-1267   www.czech-server.cz
    © 1999-2015 Nitemedia s. r. o. Všechna práva vyhrazena.