abclinuxu.cz AbcLinuxu.cz itbiz.cz ITBiz.cz HDmag.cz HDmag.cz abcprace.cz AbcPráce.cz
Inzerujte na AbcPráce.cz od 950 Kč
Rozšířené hledání
×
    dnes 18:11 | Nová verze

    Yocto Project byl vydán ve verzi 5.0. Její kódové jméno je Scarthgap. Yocto Project usnadňuje vývoj vestavěných (embedded) linuxových systémů na míru konkrétním zařízením. Cílem projektu je nabídnou vývojářům vše potřebné. Jedná se o projekt Linux Foundation.

    Ladislav Hagara | Komentářů: 0
    dnes 17:56 | Nová verze

    Operační systém 9front, fork operačního systému Plan 9, byl vydán v nové verzi "do not install" (pdf). Více o 9front v FQA.

    Ladislav Hagara | Komentářů: 0
    dnes 13:11 | Nová verze

    Svobodná webová platforma pro sdílení a přehrávání videí PeerTube (Wikipedie) byla vydána v nové verzi 6.1. Přehled novinek i s náhledy v oficiálním oznámení a na GitHubu. Řešeny jsou také 2 bezpečnostní chyby.

    Ladislav Hagara | Komentářů: 3
    dnes 12:33 | Zajímavý software

    Lennart Poettering na Mastodonu představil utilitu run0. Jedná se o alternativu k příkazu sudo založenou na systemd. Bude součástí systemd verze 256.

    Ladislav Hagara | Komentářů: 12
    včera 23:22 | Nová verze

    Hudební přehrávač Amarok byl vydán v nové major verzi 3.0 postavené na Qt5/KDE Frameworks 5. Předchozí verze 2.9.0 vyšla před 6 lety a byla postavená na Qt4. Portace Amaroku na Qt6/KDE Frameworks 6 by měla začít v následujících měsících.

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

    Ubuntu 24.10 bude Oracular Oriole (věštecká žluva).

    Ladislav Hagara | Komentářů: 11
    včera 20:22 | Nová verze

    Byla vydána nová verze 2.45.0 distribuovaného systému správy verzí Git. Přispělo 96 vývojářů, z toho 38 nových. Přehled novinek v příspěvku na blogu GitHubu a v poznámkách k vydání. Vypíchnout lze počáteční podporu repozitářů, ve kterých lze používat SHA-1 i SHA-256.

    Ladislav Hagara | Komentářů: 0
    včera 13:33 | IT novinky

    Před 25 lety, ve čtvrtek 29. dubna 1999, byla spuštěna služba "Úschovna".

    Ladislav Hagara | Komentářů: 0
    včera 01:00 | Nová verze

    Byla vydána nová verze 24.04.28 s kódovým názvem Time After Time svobodného multiplatformního video editoru Shotcut (Wikipedie) a nová verze 7.24.0 souvisejícího frameworku MLT Multimedia Framework. Nejnovější Shotcut je vedle zdrojových kódů k dispozici také ve formátech AppImage, Flatpak a Snap.

    Ladislav Hagara | Komentářů: 0
    28.4. 16:33 | Nová verze Ladislav Hagara | Komentářů: 0
    KDE Plasma 6
     (75%)
     (8%)
     (2%)
     (15%)
    Celkem 887 hlasů
     Komentářů: 4, poslední 6.4. 15:51
    Rozcestník

    plazmový mqtt čudliky na plochu

    30.3.2021 00:41 | Přečteno: 5649× | Výběrový blog | poslední úprava: 31.3.2021 12:38

    sem si začala psát mqtt widget pro plasma/kde5 desktopový prostředí protože žádnej hotovej mqtt widget tam neměli :O :/ eště to neni hotový ale ten stou rsm čtečkou sem taky strká nehotový :D ;D

    POZOR!!!!!!!!!!!!!!!!!!!!!

    momentálně to neni eště uplně vodladěný muže to udělat moc moc špatný věci jako zničit počítač smazat disk nebo popoužití widgetu když si vnoci špatně přikrijete nohy tak vás muže přijít stalman kousnout dopaty :O :O

     


    plazmový čudliky


    Update: konfigurační soubor se nemenuje 'config.xml' ale 'main.xml' :D

    Plazma widgety na plochu kterým voni řikaj 'plasmoidy' se pišou hlavně v nějakejch divnejch qml skriptech který umožňujou používat javascript a c++ s knihovnama qt (tech qt takže to asi jako neni uplně svobodný :O :O vono qt nějak měnilo ty svý licence takže nikdo nasvěte neví který nástroje/knihovny sou svobodný který zdarma který zapeníze a který se nesměj používat vubec :O :O)

    Tendleten čudlikovej widget má c++ backend kterej se do widgetu/plazmoidu dá strčit jako takovej jakože plugin. Na dělaní MQTT to používá cčkovou knihovnu paho vod eclipse hele. Maj tudletu knihovnu pro spousty jinejch jazyků i pro c++ ale ta vobyč cčková má v debianu bullseye rovnou balíček tak sem vzala tu ikdyž to asi jako neni správný c++kový řešení nějaký dělání s vobyč ukazatelama na funkce strukturama nebo polema/ukazatelama misto nějakejch těch jejich std::kontejnerů

    jestli vás někoho jako napadlo proč sem nepoužila *.js knihovičku kterou tam eclipse taky má nóó tak vona boužel v qml nefunguje :O :/ qml umí nějaký jednoduchý websockety ale neštimuje to dosebe s touhletou knihovnou. Další možnost bylo vzit websockety a povidat si nima s nějakým vodděleným server skriptem jak to jako dělá třeba panon widget hele ale toje takový divný ne?? :O :O nóó takže sem to teda jakoby namastila v c++

    Jak si jako udělat c++kovej plugin a registrovat qt/c++ třídu do qml sem vobšlehla tady u nějakýho pana kotelníka hele :D

    adresářová struktura čudliků

    Dohromady sou tam zatim jenom tři c++ třídy nastrkaný ve složce plugin. Singleton/jedináček toho našeho klienta pro dělání mqtt povidání v 'KlientProMQTT.h', třída co dělá jenom že přečte *.txt/*.json a strčí nám ho do qml (qml samo vosobě asi jako neumí číst soubory nadisku :O :O) v 'NacitadloSouboru.h' a pak 'PlasmoidPlugin.h' která dělá že nám ty dvě veci zaregistruje jako datový typy/oběty/elementy a mužem to pak v qml naimportovat jako knihovnu

    Plazmoidy/kde widgety se musej skládat z nějaký složšky do který se dá soubor 'metadata.desktop' a do něj se napišou věci jako jak se ten widget/plazmoid bude menovat kde má skovanej hlavní skriptík 'main.qml' jakou má ikonku a takový věci. vtý složšce s 'metadata.desktop' si vyrobíme další složšku kterou pomenujem 'contents' a vní eště dvě další složsky, 'config' a 'ui'. Ve složšce 'config' si v souboru config.xml main.xml si podle návodu hele nadefinujem proměný jaký si widget/plazmoid umí pamatovat a v souboru config.qml umístění *.qml skriptíky jednotlivejch tabů v nastavování widgetu.

    Ve složšce 'ui' musíme mit někde skovanej 'main.qml' skript kterej je hlavní součástka widgetu do kterýho si pak mužem importovat další voběkty/qml knihovny který mužou bejt skovaný taky v nějakejch svejch dalších složškách. plazmový čudliky maj všecky jednotlivý druhy čudliků v jedný složšce kde má každej druch svou 'třídu'. Je tam taková jakože společná třída 'Cudlik.qml' ze který vostatní čudliky 'děděj'.

    Zatim to umí jenom sedum druhů čudliků:

    složšková/adresářová struktura plazmovejch čudliků je takovádle zatim

    .
    ├── CMakeLists.txt
    ├── package
    │   ├── contents
    │   │   ├── config
    │   │   │   ├── config.qml
    │   │   │   └── main.xml
    │   │   └── ui
    │   │       ├── cudliky
    │   │       │   ├── Cudlik.qml
    │   │       │   ├── Graf.qml
    │   │       │   ├── Kruh.qml
    │   │       │   ├── Moznosti.qml
    │   │       │   ├── Napis.qml
    │   │       │   ├── Prepinadlo.qml
    │   │       │   ├── Soupatko.qml
    │   │       │   └── Tlacitko.qml
    │   │       ├── main.qml
    │   │       └── NastavovaniCudliku.qml
    │   └── metadata.desktop
    └── plugin
        ├── CMakeLists.txt
        ├── KlientProMQTT.cpp
        ├── KlientProMQTT.h
        ├── NacitadloSouboru.cpp
        ├── NacitadloSouboru.h
        ├── PlasmoidPlugin.cpp
        ├── PlasmoidPlugin.h
        └── qmldir
    

    instalace

    má to různý závislosti. pro něco na nějakým novějším debianu s kde založeným doinstalujem všecko důležitý příkazem

    sudo apt install cmake extra-cmake-modules libpaho-mqtt-dev qtdeclarative5-dev libkf5plasma-dev libssl-dev libcjson-dev

    samotnej widget se kompiluje a instaluje tak že se vleze do tý složšky stim prvním CMakeLists.txt souborem a udělá se

    cmake .
    make
    sudo make install
    

    nóó a pak se to voběvuje mezi nainstalovanejma widgetama a mužem si to strčit naplochu ;D

    pokuď si vtom uděláte nějaký změny kdyžuž máte widget puštěnej a přeinstalujete si ho tak pak jakoby musíte zavolat

    plasmashell --replace

    jinak tam zustane ten starej nezmeněnej

    jak si jako nakonfigurovat čudliky

    Konfiguruje se to načtením json kterým se naštelujou přihlašovací údaje barvičky a tak podobně

    každej čudlik tam musí mit vyplněný atributy druh, název, xovou a ipsilonovou souřadnici v gridu/mřížšce, topic.

    nepoviný atributy sou booly jestli muzePublikovat a muzePrijimat, QoS/kvalita služby, retain, jeCelociselny (má pochopytelně smysl jakoby jenom u čudliků co dělaj s číslama :D ;D), šířka a výška v počtu vobsazenejch chlívečků v tý mřížšce do který se budou čudliky strkat, jsonElement pro jakože hóódně primitivní parsování přijímanejch mqtt zpráviček v json formátu a další který mužete vidět v ukázkovým configu :D ;D

    jestli chcete mit víc různejch widgetů protože vám nestačí jeden si musíte pohlídat aby měl jakoby každej jiný id!!!!!! :O :O jinak se budou navzájem vodpojovat :O :O

    {
        "broker":
            {
                "adresa": "tcp://123.456.123.456:1883",
                "id": "widgetNaPlose",
                "uzivatel": "greta",
                "heslo": "1234"
            },
        "grid":
            {
                "sirka": 4,
                "vyska": 9
            },
        "barvy":
            {
                "pozadi": "#901a4314",
                "text": "#efe7bc",
                "aktivni": "#fad02c",
                "kontura": "#333652"
            },
        "cudliky": [
            {
                "druh": "Prepinadlo",
                "nazev": "Čudlík",
                "onHodnota": 1,
                "offHodnota": 0,
                "muzePublikovat": true,
                "muzePrijimat": true,
                "x": 0,
                "y": 0,
                "topic": "nejakej_topic/blablabla1",
                "retain": true,
                "QoS": 2
            },
            {
                "druh": "Prepinadlo",
                "nazev": "Druhej",
                "onHodnota": 1,
                "offHodnota": 0,
                "muzePublikovat": true,
                "muzePrijimat": true,
                "x": 1,
                "y": 0,
                "topic": "nejakej_topic/blablabla2",
                "retain": true,
                "QoS": 2
            },
            {
                "druh": "Prepinadlo",
                "nazev": "Třetí",
                "onHodnota": 1,
                "offHodnota": 0,
                "muzePublikovat": true,
                "muzePrijimat": true,
                "x": 2,
                "y": 0,
                "topic": "nejakej_topic/blablabla3",
                "retain": true,
                "QoS": 2
            },
            {
                "druh": "Prepinadlo",
                "nazev": "Čtvrtý",
                "onHodnota": 1,
                "offHodnota": 0,
                "muzePublikovat": true,
                "muzePrijimat": true,
                "x": 3,
                "y": 0,
                "topic": "nejakej_topic/blablabla4",
                "retain": true,
                "QoS": 2
            },
            {
                "druh": "Kruh",
                "nazev": "CO2 v atmosféře",
                "minHodnota": 123,
                "maxHodnota": 987,
                "muzePublikovat": true,
                "muzePrijimat": true,
                "x": 1,
                "y": 1,
                "sirka": 2,
                "vyska": 2,
                "topic": "nejakej_topic/x",
                "QoS": 0
            },
            {
                "druh": "Soupatko",
                "nazev": "Víkon vysavačů",
                "minHodnota": 0,
                "maxHodnota": 1000,
                "znakyZaHodnotou": "TW",
                "muzePublikovat": true,
                "muzePrijimat": true,
                "x": 0,
                "y": 1,
                "sirka": 1,
                "vyska": 1,
                "topic": "nejakej_topic/blah1",
                "QoS": 0
            },
            {
                "druh": "Soupatko",
                "nazev": "Víkon konvic",
                "minHodnota": 0,
                "maxHodnota": 1000,
                "znakyZaHodnotou": "TW",
                "muzePublikovat": true,
                "muzePrijimat": true,
                "x": 0,
                "y": 2,
                "topic": "nejakej_topic/blah2",
                "QoS": 0
            },
            {
                "druh": "Soupatko",
                "nazev": "Promořování",
                "minHodnota": 1234,
                "maxHodnota": 4321,
                "znakyZaHodnotou": " ☠",
                "muzePublikovat": true,
                "muzePrijimat": true,
                "x": 3,
                "y": 1,
                "topic": "nejakej_topic/promor",
                "QoS": 0
            },
            {
                "druh": "Kruh",
                "nazev": "Promořování",
                "minHodnota": 0,
                "maxHodnota": 4321,
                "znakyZaHodnotou": " ☠",
                "muzePublikovat": false,
                "muzePrijimat": true,
                "x": 3,
                "y": 2,
                "topic": "nejakej_topic/promor",
                "QoS": 0
            },
    
            {
                "druh": "Graf",
                "nazev": "Vysázenejch stromků vlese",
                "muzePublikovat": false,
                "muzePrijimat": true,
                "x": 0,
                "y": 4,
                "sirka": 4,
                "vyska": 2,
                "topic": "nejakej_topic/x",
                "jeCelociselny": false,
                "QoS": 0
            },
            {
                "druh": "Graf",
                "nazev": "Tloušťka ledovcový vrstvy",
                "muzePublikovat": false,
                "muzePrijimat": true,
                "x": 0,
                "y": 7,
                "sirka": 2,
                "vyska": 2,
                "topic": "nejakej_topic/x",
                "jeCelociselny": false,
                "QoS": 0
            },
            {
                "druh": "Napis",
                "nazev": "Kobaltová raketa zaměřená na:",
                "muzePublikovat": false,
                "muzePrijimat": true,
                "maOkraj": false,
                "x": 2,
                "y": 6,
                "sirka":2,
                "vyska": 2,
                "topic": "nejakej_topic/raketa"
            },
            {
                "druh": "Moznosti",
                "nazev": "vybrat cíl",
                "muzePublikovat": true,
                "muzePrijimat": true,
                "x": 2,
                "y": 8,
                "topic": "nejakej_topic/raketa",
                "seznamMoznosti": ["praha", "brno", "brusel"]
            },
            {
                "druh": "Tlacitko",
                "nazev": "Odpálení kobaltový rakety",
                "napis": "Odpálit!!!!",
                "coPosila": "bum!!!!!",
                "muzePublikovat": true,
                "muzePrijimat": false,
                "x": 3,
                "y": 8,
                "topic": "nejakej_topic/raketa"
            }
        ]
    }
    
    

    todo list

    vodkazy na návody/tutoriály užitečný

    https://zren.github.io/kde/docs/widget/

    https://develop.kde.org/docs/plasma/widget/

    https://techbase.kde.org/Development/Tutorials/Plasma5/QML2/GettingStarted

    https://doc.qt.io/qt-5/qtquick-qmlmodule.html

    https://api.kde.org/frameworks-api/frameworks-apidocs/frameworks/kquickcharts/html/index.html

    https://develop.kde.org/docs/plasma/widget/configuration/

    https://github.com/kotelnik/plasma-applet-weather-widget

    zdrojáček

    tady dole a taky tady hele

    plugin/CMakeLists.txt

    set(plasmoidplugin_SRCS
        PlasmoidPlugin.cpp
        KlientProMQTT.cpp
        NacitadloSouboru.cpp
        )
        
    
    set(THREADS_PREFER_PTHREAD_FLAG ON)
    
    find_package(Threads REQUIRED)
    find_package(OpenSSL REQUIRED)
    
    add_library(plasmoidplugin SHARED ${plasmoidplugin_SRCS})
    
    target_compile_features(plasmoidplugin PRIVATE cxx_std_20)
    target_compile_options(plasmoidplugin PRIVATE -fexceptions)
    
    target_include_directories(plasmoidplugin PRIVATE ${OPENSSL_INCLUDE_DIR})
    
    target_link_libraries(plasmoidplugin Qt5::Quick KF5::Plasma paho-mqtt3as cjson ${OPENSSL_LIBRARIES} Threads::Threads)
    
    install(TARGETS plasmoidplugin DESTINATION ${QML_INSTALL_DIR}/org/kde/private/mqttCudliky)
    
    install(FILES qmldir DESTINATION ${QML_INSTALL_DIR}/org/kde/private/mqttCudliky)
    

    plugin/KlientProMQTT.h

    #ifndef KLIENT_PRO_MQTT_H
    #define KLIENT_PRO_MQTT_H
    
    #include <MQTTAsync.h>
    #include <cjson/cJSON.h>
    
    #include <string.h>
    #include <unistd.h>
    
    #include <string>
    #include <map>
    
    #include <qt5/QtCore/QDebug>
    #include <qt5/QtCore/QObject>
    #include <qt5/QtCore/QThread>
    #include <qt5/QtCore/QString>
    #include <qt5/QtQml/QJSEngine>
    #include <qt5/QtQml/QQmlEngine>
    
    #define CEKACI_CAS 10000L
    #define VYCHOZI_QOS 0
    
    //jakej je jako stav připojení  
    enum StavPripojeni { CHYBA, NEPRIPOJENEJ, PRIPOJENEJ, ZAPSANEJ };
    
    // podědíme z 
    class KlientProMQTT : public QThread
    {
        // qt oběkty to tady ve třídě musej mit :O :O
        Q_OBJECT
        
    public:
        
        // jeto singleton/jedináček takže mužem mit jenom jednu instanci třídy vyrobenou
        // skovanou v nějaký statický proměný třídy
        // konstrukor je private a misto něj se volá nějaká statická metoda co vrací tu instanci společnou
        // singleton budem pak registrovat ve třídě 'PlasmoidPlugin' jako qml typ funckí 'qmlRegisterSingletonType'
        // ata chce aby metoda getInstance hamala tydlety ukazatele ;D
        static KlientProMQTT * ziskatInstanci(QQmlEngine * engine,  QJSEngine * scriptEngine);
        
        
        //void poslat(const QString & topic, const QString & zprava, unsigned int qos, bool retained);
        
        //StavPripojeni getStav() const {return stav;}
    
        // destruktor co dělá že uklidí
        ~KlientProMQTT();
        
    signals:
        
        // signály který qt oběkt bude posílat
        // v qml nato sou napojený chytací metody
        // definujem jakoby jenom hlavičky metod žádný tělíčka. všecko co se do tý signal metody narve
        // se pak strčí do argumentu na stejný pozici vtěch qml/js funckí napojenejch
        
        // v c++/qt zdrojáčku se pak před nima musí psát 'Q_EMIT' abyto fungovalo :O :O
        
        // signály co dělaj že předaj klientem chycenou zprávu do qml frontendu
        void zpravaDoFrontendu(const QString & topic, const QString & obsahZpravy);
        void zpravaJsonDoFrontendu(const QString & topic, const QString & obsahZpravy);
        
        // signály který mqtt klient posílá když se vodpojí/připojí/něco se rozbije
        void odpojenej();
        void pripojenej();
        void chyba(QString textChyby = "chyba :D");
        
    public Q_SLOTS:
        
        // funkce co připojujou a vodpojujou k/vod mqtt brokera
        // funkce připojit při úspěchu vrací true a při asi závažnějších chybách blije vyjímky
        bool pripojit();
        void odpojit();
        
        // nastaví atributy m_adresa m_id a tydlety všecky který potřebujem k připojování k brokeroj a vyrobí podle nich 
        // struktury m_connOpts, m_discOpts...... který budem nastrkávat do funckí z knihovničky MQTTAsync.h 
        void nastavit(const QString & adresa, const QString & id, const QString & uzivatel, const QString & heslo);
        
        // nastaví seznam topiců + jejich qos/kvalitu služby z qml/javascriptovejch polí strčenejch sem
        // každej topic by tam měl bejt jenom jednou napsanej
        // nemužem použít QMap nebo nějakej jinej víc chytřejší vobal protože naněco takovýho neumí qml převíst :O :/
        // převody mezi qml a qt/c++ maj popsaný tady hele https://doc.qt.io/qt-5/qtqml-cppintegration-data.html
        void nastavitSeznamTopicu(const std::vector<QString> & topicy, const std::vector<int> & qos);
        
        // pošlem z klienta zprávu
        // žere to jakoby ty qstringy ale ty sou převáděný na vobyč str::stringy uvnitř takže byse dotoho němeli strkat
        // žádný víc speciální znaky protože byje to asi jako nemuselo převíst :O :O
        // mqtt topicy by asi jako taky měli bejt složený jenom s vobyč ascii znáčků si myslim :O :O
        void poslat(const QString & topic, const QString & obsahZpravy, unsigned int qos = VYCHOZI_QOS, bool retained = false);
        
        // odpojí klienta nastaví adresu id etc + topicy/qos a zkusí znova udělat připojení
        void reset(const QString & adresa, const QString & id, const QString & uzivatel, const QString & heslo, const std::vector<QString> & topicy, const std::vector<int> & qos);
        
        // metoda na přešmiknutí vlákna
        // zavolá requestInterruption() a počká na ukončení 
        void stop();
        
        // metoda co řiká jestli je mqtt klient připojenej
        bool jePripojenej() const {return (bool)MQTTAsync_isConnected(m_klient);}
        
        // jestli vlákno běží
        bool bezi() const {return isRunning();}
        
    private:
        
        // tajenj privátní konstruktor takže muže bejt zavolanej jenom z nějaký jiný metody týdletý třídy
        // singleton se nám vyrábí jenom  v metodě 'ziskatInstanci'
        explicit KlientProMQTT(QObject * parent = nullptr);
        
        // tady je skovaná ta jediná instance týdletý třídy
        static KlientProMQTT * instance;
    
        // metoda na zapsání k topicu 
        // před zapsáním nejdřiv musíme bejt připojený k brokeroj bezchybně
        void subscribe();
        
        // vypuštění vlákna
        // jenom se tam furt hlídá jestli je přiojenej/nepřipojenej
        // jedinej důvod proč misto vobyčejnýho qoběktu s callbackama je použitý vlákno jeto že když klient klient jednou ztratí spojení
        // a připojí se znova tak už to pak nechtělo dělat 'onConnect' callback takže nebylo možný z c++/qt říct qml/gui že neni připojenej
        // artelnativní řešení by asi jako mohlo bejt mit v main.qml nějakej časovač co by furt koukal jestli je klinet připojenej :O :O
        // možná tam jakoby maj voni nějakou chybku nevim :O :O
        void run() override;
        
        StavPripojeni stav;
        
        // přihlašovací údaje/data pro mqtt brokera
        std::string m_adresa;
        std::string m_id;
        std::string m_uzivatel;
        std::string m_heslo;
        
        // ke kolika topiců se chcem zapsat a seznam jejich názvů + QoS(kvalita služby)
        // mqtt vobyč cčková knihova chce vobyč starý cčkový pole/ukazate navstup
        size_t m_pocetTopicu;
        char ** m_nazvyTopicu;
        int * m_QoSsTopicu;
        
        // mqttasync.h knihovnou vyrobenej klient
        // s nim pracujou všecky ty funkce ztý knihovy
        MQTTAsync m_klient;
        
        // různý struktury nastavovací při připojování/vodpojování m_klienta
        // strkaj se do nich různý parametry + věčinou dvojice ukazatelů na funcke který sou pak
        // zavolaný jako callbacky potom cose to povede/nepovede udělat
        
        // připojovací
        MQTTAsync_connectOptions m_connOpts;
        
        // vodpojovací
        MQTTAsync_disconnectOptions m_discOpts;
        
        //na posílání zpráv
        MQTTAsync_responseOptions m_sendRespOpts;
        
        // subscribovací/na zapisování do topiců
        MQTTAsync_responseOptions m_subscribeRespOpts;
        
        // a tady sou ty různý callbacky jako statický metody
        // vobyčejný metody voběktu by to neumělo zhamat protože ty maj v c++ prej
        // jako takovej první neviditelnej argument ukazatel na sám sebe voběkt nebo takovýho něco
        // context je vodkaz na mqtt klienta připojenýho kterýho si musíme přetypovávat z void když ho třeba potřebujem
        
        // callback při vodpojení úspěch/neůspěch
        static void onDisconnect(void * context, MQTTAsync_successData * odpoved);
        static void onDisconnectFail(void * context, MQTTAsync_failureData * odpoved);
        
        // callbacky pro zapisování k topicům
        static void onSubscribe(void * context, MQTTAsync_successData * odpoved);
        static void onSubscribeFail(void * context, MQTTAsync_failureData * odpoved);
        
        // připojování
        // onConnect callbacky nejsou volaný při automatickým znovupřipojení klienta
        static void onConnect(void * context, MQTTAsync_successData * odpoved);
        static void onConnectFail(void * context, MQTTAsync_failureData * odpoved);
        
        // callbacky pro posílání zpráviček klientem
        static void onSend(void * context, MQTTAsync_successData * odpoved);
        static void onSendFail(void * context, MQTTAsync_failureData * odpoved);
    
        // při doručení zprávy
        static void onDeliver(void * context, MQTTAsync_token token);
        
        // ztráta spojení
        static void onConnLost(void * context, char * duvod);
        
        // při přijetí zprávy
        // pozor je tam hulvátstyle kontrola jestli je zpráva string/řetězec ve formátu json že
        // se kouká na první znak jestli toje složená závorka '{'
        static int onMessage(void * context, char * topicNazevStr, int topicStrZnaku, MQTTAsync_message * zprava);
        
        
    };
    
    
    
    #endif
    

    plugin/KlientProMQTT.cpp

    #include "KlientProMQTT.h"
    
    using namespace std;
    
    KlientProMQTT * KlientProMQTT::instance = nullptr;
    
    KlientProMQTT * KlientProMQTT::ziskatInstanci(QQmlEngine * engine, QJSEngine * scriptEngine)
    {
        Q_UNUSED(engine);
        Q_UNUSED(scriptEngine);
        
        if(KlientProMQTT::instance == nullptr)
        {
            KlientProMQTT::instance = new KlientProMQTT();
        }
        
        return KlientProMQTT::instance;
    }
    
    // konstrukotr skoro nic nedělá
    // všecko bude nastavovaný jinejma metodama
    KlientProMQTT::KlientProMQTT(QObject * parent) : QThread(parent), stav(NEPRIPOJENEJ), m_nazvyTopicu(nullptr), m_QoSsTopicu(nullptr)
    {
    }
    
    // metoda stop poprosí vlákno vo to aby se jakože přešmiklo a počká
    void KlientProMQTT::stop()
    {
        requestInterruption();
        wait();
    }
    
    
    // run se zkusí připojit a pak furt vesmyčce kouká jestli neni znova připojenej
    void KlientProMQTT::run()
    {
        if(!pripojit())
        {
            qDebug()<<"nepovedlo se pripojit klienta";
            return;
        }
        while(!isInterruptionRequested())
        {
    
            usleep(CEKACI_CAS);
            
            if(stav == NEPRIPOJENEJ && jePripojenej())
            {
                stav = PRIPOJENEJ;
                Q_EMIT pripojenej();
            }
        }
        // když bylo vlákno přešmiknutý tak zkusíme vodpojit klienta
        // jestli je připojenej si metoda vodpojit hlídá sama
        odpojit();
        
        // qt::debugovací výstup
        qDebug()<<"mqtt client konci!!!!!!!!!";
    }
    
    // nastavování údajů na připojování k brokeroj
    void KlientProMQTT::nastavit(const QString & adresa, const QString & id, const QString & uzivatel, const QString & heslo)
    {
        // musíme převíst qstringy na vobyč std::stringy 
        // divný/neascii znkay se asi jako ztratěj tak pozor jako :O :O
        m_adresa = adresa.toStdString();
        m_id = id.toStdString();
        m_uzivatel = uzivatel.toStdString();
        m_heslo = heslo.toStdString();
        
        // inicianiluzujeme si ty struktury pro připojování/vodpojování/etc... výhozíma hodnotama
        m_connOpts = MQTTAsync_connectOptions_initializer;
        m_discOpts = MQTTAsync_disconnectOptions_initializer;
        m_sendRespOpts = MQTTAsync_responseOptions_initializer;
        m_subscribeRespOpts = MQTTAsync_responseOptions_initializer;
        
        // noa ty výhozí hodnoty jakože teťko přepišem nějakejma svejma kde potřebujem změnit
        
        // maximální možnej čas v sekundách kterej muže utýct vod posledního komunikování klienta s mqtt brokerem
        // když upline tak se pošle jakoby takovej 'ping' aby si navzájem řekli že sou voba eště naživu :O :O
        m_connOpts.keepAliveInterval = 20;
        
        // když máme zapnutý automatický znovupřipojování tak neni prej dobrý mit zapnutý promazávání session cache
        m_connOpts.cleansession = 0;
        
        //callbacky
        m_connOpts.onSuccess = KlientProMQTT::onConnect;
        m_connOpts.onFailure = KlientProMQTT::onConnectFail;
        
        // uživatel a heslo
        m_connOpts.username = m_uzivatel.c_str();
        m_connOpts.password = m_heslo.c_str();
        
        // zapnem automatický znovupřipojování a nastavíme znovupřipojovací interval ve kterým to jakoby tamto 
        // znovupřipojení zkouší třeba vod jedný do tří vteřin
        m_connOpts.automaticReconnect = 1;
        m_connOpts.minRetryInterval = 1;
        m_connOpts.maxRetryInterval = 3;
       
        // u vostatních struktur callbacky
        m_subscribeRespOpts.onSuccess = KlientProMQTT::onSubscribe;
        m_subscribeRespOpts.onFailure = KlientProMQTT::onSubscribeFail;
        
        m_sendRespOpts.onSuccess = KlientProMQTT::onSend;
        m_sendRespOpts.onFailure = KlientProMQTT::onSendFail;
        
        m_discOpts.onSuccess = KlientProMQTT::onDisconnect;
        m_discOpts.onFailure = KlientProMQTT::onDisconnectFail;
        
        // všecky tydlety struktury maj v sobě skovanej context/m_klienta
        // ho tam šoupnem až si ho v metodě připojit() vyrobíme ;D
    }
    
    // převedem vectory topiců/qos na ty ukazatelový pole. nejde to udělat nějak víc líp????? :O :O
    // předpokádaj se stejně dlouhatánský pole aže se topicy nebudou vopakovat (to se hlídá v main.qml )
    // neví někdo jestli de nějak v c++20 udělat todleto hele https://www.cplusplus.com/forum/general/228918/ :O :O :O :O
    void KlientProMQTT::nastavitSeznamTopicu(const std::vector<QString> & topicy, const std::vector<int> & qos)
    {
        if(topicy.size() != qos.size())
            throw runtime_error("neco je v qml moc spatne protoze do metody \'nastavitSeznamTopicu\' sou strceny vektory o ruzny dylce :O :O");
    
        if(topicy.size() == 0)
            qDebug()<<"do metody \'nastavitSeznamTopicu\' se strkaj vectory o nulovy dylce :O :O";
        
        
        if(m_nazvyTopicu != nullptr)
            delete [] m_nazvyTopicu;
        if(m_QoSsTopicu != nullptr)
            delete [] m_QoSsTopicu;
        
        m_pocetTopicu = topicy.size();
        m_nazvyTopicu = new char * [m_pocetTopicu];
        m_QoSsTopicu = new int [m_pocetTopicu];
        for(size_t i = 0; i < m_pocetTopicu; i++)
        {
            m_nazvyTopicu[i] = strdup(topicy[i].toStdString().c_str());
            m_QoSsTopicu[i] = qos[i];
            qDebug()<<"klient se bude chtit pripojovat k topicu \'"+QString(m_nazvyTopicu[i])+"\' s QoS == "<<m_QoSsTopicu[i];
        }
    }
    
    
    bool KlientProMQTT::pripojit()
    {
        // návratovej chybvoej kód když se něco nepovede
        // mužem si pak dycky najít v hlavičkovým souboru 'MQTTAsync.h' tý paho knihovničky cože
        // to jako znamená tadleta chyba
        int rc; 
        
        // vyrobíme m_klienta 
        if ((rc = MQTTAsync_create(&m_klient, m_adresa.c_str(), m_id.c_str(), MQTTCLIENT_PERSISTENCE_NONE, nullptr))!= MQTTASYNC_SUCCESS)
        {
            string err = "nepodarilo se vyrobit MQTTAsync klienta!!!!!!!!!!!!\nnavratovej chybovej kod: ";
            err += to_string(rc);
            throw runtime_error(err);
        }
    
        if ((rc = MQTTAsync_setCallbacks(m_klient, m_klient, onConnLost, onMessage, onDeliver)) != MQTTASYNC_SUCCESS)
        {
            string err = "nepodarilo se klientoj nastavit callbacky!!!!!!!!!!!!\nnavratovej chybovej kod: ";
            err += to_string(rc);
            throw runtime_error(err);
        }
        
        // vyrobenýho klienta jakoby nastrkáme do těch nastavovacích struktur
        m_connOpts.context = m_klient;
        m_subscribeRespOpts.context = m_klient;
        m_sendRespOpts.context = m_klient;
        m_discOpts.context = m_klient;
        
        if((rc = MQTTAsync_connect(m_klient, &m_connOpts)) != MQTTASYNC_SUCCESS)
        {
            QString err = "nepodarilo se pripojit klienta!!!!!!!!!!!! navratovej chybovej kod: " + QString::number(rc);
            qDebug()<<err;
            Q_EMIT chyba("nepodarilo se pripojit klienta!!!!\nmrkni na prihlasovaci udaje");
            return false;
        }
    
        while(stav == NEPRIPOJENEJ)
            usleep(CEKACI_CAS);
        
        if(stav == CHYBA)
        {        
            QString err = "nepodarilo se subscribnout klienta!!!!!!";
            qDebug()<<err;
            Q_EMIT chyba(err);
            return false;
        }
        
        return true;
        
    }
    
    void KlientProMQTT::odpojit()
    {
        // když neni připojenej tak ho nemužem začít vodpojovat
        // mqttasync.h nato nadává 
        if(!jePripojenej())
             return;
        int rc;
        if ((rc = MQTTAsync_disconnect(m_klient, &m_discOpts)) != MQTTASYNC_SUCCESS)
        {
            string err = "nepodarilo se zacit vodpojovani klienta!!!!!!!!!!!!\nnavratovej chybovej kod: " + to_string(rc);
            throw runtime_error(err);
        }
        // budem čekat než to jakoby nějak dopadne :D
        while (stav == PRIPOJENEJ && stav != CHYBA)
            usleep(CEKACI_CAS);
        
        // když to skončí chybou tak máme nějakej problémek kterej tady asi jako nevyřešíme
        if(stav == CHYBA)
        {        
            string err = "nepodarilo se vodpojit klienta!!!!!!!!!!!!";
            throw runtime_error(err);
        }
    }
    
    void KlientProMQTT::subscribe()
    {
        if( stav != PRIPOJENEJ)
        {
            string err = "klient musi bejt pred subscribnutim pripojenej!!!!";
            throw runtime_error(err);
        }
        int rc;
        if ((rc = MQTTAsync_subscribeMany(m_klient, m_pocetTopicu, m_nazvyTopicu, m_QoSsTopicu, &m_subscribeRespOpts)) != MQTTASYNC_SUCCESS)
        {
            string err = "nepodarilo se zacit subscribovat klienta!!!!!!!!!!!!\nnavratovej chybovej kod: " + to_string(rc);
            throw runtime_error(err);
        }
    }
    
    void KlientProMQTT::poslat(const QString & topic, const QString & zprava, unsigned int qos, bool retained)
    {
        // když neni klient připojenej nic se nebude posílat
        // posílání zpráviček z vodpojenýho klienta má jakoby zabránit zamikání čudliků v gui dycky když je klient vodpojenej
        if(!jePripojenej())
        {
            qDebug()<<"klient neni pripojenej takze se nic nebude posilat";
            return;
        }
        
        string zpravaStdstr = zprava.toStdString();
            
        MQTTAsync_message msg = MQTTAsync_message_initializer;
        msg.payload = (void *)zpravaStdstr.c_str();
        msg.payloadlen = zpravaStdstr.length();
        msg.qos = qos;
        msg.retained = int(retained);
            
        int rc;
        if ((rc = MQTTAsync_sendMessage(m_klient, topic.toStdString().c_str(), &msg, &m_sendRespOpts)) != MQTTASYNC_SUCCESS)
        {
            string err = "nepodarilo se poslat str zpravu!!!!!!!!!!!!\nnavratovej chybovej kod: " + to_string(rc);
            throw runtime_error(err);
        }
    }
    
    // vodpojíme nastavíme a zkusíme znova připojit
    void KlientProMQTT::reset(const QString & adresa, const QString & id, const QString & uzivatel, const QString & heslo, const std::vector<QString> & topicy, const std::vector<int> & qos)
    {
        odpojit();
        
        if(m_klient != nullptr)
            MQTTAsync_destroy(&m_klient);
        
        nastavit(adresa, id, uzivatel, heslo);
        nastavitSeznamTopicu(topicy, qos);
        
        stav = NEPRIPOJENEJ;
        pripojit();
    }
    
    
    //callbacky
    
    void KlientProMQTT::onDisconnect(void * context, MQTTAsync_successData * odpoved)
    {
        (void)context;
        (void)odpoved;
        instance->stav = NEPRIPOJENEJ;
        Q_EMIT instance->odpojenej();
        qDebug()<<"uspesne odpojeni"<<Qt::endl;
    }
        
    void KlientProMQTT::onDisconnectFail(void * context, MQTTAsync_failureData * odpoved)
    {
        (void)context;
        instance->stav = CHYBA;
        Q_EMIT instance->chyba("neuspesne vodpojeni");
        qDebug()<<"neuspesne vodpojeni "<<Qt::endl<<"chybovy kod: "<<odpoved->code<<Qt::endl;
    }
        
    void KlientProMQTT::onSubscribe(void * context, MQTTAsync_successData * odpoved)
    {
        (void)context;
        (void)odpoved;
        instance->stav = ZAPSANEJ;
        qDebug()<<"uspesne zapsani k topicu"<<Qt::endl;
    }
        
    void KlientProMQTT::onSubscribeFail(void * context, MQTTAsync_failureData * odpoved)
    {
        (void)context;
        instance->stav = CHYBA;
        Q_EMIT instance->chyba("neuspesne zpasani k topicu");
        qDebug()<<"neuspesne zpasani k topicu"<<Qt::endl<<"chybovy kod: "<<odpoved->code<<Qt::endl;
    }
        
    void KlientProMQTT::onConnect(void * context, MQTTAsync_successData * odpoved)
    {
        (void)context;
        (void)odpoved;
        qDebug()<<"uspesne pripojeno"<<Qt::endl;
        instance->stav = PRIPOJENEJ;
        Q_EMIT instance->pripojenej();
        instance->subscribe();
    }
        
    void KlientProMQTT::onConnectFail(void * context, MQTTAsync_failureData * odpoved)
    {
        (void)context;
        qDebug()<<"neslo pripojit"<<Qt::endl<<"chybovy kod: "<<odpoved->code<<Qt::endl;
        instance->stav = CHYBA;
        Q_EMIT instance->chyba("neslo pripojit");
    }
        
    void KlientProMQTT::onSend(void * context, MQTTAsync_successData * odpoved)
    {
        (void)context;
        (void)odpoved;
        qDebug()<<"poslalo se"<<Qt::endl;
    }
        
    void KlientProMQTT::onSendFail(void * context, MQTTAsync_failureData * odpoved)
    {
        (void)context;
        qDebug()<<"nepodarilo se odeslat ZPRAVU"<<Qt::endl<<"chybovy kod: "<<odpoved->code<<Qt::endl;
        qDebug()<<"klient se tedko pokusi vodpojit";
        Q_EMIT instance->chyba("neslo poslat zpravu");
        instance->odpojit();
    }
    
    void KlientProMQTT::onDeliver(void * context, MQTTAsync_token token)
    {
        (void)context;
        qDebug()<<"doruceni zpravy potvrzeno"<<Qt::endl<<"token: "<<token<<Qt::endl<<Qt::endl;
    }
        
    void KlientProMQTT::onConnLost(void * context, char * duvod)
    {
        (void)context;
        instance->stav = NEPRIPOJENEJ;
        Q_EMIT instance->odpojenej();
        qDebug()<<"spojeni ztraceno";
        if(duvod != nullptr)
            qDebug()<<"duvod odpojeni: "<<duvod;
    }
        
    //vrací jedničku když zprávu správně přijmem jinak nám ji to zkusí znova strčit
    int KlientProMQTT::onMessage(void * context, char * topicNazevStr, int topicStrZnaku, MQTTAsync_message * zprava)
    {
        (void)context;
        (void)topicStrZnaku;
                
        if(zprava->payloadlen > 0)
        {
            qDebug()<<"prijata zprava do topicu \'" + QString(topicNazevStr) +"\' s vobsahem:";
            qDebug()<<QString::fromLocal8Bit((char *)zprava->payload);
            
            QString topicQstr = QString::fromLocal8Bit(topicNazevStr), zpravaQstr = QString::fromLocal8Bit((char *)zprava->payload);
                    
            if( ((char *)zprava->payload)[0] == '{' )
            {
                cJSON * jsonZprava = cJSON_Parse((char*)zprava->payload);
                if (jsonZprava != nullptr)
                {
                    //zprava asi jako bude ve formatu json
                    cJSON_Delete(jsonZprava);
                            
                    Q_EMIT instance->zpravaJsonDoFrontendu(topicQstr, zpravaQstr);
                            
                    MQTTAsync_freeMessage(&zprava);
                    MQTTAsync_free(topicNazevStr);
                    return 1;
                }
            }
                    
            Q_EMIT instance->zpravaDoFrontendu(topicQstr, zpravaQstr);
        }
        else
            qDebug()<<"prijata prazdna zprava :O :O";
                
        MQTTAsync_freeMessage(&zprava);
        MQTTAsync_free(topicNazevStr);
        return 1;
    }
        
        
    // destruktor co dělá že uklidí
    KlientProMQTT::~KlientProMQTT()
    {
        if(jePripojenej())
            odpojit();
        
        if(m_klient != nullptr)
            MQTTAsync_destroy(&m_klient);
        
        delete [] this->m_nazvyTopicu;
        delete [] this->m_QoSsTopicu;
    }
    

    plugin/NacitadloSouboru.h

    #ifndef NACITADLO_SOUBORU_H
    #define NACITADLO_SOUBORU_H
    
    #include <qt5/QtCore/QObject>
    #include <qt5/QtCore/QUrl>
    #include <qt5/QtCore/QFile>
    #include <qt5/QtCore/QDebug>
    
    class NacitadloSouboru : public QObject
    {
        Q_OBJECT
        
    public:
        
        explicit NacitadloSouboru(QObject * parent = nullptr) : QObject(parent){}
        ~NacitadloSouboru(){}
        
        Q_SLOT QString nacistSoubor(const QUrl & cesta);
    };
    
    
    #endif
    

    plugin/NacitadloSouboru.cpp

    #include "NacitadloSouboru.h"
    
    #include <stdio.h>
    #include <stdlib.h>
    
    QString NacitadloSouboru::nacistSoubor(const QUrl & cesta)
    {    
            QFile soubor(cesta.toLocalFile());
            
            if(!soubor.open(QFile::ReadOnly | QFile::Text))
                return "neslo otevrit!!!!!!!!!!";
            else
                return soubor.readAll();
            
            
    }
    

    plugin/PlasmoidPlugin.h

    #ifndef PLASMOIDPLUGIN_H
    #define PLASMOIDPLUGIN_H
    
    #include <QQmlExtensionPlugin>
    
    class QQmlEngine;
    class PlasmoidPlugin : public QQmlExtensionPlugin
    {
        Q_OBJECT
        Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QQmlExtensionInterface")
    
    public:
        void registerTypes(const char *uri) override;
    };
    
    #endif // PLASMOIDPLUGIN_H
    

    plugin/PlasmoidPlugin.cpp

    #include "PlasmoidPlugin.h"
    #include "KlientProMQTT.h"
    #include "NacitadloSouboru.h"
    
    #include <QtQml>
    #include <QDebug>
    
    void PlasmoidPlugin::registerTypes(const char *uri)
    {
        Q_ASSERT(uri == QLatin1String("org.kde.private.mqttCudliky"));
        
        qmlRegisterSingletonType<KlientProMQTT>(uri, 1, 0, "Klient", KlientProMQTT::ziskatInstanci);
        qmlRegisterType<NacitadloSouboru>(uri, 1, 0, "Nacitadlo");
    }
    

    plugin/qmldir

    module org.kde.private.mqttCudliky
    
    plugin plasmoidplugin
    

    package/metadata.desktop

    [Desktop Entry]
    Name=mqttCudliky
    Comment=Nejvíc nejkrásnější mqtt widget
    
    Type=Service
    X-KDE-ParentApp=
    X-KDE-PluginInfo-Author=gréta
    X-KDE-PluginInfo-Email=gretulililinka@protonmail.com
    X-KDE-PluginInfo-License=nevim jak to vomezuje licence qt :D
    X-KDE-PluginInfo-Name=org.kde.mqttCudliky
    X-KDE-PluginInfo-Version=1.0
    X-KDE-PluginInfo-Website=www.replace.com
    X-KDE-ServiceTypes=Plasma/Applet
    X-Plasma-NotificationArea=true
    X-Plasma-API=declarativeappletscript
    X-Plasma-MainScript=ui/main.qml
    X-Plasma-RemoteLocation=
    X-KDE-PluginInfo-Category=Environment and Weather
    Icon=preferences-system-network-sharing
    

    package/contents/config/config.qml

    //tady sou definovaný taby v konfiguraci widgetu naploše
    import QtQuick 2.0
    
    import org.kde.plasma.configuration 2.0 as PlasmaConfig
    
    PlasmaConfig.ConfigModel
    {
        PlasmaConfig.ConfigCategory
        {
            name: i18n('Nastavování čudliků')
            icon: 'preferences-desktop-plasma'
            source: 'NastavovaniCudliku.qml'
        }
    
    }
    
     
    

    package/contents/config/main.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <kcfg xmlns="http://www.kde.org/standards/kcfg/1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.kde.org/standards/kcfg/1.0 http://www.kde.org/standards/kcfg/1.0/kcfg.xsd">
        <kcfgfile name=""/>
    
        <group name="General">
            <entry name="adresa" type="String">
                <default></default>
            </entry>
            <entry name="id" type="String">
                <default></default>
            </entry>
            <entry name="uzivatel" type="String">
                <default></default>
            </entry>
            <entry name="heslo" type="String">
                <default></default>
            </entry>
        </group>
        <group name="Cudliky">
            <entry name="konfiguracniJson" type="String">
                <default>
    
                </default>
            </entry>
        </group>
    </kcfg>
    

    package/contents/ui/main.qml

    import QtQuick 2.9
    import QtQuick.Window 2.2
    import QtQuick.Controls 2.5
    import QtQuick.Layouts 1.11
    
    //import org.kde.quickcharts 1.0 as Charts
    import org.kde.plasma.core 2.0 as PlasmaCore
    import org.kde.plasma.plasmoid 2.0
    import org.kde.plasma.components 3.0 as PlasmaComponents
    
    // naimportujem si všecky voběkty ze složšky 'cudliky'
    import "./cudliky"
    
    // taky si naimportujem náš c++/qt plugin
    import org.kde.private.mqttCudliky 1.0
    
    //chceme takovej ten velkej widget naplochu
    Item
    {
        // podporujem jenom velkej widget strčenej naplochu
        Plasmoid.preferredRepresentation: Plasmoid.fullRepresentation
        
        Plasmoid.fullRepresentation: Item
        {
            id: main
            
            // minimální šířka/vejška widgetu pole počtu čudliků
            Layout.minimumWidth: (velikostMezer + 64) * main.sloupcu * PlasmaCore.Units.devicePixelRatio
            Layout.minimumHeight: (velikostMezer + 64) * main.radku * PlasmaCore.Units.devicePixelRatio
            
            // počet sloupců a řádků grid/mřížškovýho layoutu/rozložení čudliků
            // čudliky se budou strkat dotoho elmentu grid
            property alias radku: grid.rows
            property alias sloupcu: grid.columns
            
            // velikost mezer mezi čudlikama v pixelech
            property int velikostMezer: 2
            
            // různý pole který držej referenci na voběkty čudliků
            
            // uplně všecky čudliky
            property var vseckyCudliky: []
            
            // čudliky podle jednotlivejch topiců
            // key/klíč pole sou názvy topiců
            property var cudlikyPodleTopicu: []
            
            // taky čudliky podle topiců ale takový co dělaj že chtěj psaníčko v *.json formátu :D ;D
            property var jsonCudlikyPodleTopicu: []
            
            // seznam jenom těch čudliků co uměj publikovat
            // potřebujem znát nato abysme je mohli dycky všecky zamknout když mqtt klient ztratí spojení s brokerem
            property var publikovaciCudliky: []
            
            
            // 'sada' všech topiců s nejvíc nejvěčím QoS jako hodnotou
            // potřebujem ji mit jako vobyč array/pole abysme ji mohli strčit do qt/c++
            // v seznamTopicu by měli bejt jenom stringy a v qos zase samý int
            // ( de ňák v js hezky rozlousknout pole na dvě různý žeby v jednom byly keys a vdruhým values?????? nějakej takovej vopak zip :O :O )
            property var seznamTopicu: []
            property var seznamTopicuQoS: []
            
            // výchozí barvy když nejsou definovaný v konfigu
            property color barvaTextu: 'black'
            property color barvaAktivni: 'red'
            property color barvaKontury: 'green'
            property color barvaPozadi: 'white'
            
            // načtem ůdaje o brokeroj/přihlašovací ůdaje z konfigu
            // mužou bejt i undefined/nedefinovaný to se pak hlídá dál aby se nezačalo připojovat
            property string adresa: plasmoid.configuration.adresa
            property string id: plasmoid.configuration.id
            property string uzivatel: plasmoid.configuration.uzivatel
            property string heslo: plasmoid.configuration.heslo
            
            // výchozí konfigurační string pro případ že neni žádnej uloženej v konfigu
            
            // normálně by asi jako měla fungovat hodnota strčená mezi <default></default> tagy v 
            // main.xml ale ňák ji to nechtělo načítat :O :/
            // možná to neumí zhamat *.json možná dělaj problémy uvozovky možná to nefunguje
            // jenom v tom testovacím plasmoidviewer vokýnku. nevim :O :/
            
            property string jsonString: 
            '{
    
            "grid":
                {
                    "sirka": 1,
                    "vyska": 1
                },
            "barvy":
                {
                    "pozadi": "#0f808080",
                    "text": "#d3d3d3",
                    "aktivni": "#00ffff",
                    "kontura": "#191919"
                },
            "cudliky": [
                {
                    "druh": "Moznosti",
                    "nazev": "čudlík",
                    "muzePublikovat": false,
                    "muzePrijimat": false,
                    "x": 0,
                    "y": 0,
                    "topic": "nejaky_topic",
                    "seznamMoznosti": ["vychozi nastaveni cudliku"]
                }
                ]
            }'
    
            // funcke co dělá že veme json a podle něj vyrobí všecky čudliky
            // nastaví barvičky/velikost mřížšky a takový tydlety
            // taky nám naplní všecky ty pole čudliků
            function jsonNaElementy(json)
            {
    
                // nastavení počtu řádků/sloupců mřížšky
                main.sloupcu = json.grid.sirka;
                main.radku = json.grid.vyska;
                
                // jestli jsou v json barvičky tak nastavíme barvičky :D ;D
                if(json.hasOwnProperty('barvy'))
                {
                    barvaAktivni = json.barvy.aktivni;
                    barvaTextu = json.barvy.text;
                    barvaPozadi = json.barvy.pozadi;
                    barvaKontury = json.barvy.kontura;
                }
                
                // noa teďko projdem všecky čudliky v json a zkusíme je dynamicky vyrobit a nastrkat do tý mřížšky
                for(var i in json.cudliky)
                {
                    // vezmem si z json další json samotnýho jednoho čudlika
                    var cudlikJson = json.cudliky[i];
                    
                    // id našeho čudliku vyrobenýho
                    // nějaký id asi musíme vyplnit jinak nemá nějakej víc věčí význam
                    var id = 'cudlik_' + i;
    
                    // čudlik budem vyrábět funkcí 'createQmlObject' která má navstupu string kterej vobsahuje zdrojáček qml elementu
                    // náš string začnem importem
                    var obektStr = 'import "./cudliky";';
                    obektStr += cudlikJson.druh + '{';
                    
                    // jestli muže čudlik publikovat tak taky musí mit možnost posílat publikovací signál dalším qt/qml elementům
                    // bude posílat signál s topicem a nějakou tamtou zprávou
                    if(cudlikJson.muzePublikovat)
                    {
                        obektStr += 'signal zpravaOdCudliku(string topic, string zprava);';
                    }
                    obektStr += '}';
                    
                    // vyrobíme si čudlik strčíme ho do gridu a nastavíme mu nějaký id
                    var cudlik = Qt.createQmlObject(obektStr, grid, id);
                    
                    // další atributy čudliku nastavíme jako atributy javascriptovýho voběktu
                    
                    // méno a topic ke kterýmu je připojenej
                    cudlik.nazev = cudlikJson.nazev;
                    cudlik.mqttTopic = cudlikJson.topic;
                    
                    // čudlik bude v mřížšce vyplňovat všecky přidělený chlívečky
                    cudlik.Layout.fillHeight = true;
                    cudlik.Layout.fillWidth = true;
                    
                    // nastavíme pozici v mřížšce/gridu
                    cudlik.Layout.column = cudlikJson.x;
                    cudlik.Layout.row = cudlikJson.y;
                    
                    // jestli má čudlik v json nastavenou nějakou šířku/výšku teda jakože kolik
                    // chlívečků mřížky má našířku/navejšku tak nastavíme
                    if(cudlikJson.hasOwnProperty('sirka'))
                        cudlik.Layout.columnSpan = cudlikJson.sirka;
                    if(cudlikJson.hasOwnProperty('vyska'))
                        cudlik.Layout.rowSpan = cudlikJson.vyska;
                    
                    // vobarvení čudliku
                    // jinak má svý nějaký výchozí barvičky
                    cudlik.barvaAktivni = barvaAktivni;
                    cudlik.barvaTextu = barvaTextu;
                    cudlik.barvaPozadi = barvaPozadi;
                    cudlik.barvaKontury = barvaKontury;
                    
                    // jestli čudlik muže publikovat tak mu nastavíme QoS/kvalitu služby posílací parametr + retain 
                    // a taky napojíme jeho signál 'zpravaOdCudliku' na funkci 'zpravaCudliku'
                    if(cudlikJson.muzePublikovat)
                    {
                        cudlik.mqttQos = cudlikJson.hasOwnProperty('QoS') ? cudlikJson.QoS : parseInt(0);
                        cudlik.mqttRetain = cudlikJson.hasOwnProperty('retain') ? cudlikJson.retain : false;
                        
                        cudlik.zpravaOdCudliku.connect(zpravaCudliku);
                    }
                    else
                    {
                        cudlik.muzePublikovat = false;
                    }
                    
                    // jestli máme v json definovanej nějakej atribut 'jsonElement' jakože čudlik
                    // chce vezprávičkách dycky luštit nějakej json a zněj si něco vyzobnout tak nastavíme že parsuje json
                    if(cudlikJson.hasOwnProperty('jsonElement'))
                    {
                        cudlik.parsujeJson = true;
                        cudlik.jsonElement = cudlikJson.jsonElement;
                    }
                    
                    // jestli pracuje/drží datovej typ v celočíselný podobě nebo ne
                    if(cudlikJson.hasOwnProperty('jeCelociselny'))
                    {
                        cudlik.jeCelociselny = cudlikJson.jeCelociselny;
                    }
                    
                    // ruzný specifický atributy pro různý druhy čudliků
                    switch(cudlikJson.druh)
                    {
                        
                        case 'Prepinadlo':
                            if(cudlikJson.hasOwnProperty('zpravaPriOn'))
                                cudlik.zpravaPriOn = cudlikJson.zpravaPriOn;
                            if(cudlikJson.hasOwnProperty('zpravaPriOff'))
                                cudlik.zpravaPriOff = cudlikJson.zpravaPriOff;
                            if(cudlikJson.hasOwnProperty('onText'))
                                cudlik.onText = cudlikJson.onText;
                            if(cudlikJson.hasOwnProperty('offText'))
                                cudlik.offText = cudlikJson.offText;
                            
                            // aktualizace přepínadla protože vokamžitě nemá barvičku
                            cudlik.aktualizovatCudlik();
                            break;
                            
                        case 'Soupatko':
                        case 'Kruh':
                            if(cudlikJson.hasOwnProperty('minHodnota'))
                                cudlik.hodnotaMin = cudlikJson.minHodnota;
                            if(cudlikJson.hasOwnProperty('maxHodnota'))
                                cudlik.hodnotaMax = cudlikJson.maxHodnota;
                            if(cudlikJson.hasOwnProperty('znakyZaHodnotou'))
                                cudlik.znakyZaHodnotou = cudlikJson.znakyZaHodnotou;
                            
                            console.log(cudlik.hodnotaMin);
                            console.log(cudlikJson.hodnotaMin);
                            
                            if(cudlikJson.druh == 'Kruh')
                                cudlik.aktualizovatPrumerTakyStred();
                            
                            break;
                            
                        case 'Graf':
                            if(cudlikJson.hasOwnProperty('pocetCarMrizky'))
                                cudlik.pocetCarMrizky = cudlikJson.pocetCarMrizky;
                            break;
                        case 'Tlacitko':
                            if(cudlikJson.hasOwnProperty('coPosila'))
                                cudlik.coPosila = cudlikJson.coPosila;
                            if(cudlikJson.hasOwnProperty('napis'))
                                cudlik.napis = cudlikJson.napis;
                            break;
                            
                        case 'Moznosti':
                            if(cudlikJson.hasOwnProperty('seznamMoznosti'))
                                cudlik.seznamMoznosti = cudlikJson.seznamMoznosti;
                            break;
                            
                        case 'Napis':
                            if(cudlikJson.hasOwnProperty('maOkraj'))
                                cudlik.maOkraj = cudlikJson.maOkraj;
                            break;
                            
                        default:
                            console.error('neznamej druch cudliku v json souboru :O :O');
                            break;
                    }
                    
                    
                    // přijímací čudliky si rozškatulkujem do polí(slovníků) kde klíčem je topic danýho čudliku dycky
                    // nebudem si pak muset přestrkávat zprávu vod mqtt klienta do všech čudliků najednou ale
                    // jenom do čudliků danýho topicu
                    // máme dvě takový pole polí přijímacích čudliků jedno vobyčejný a druhý pro json
                    if(cudlikJson.muzePrijimat)
                    {
                        if(cudlik.parsujeJson)
                        {
                            if(cudlikJson.topic in jsonCudlikyPodleTopicu)
                                jsonCudlikyPodleTopicu[cudlikJson.topic].push(cudlik);
                            else
                                // jestli neni tak přidáme nový pole
                                jsonCudlikyPodleTopicu[cudlikJson.topic] = [cudlik];
                        }
                        else
                        {
                            if(cudlikJson.topic in cudlikyPodleTopicu)
                                cudlikyPodleTopicu[cudlikJson.topic].push(cudlik);
                            else
                                cudlikyPodleTopicu[cudlikJson.topic] = [cudlik];
                        }
                    }
                    else
                    {
                        cudlik.muzePrijimat = false;
                    }
    
                    // strčíme čudlik do pole který má referenci na všecky čudliky
                    vseckyCudliky.push(cudlik);
                    
                    // jestli čudlik muže publikovat tak taky skováme do pole publikovacích čudliků
                    if(cudlik.muzePublikovat)
                        publikovaciCudliky.push(cudlik);
                    
                    // nakonec skusíme přidat QoS/topic do tý pomyslný 'sady' ze dvou polí
                    // topic přidáváme jenom když eště v poli neni. když je tak kouknem jestli je přidávaný qos věčí než to uložený
                    // a jestli jako jo tak přepišem
                    if(seznamTopicu.includes(cudlikJson.topic))
                    {
                        var index = seznamTopicu.indexOf(cudlikJson.topic);
                        if(seznamTopicuQoS[index] < cudlikJson.QoS)
                            seznamTopicuQoS[index] = cudlikJson.QoS;
                    }
                    else
                    {
                        // jestli topic eště v 'sadě' neni tak prostě jako přidáme
                        seznamTopicu.push(cudlikJson.topic);
                        seznamTopicuQoS.push(cudlikJson.QoS);
                    }
    
                }
                
            }
            
            // funkce co vodstraní všecky čudliky
            function odstranitCudliky()
            {
                vseckyCudliky.forEach(cudlik => {cudlik.destroy();});
                vseckyCudliky = [];
                
                publikovaciCudliky = [];
                cudlikyPodleTopicu = [];
                jsonCudlikyPodleTopicu = [];
                
                // seznam topiců promažem taky
                seznamTopicu = [];
                seznamTopicuQoS = [];
            }
            
            // funcke co podle topicu strčí nějakou zprávu všem čudlikům 
            function strcitZpravuCudlikum(topic, obsah)
            {
                console.log('zprava cudlikum topic: ' + topic);
                cudlikyPodleTopicu[topic].forEach(cudlik => {cudlik.prijmout(obsah);});
            }
            
            // tosamý co 'strcitZpravuCudlikum' ale s json
            function strcitJsonZpravuCudlikum(topic, obsah)
            {
                var json = null;
                try
                {
                    json = JSON.parse(obsah);
                }
                catch(e)
                {
                    console.error('chyba pri parsovani json zpravy: ' + e.name + ', ' + e.message);
                }
                console.log('json zprava cudlikum topic: ' + topic);
                jsonCudlikyPodleTopicu[topic].forEach(cudlik => {cudlik.prijmoutJson(json);});
            }
            
            // zpráva vod čudliku
            // klient ji zkusí poslat (stav připojení si hlídá metoda 'poslat')
            function zpravaCudliku(topic, obsah)
            {
                console.log('posilam str: '+obsah);
                Klient.poslat(topic, obsah);
            }
            
            // callbacky na vodpojení/připojení/chybu klienta
            // vypnem posílací čudliky
            function odpojeniKlienta()
            {
                malejTextDole.text = 'odpojeno (posílací čudliky teďko nefungujou)';
                publikovaciCudliky.forEach(cudlik => {cudlik.muzePublikovat = false;});
            }
            
            // zapnem posílací čudliky
            function pripojeniKlienta()
            {
                malejTextDole.text = 'připojeno';
                publikovaciCudliky.forEach(cudlik => {cudlik.muzePublikovat = true;});
            }
            
            function chybaKlienta(popis)
            {
                if(popis === undefined)
                    malejTextDole.text = 'chyba :D';
                else
                    malejTextDole.text = popis;
            }
            
            // funkce co se zavolá jakmile máme qml voběkt kompletní
            Component.onCompleted:
            {
    
                // napojení signálů z mqtt klienta na vodpovídající funkce tady
                Klient.zpravaDoFrontendu.connect(strcitZpravuCudlikum);
                Klient.zpravaJsonDoFrontendu.connect(strcitJsonZpravuCudlikum);
                
                Klient.odpojenej.connect(odpojeniKlienta);
                Klient.pripojenej.connect(pripojeniKlienta);
                Klient.chyba.connect(chybaKlienta);
                
                // jestli máme v kongiguraci uloženej string json souboru tak ho vemem jinak použijem ten výchozí
                var konfiguracniJsonStr = plasmoid.configuration.konfiguracniJson || jsonString;
                
                // zkisíme json naparsovat
                var json = null;
                try
                {
                    json = JSON.parse(konfiguracniJsonStr);
                }
                catch(e)
                {
                    console.error('chyba pri parsovani konfiguracniho *.json: ' + e.name + ', ' + e.message);
                    malejTextDole.text = 'nešlo naparsovat json :O :O';
                }
                
                if(json != null)
                {
                    // jestli máme validní json tak podle něj mužem vyrobit čudliky :D ;D
                    jsonNaElementy(json);
                    
                    // nastavíme seznam 
                    Klient.nastavitSeznamTopicu(seznamTopicu, seznamTopicuQoS);
                    
                    // jestli máme nastavenou brokera/přihlašovací ůdaje a klient neni puštěnej tak ho nastavíme a zapnem
                    if(adresa && id && uzivatel && heslo)
                    {
                        if(!Klient.bezi())
                        {
                            Klient.nastavit(adresa, id, uzivatel, heslo);
                            Klient.start();
                        }
                        else
                        {
                            // sem by jsme se jako vubec neměli dostat :D
                            console.log('mqtt klient uz bezi :O :O');
                        }
                    }
                    else
                    {
                        var txt = 'mqtt klient se nespustil protoze neni nakonfigurovanej';
                        console.log(txt);
                        malejTextDole.text = txt;
                    }
                }
                
            }
            
            // když odstraníme widget tak taky jako musíme vipnout mqtt klienta ;D
            Component.onDestruction:
            {
                Klient.stop();
            }
            
            
            //regování na změnu konfigurace
            Plasmoid.onUserConfiguringChanged:
            {
                var konfiguracniJsonStr = plasmoid.configuration.konfiguracniJson || jsonString;
                var json = null;
                try
                {
                    json = JSON.parse(konfiguracniJsonStr);
                }
                catch(e)
                {
                    console.error('chyba pri parsovani konfiguracniho *.json: ' + e.name + ', ' + e.message);
                    malejTextDole.text = 'nešlo naparsovat json :O :O';
                }
                
                if(json != null)
                {
                    odstranitCudliky();
                    jsonNaElementy(json);
                    Klient.nastavitSeznamTopicu(seznamTopicu, seznamTopicuQoS);
                    
                    if(adresa && id && uzivatel && heslo)
                    {
                    
                        // jestli klient už běží tak mu resetnem
                        // to znamená že ho vodpojíme přepišem parametry a připojíme znova
                        // vlákno se nepřetrhne :D
                        if(Klient.bezi())
                        {
                            Klient.reset(adresa, id, uzivatel, heslo, seznamTopicu, seznamTopicuQoS);
                        }
                        else
                        {              
                            // jinak normálně pustíme
                            Klient.nastavit(adresa, id, uzivatel, heslo);
                            Klient.start();
                        }
                    
                    }
                    else
                    {
                        // jestli je konfigurace špatná/nějakej údaj chybí tak se klient nezačne připojovat
                        var txt = 'mqtt klient se nespustil protoze neni nakonfigurovanej';
                        console.log(txt);
                        malejTextDole.text = txt;
                    }
                    
                }
            }
            
            
            /*
            *  TODO 
            * todleto se nikdy nezavovlalo :O :O
            *  kolibáč by si tam naně měl pořádně došlápnout aby to tam dali dopořádku si myslim :O :O
            * 
            * 
            Plasmoid.onFormFactorChanged:
            {
                console.log("zmena rozliseni");
            }
            
            Plasmoid.onAvailableScreenRegionChanged:
            {
                console.log("zmena!!!!!!!!!!");
            }
            
            Plasmoid.onLocationChanged:
            {
                console.log("zmena222!!!!!!!!!!");
            }
            */
            
            
            // grid/mřížka do který se nastrkaj jednotlivý čudliky
            GridLayout
            {
                id: grid
                width: parent.width
                height: parent.height - malejTextDole.height
                rowSpacing: velikostMezer
                columnSpacing: velikostMezer
            }
            
            // malej stavovej textík dole u spodního vokraje widgetu
            // řiká cose právě děje a jestli je widget připojenej/nepřipojenej a takový věci
            Text
            {
                y: grid.height
                id: malejTextDole
                text: 'právě teďko zapnutý'
                color: main.barvaTextu
            }
            
        }
    
    }
    

    package/contents/ui/NastavovaniCudliku.qml

    import QtQuick 2.0
    import QtQuick.Controls 2.5
    import QtQuick.Dialogs 1.0
    import QtQuick.Layouts 1.12
    import org.kde.kirigami 2.4 as Kirigami
    
    // podle ukázky tady hele https://develop.kde.org/docs/plasma/widget/configuration/
    
    // naimportujem si svuj plugin kuli třídě 'NačítadloSouboru' kterou potřebujem kuli načtení textovýho souboru
    // samotný qml nic takovýho jako přečíst nějakej *.txt asi neumí :O :O
    import org.kde.private.mqttCudliky 1.0
    
    Kirigami.FormLayout
    {
        id: page
        Kirigami.FormData.label: i18n('Nastavování')
    
        // vyrobení načítadla
        Nacitadlo
        {
            id: nacitadlo
        }
        
        // proměný musej mit ten prefix 'cfg_' aby si to jakože spárovalo s vodpovídajícíma hodnotama v souboru main.xml 
        property alias cfg_adresa: konfiguraceAdresa.text
        property alias cfg_id: konfiguraceId.text
        property alias cfg_uzivatel: konfiguraceUzivatel.text
        property alias cfg_heslo: konfiguraceHeslo.text
      
        property alias cfg_konfiguracniJson: configTxt.text
        
        TextField
        {
            id: konfiguraceAdresa
            Kirigami.FormData.label: i18n('adresa:')
            placeholderText: i18n('adresa s druhem protokolu a portem nakonci. třeba něco jako tcp://127.0.0.1:1883')
        }
            
        TextField
        {
            id: konfiguraceId
            Kirigami.FormData.label: i18n('id klienta')
            placeholderText: i18n('id klienta')
        }
    
        TextField
        {
            id: konfiguraceUzivatel
            Kirigami.FormData.label: i18n('uživatel')
            placeholderText: i18n('uživatel')
        }
            
        TextField
        {
            id: konfiguraceHeslo
            Kirigami.FormData.label: i18n('heslo')
            placeholderText: i18n('heslo')
        }
    
        
        ColumnLayout
        {
        Kirigami.FormData.label: i18n('načíst z konfiguračního *.json (umí to načíst i tamto nastavování brokera takže seto nemusí vyplňovat rukama)')
        
        
            TextArea
            {
            id: configTxt
            placeholderText: i18n('tady by měl bejt konfurační json čudliků ukázanej')
            Layout.fillHeight: true
            Layout.fillWidth: true
            }
    
            Button
            {
                text: i18n('Načíst *.json ze souboru')
                icon.name: 'folder-symbolic'
                onClicked:
                {
                    fileDialogLoader.active = true
                }
    
                // načítadlo souborů
                // soubor dostanem jako proměnou fileUrl toje místo uložení toho souboru někde v systemu
                // asi nám neumí dát přímo jeho vobsah nevim :O :O
                Loader
                {
                    id: fileDialogLoader
                    active: false
    
                    sourceComponent: FileDialog 
                    {
                        id: fileDialog
                        //folder: shortcuts.music
                        
                        // chcem json ale umožníme taky vybrat všecky soubory
                        nameFilters: [i18n('json(%1)', '*.json'),i18n('všecky soubory(%1)', '*'),]
                        
                        onAccepted:
                        {
                            // načtem načítadlem vobsah souboru do js proměný
                            var obsah = nacitadlo.nacistSoubor(fileUrl);
                            
                            // měl byto bejt jakože validní json nóó tak si ho zkusíme tady nejdřiv naparsovat a
                            // když nám to nebude/skončí vyjímkou tak tam asi jako je nějaká chyba
                            var json = null;
                            try
                            {
                                json = JSON.parse(obsah);
                            }
                            catch(e)
                            {
                                configTxt.text = 'chyba pri parsovani konfiguracniho *.json: ' + e.name + ', ' + e.message;
                                console.error(configTxt.text);
                            }
                            
                            if(json != null)
                            {
                                // jestli máme validní json tak ho strčíme do configTxt textovýho pole aby se nám jakože pak uložil do nastavení widgetu
                                configTxt.text = obsah;
                                
                                // jestli má json soubor element pomenovanej 'broker' tak podle něj nastavíme připojení a nemusíme to vyplňovat ručně furt
                                if(json.hasOwnProperty('broker'))
                                {
                                    var brokerJson = json.broker;
                                    
                                    if(brokerJson.hasOwnProperty('adresa'))
                                        konfiguraceAdresa.text = brokerJson.adresa;
                                    if(brokerJson.hasOwnProperty('id'))
                                        konfiguraceId.text = brokerJson.id;
                                    if(brokerJson.hasOwnProperty('uzivatel'))
                                        konfiguraceUzivatel.text = brokerJson.uzivatel;
                                    if(brokerJson.hasOwnProperty('heslo'))
                                        konfiguraceHeslo.text = brokerJson.heslo;
                                }
                                
                            }
                            
                            fileDialogLoader.active = false;
                        }
                        
                        onRejected:
                        {
                            fileDialogLoader.active = false;
                        }
                        
                        Component.onCompleted: open()
                    }
                }
            }
    
        }
        
    }
     
    

    package/contents/ui/cudliky/Cudlik.qml

    import QtQml 2.2
    import QtQuick 2.9
    import QtQuick.Layouts 1.11
    
    // oběkt ze kterýho 'děděj' všecky vostatní čudliky 
    
    Rectangle
    {
    
        //nějaká minimalní velikost aby se nám to jakože celý nescvrklo uplně
        Layout.minimumWidth: 64
        Layout.minimumHeight: 64
        
        property string nazev: 'Cudlik'
        
        // výchozí barvy čudliku kdyby třeba jako nebyly přenastavený po vyrobení
        property color barvaTextu: 'black'
        property color barvaAktivni: 'red'
        property color barvaKontury: 'green'
        property color barvaPozadi: 'white'
        
        // tloušťka vokraje a zakulacení vokrajů
        property real velikostOkraje: 5
        property real zakulaceni: 5
        
        // k jakýmu je připojenej topicu s jakým qos/kvalitou služby a jestli je zapnutej retain flag
        property string mqttTopic: ''
        property int mqttQos: 0
        property bool mqttRetain: false
        
        // jestli muže publikovat a přijímat zprávy
        property bool muzePublikovat: true
        property bool muzePrijimat: true
        
        // alias/reference kterou umožňujem potomkům lízt k titulku týdletý třídy
        property alias titulek: titulek
        // alias kterým se nastavuje viditelnost titulku
        property alias maTitulek: titulek.visible
        
        // jestli jakoby parsuje json a jestli jo tak jakej element hledá
        // žádný složitý parsování prostě koukne na element
        // potřebuje někdo nějaký víc složitější parsování??????? :O :O :O :O
        // sou různý mrňavý knihovničky nato hele třeba https://www.w3resource.com/JSON/JSONPath-with-JavaScript.php
        property bool parsujeJson: false
        property string jsonElement: ""
        
        // jestli je double/int
        property bool jeCelociselny: true
        
        // jestli je vubec jako číselnej
        property bool jeCiselny: true
        
        color: Qt.rgba(0,0,0,0)
        
        // funkce do který se budou strkat přijatý zprávy
        // nevim jak to udělat jako abstraktní metodu :D
        function prijmout(zprava){console.log("zavolano cudlik.prijmout rodicovsky tridy :O :O");}
        
        // funkce co zkusí vyparsovat klíč z json zprávičky aten pak strčit do normální funkce přijmout
        // potomci Čudliku todleto teda pak nemusej řešit
        function prijmoutJson(zpravaJson)
        {
            if(parsujeJson)
            {
                if(zpravaJson.hasOwnProperty(jsonElement))
                {
                    prijmout(zpravaJson[jsonElement]);
                }
                else
                {
                    console.error('v json zprave neni tendlecten klic/element!!!!!!!!!!!!!!!');
                }
            }
            else
            {
                console.error('tendle cudlik nechce json parsovat!!!!!!!!!!!!!!');
            }
            
        }
        
        // titulek čudliku kterej se věčinou zobrazuje nad tim elementem
        Text
        {
            id: titulek
            text: "Cudlik"
            color: parent.barvaTextu
    //         font.pointSize: 16
                // velikost fontu se vybírá sama podle width/height velikosti Text voběktu
                font.pointSize: 256
                minimumPointSize: 8
                fontSizeMode: Text.Fit
            
            width: parent.width
            height: parent.height/5
            visible: true
        }
    }
    

    package/contents/ui/cudliky/Graf.qml

    import QtQuick 2.9
    import QtQuick.Controls 2.5
    import org.kde.quickcharts 1.0 as Charts
    import org.kde.quickcharts.controls 1.0 as ChartsControls
    
    // čudlik s kcharts grafem
    // api maj trošičku popsaný tady https://api.kde.org/frameworks-api/frameworks-apidocs/frameworks/kquickcharts/html/index.html
    // ale blbě se k tomu hledaj nějaký víc složitější ukázkový příklady :O :/
    
    Cudlik 
    {
        id: grafRoot
        nazev: "graf"
        titulek.text: nazev
        
        property real zobrazovanaPromena: 0
        property var zdrojDat: Charts.SingleValueSource { value: zobrazovanaPromena }
        property int pocetCarMrizky: 3
        
        function prijmout(zprava)
        {
            grafRoot.zobrazovanaPromena = jeCelociselny ? parseInt(zprava) : parseFloat(zprava);
            grafRoot.zdrojDat.dataChanged();
        }
            
        Rectangle
        {
            width: parent.width
            height: titulek.visible ? parent.height - titulek.height : parent.height
            y: titulek.visible ? titulek.height : 0
            
            color: barvaPozadi
            radius: zakulaceni
            
            
            Charts.LineChart
            {
                id: grafPlot
                antialiasing: true
                anchors.verticalCenter: parent.verticalCenter
                x: yAxisLabels.width + velikostOkraje + 10
    
                width: parent.width - velikostOkraje*2 - yAxisLabels.width -10
                height: parent.height - velikostOkraje*2
            
                colorSource: Charts.SingleValueSource { value: barvaAktivni }
                nameSource: Charts.SingleValueSource { value: nazev }
                valueSources: Charts.HistoryProxySource 
                {
                    source: grafRoot.zdrojDat
                    maximumHistory: 100
                }
                    
                lineWidth: 2
                fillOpacity: 0.5
                smooth:false
                direction:Charts.XYChart.ZeroAtEnd
                    
                    
            
                Charts.GridLines
                {
                    id: vertikalni
        
                    anchors.fill: parent
                    chart: parent
                    direction: Charts.GridLines.Vertical;
        
                    minor.count: pocetCarMrizky
                    minor.lineWidth: 1
                    minor.color: barvaTextu
                    
                    // major čáry se mi nepodařilo uplně vypnout
                    // když se třeba jako do major.count strčí 0 tak si je to asi generuje podle .frequency atributu :O :/
                    major.count: 1
                    major.lineWidth: 1
                    major.color: barvaTextu
               
                }
                
                Charts.GridLines
                {
                    id: horizontalni
        
                    anchors.fill: parent
                    chart: parent
                    direction: Charts.GridLines.Horizontal;
        
                    minor.count: pocetCarMrizky
                    minor.lineWidth: 1
                    minor.color: barvaTextu
                    
                    major.count: 1
                    major.lineWidth: 1
                    major.color: barvaTextu
                }
                
                Rectangle
                {
                    id: okrajMrizky
                    anchors.fill: parent
                    color: Qt.rgba(0,0,0,0)
                    border.color: barvaTextu
                    border.width: 1
                }
                
            }
                
            Charts.AxisLabels
            {
                id: yAxisLabels
                anchors.verticalCenter: parent.verticalCenter
    
                height: parent.height - velikostOkraje*2
                x: 10
        
                direction: Charts.AxisLabels.VerticalBottomTop
                
                // nejde to ňák víc líp???? :O :O
                delegate: Label
                {
                    color: barvaTextu
                    text: parseFloat(Charts.AxisLabels.label).toFixed(2);
                }
                
                source: Charts.ChartAxisSource 
                {
                    chart: grafPlot
                    axis: Charts.ChartAxisSource.YAxis
                    itemCount: pocetCarMrizky + 2
                }
            }
        
        
            Rectangle
            {
                id: okrajGrafu
                anchors.fill: parent
                color: Qt.rgba(0,0,0,0)
                border.color: barvaKontury
                border.width: velikostOkraje
                radius: zakulaceni
            }
        
        }
    }
    
    

    package/contents/ui/cudliky/Kruh.qml

    import QtQml 2.2
    import QtQuick 2.9
    
    // takový jakože kolečko
    // kolečko uměj namalovat i kcharts ale to sem zistila až když sem měla todleto hotový :D
    
    Cudlik
    {
        id: kruh
        
        nazev: "Kruh"
        
        // minimální maximální hodnota aktuální hodnota a možnej rosah hodnoty
        property real hodnotaMin: 0
        property real hodnotaMax: 100
        property real hodnota: 100
        property real rosahHodnot: hodnotaMax - hodnotaMin
        
        // jaký znaky se voběvujou za hodnotou uprostřed toho kruhu
        // výchozí je znak '%'
        property string znakyZaHodnotou: '%'
        titulek.text: nazev
        property real sirkaHlavniCary: 16
        property real sirkaVedlejsiCary: velikostOkraje
        property real offset_cary: 1
        
        // souřadnice středu toho kruhu a jeho poloměr
        // jeto vymyšlený tak že když je titulek kračí než zdálenost středu kruhu vod levýho/pravýho vokraje tak
        // se kruh do volnýho místa nafoukne. jinak je menčí než titulek a stčenej vo velikost titulku dolu abyseto jakože nepřekrejvalo
        // protože byto bylo takový hnusný
        
        // x je dycky uprostřed
        property real stredX: width / 2
        property real stredY: height /2
        property real polomer: height / 2
        
        // polomer je vlastně jenom poloměr kružnice podle který namalujem nějak tlustej kroužek
        // noa půlka tloušťky tohodlenctoho kroužku je atribut polomerOffset
        property real polomerOffset: sirkaHlavniCary/2 + sirkaVedlejsiCary
            
        // přepočet aktuální hodnoty na úhel v radiánech
        property real uhel: (kruh.hodnota - kruh.hodnotaMin) / kruh.rosahHodnot * 2 * Math.PI
    
        // posun úhlu aby nula byla na kružnici uplně nahoře (tam kde maj točicí hodiny dvanáctku)
        property real posunUhlu: -Math.PI / 2
        
        // naparsujem číslo podle toho jestli je float nebo celočíselný
        function prijmout(zprava)
        {
            hodnota = jeCelociselny ? parseInt(zprava) : parseFloat(zprava);
        }
        
        // výpočet poloměru podle toho kde se kružnice zdrcne s titulkem
        function aktualizovatPrumerTakyStred()
        {
            
            // když nemá titulek tak vemem to menčí z width/šířky a height/vejšky a podle toho uděláme ten poloměr
            // v polovině velikost - půlka tloušťky toho našeho malovacího kroužku
            if(!maTitulek)
            {
                kruh.polomer = (Math.min(kresliciPlocha.width, kresliciPlocha.height) - sirkaHlavniCary - sirkaVedlejsiCary) / 2 - offset_cary;
            }
            else if(titulek.width < stredX)
            {
                // když je titulek kratčí a dělá že končí před xovým středem nažeho zobrazovacího kroužku tak skusíme najít tu nejvíc nejvěčí kružnici
                // kterou tam mužem strčit. tadleta kružnice muže dosáhnout až na pravej dolní růžek titulku jestli ji to dovolej rozměry kreslicí plochy
                
                // do rovnice pro kružnici hele https://cs.wikipedia.org/wiki/Kru%C5%BEnice
                // (bod.x - střed.x)**2 + (bod.y - střed.y)**2 == r**2
                // si dosadíme za bod na vobvodu ten pravej dolní růžek titulku
                // a za střed.y vejšku kreslicí plochy - poloměr, jakože vejšku vod spodního vokraje
                // luštěnej zoreček třeba takle nějak
                // (titulek.x - kresliciPlocha.width/2)**2 + (titulek.y - kresliciPlocha.y + r)**2 == r**2
                
                // cejtim žeto de eště trošičku aritmetologicky víc zjednodušit ale sem moc líná nato :D
                // a tamta absolutní hodnota by tam asi jako vubec neměla bejt :D
                var c1 = (titulek.width - stredX)**2;
                var c2 = - titulek.height + kruh.height;
                var r = Math.abs(-(c1/(2*c2)) - (c2/2));
                
                kruh.polomer = Math.abs((Math.min(kresliciPlocha.width/2, kresliciPlocha.height/2, r) - polomerOffset) - offset_cary);
                
            }
            else
            {
                kruh.polomer = (Math.min(kresliciPlocha.width, kresliciPlocha.height - titulek.height) - sirkaHlavniCary - sirkaVedlejsiCary) / 2 - offset_cary;
            }
            
            kruh.stredY = kruh.height - kruh.polomer - polomerOffset;
        }
        
        // ždycky když se změní šířka/vejška widgetu tak přepočitáme ipsilonovou souřadnici středu kroužku + poloměr
        // fakt byse asi jako hodilo vědět jak se jako dělá callback na změnu rozlišení velikosti widgetu a tak si ty hodnoty přepočítávat :D
        onWidthChanged:
        {
            aktualizovatPrumerTakyStred();
        }
        onHeightChanged:
        {
            aktualizovatPrumerTakyStred();
        }
    
        // překreslíme malovací plochu pokaždý když se změní hodnota
        onHodnotaChanged:
        {
            kresliciPlocha.requestPaint();
            
            // tadleta aktualizace průměrů je tady jenom prozatim než se ňák podaří vymyslet jak to jako
            // aktualizovat nějak líp :O :O
            aktualizovatPrumerTakyStred();
        }
        // .. a taky když vyrobíme element
        Component.onCompleted: kresliciPlocha.requestPaint()
    
        //kreslicí plocha na který si budem malovat ty kroužky
        Canvas
        {
            id: kresliciPlocha
            width: kruh.width
            height: kruh.height
            
            // všecko je víc hežčí s antialiasingem :D ;D
            antialiasing: true
    
            onPaint:
            {
                // vezmem 2d kreslicí kontext a vypucujem 
                var ctx = getContext('2d');
                //ctx.save();
                ctx.clearRect(0, 0, kresliciPlocha.width, kresliciPlocha.height);
    
                //nakreslení pozadí
                ctx.beginPath();
                ctx.lineWidth = sirkaHlavniCary;
                ctx.strokeStyle = kruh.barvaPozadi;
                ctx.arc(kruh.stredX, kruh.stredY, kruh.polomer, 0, 2*Math.PI);
                ctx.stroke();
                
                //nakreslení zobrazovací čáry
                ctx.beginPath();
                ctx.lineWidth = sirkaHlavniCary;
                ctx.strokeStyle = kruh.barvaAktivni;
                ctx.arc(kruh.stredX, kruh.stredY, kruh.polomer, kruh.posunUhlu, kruh.posunUhlu + kruh.uhel);
                ctx.stroke();
    
                // a nakreslení vobou dvou krajních vokrajovejch čar
                ctx.beginPath();
                ctx.lineWidth = sirkaVedlejsiCary;
                ctx.strokeStyle = kruh.barvaKontury
                ctx.arc(kruh.stredX, kruh.stredY, kruh.polomer - sirkaHlavniCary/2 - offset_cary, 0, 2*Math.PI);
                ctx.stroke();
                
                ctx.beginPath();
                ctx.lineWidth = sirkaVedlejsiCary;
                ctx.strokeStyle = kruh.barvaKontury
                ctx.arc(kruh.stredX, kruh.stredY, kruh.polomer + sirkaHlavniCary/2 + offset_cary, 0, 2*Math.PI);
                ctx.stroke();
    
                //ctx.restore();
    
            }
    
            // takovej ten text uprostřed kruhu
            Text
            {
                anchors.horizontalCenter: parent.horizontalCenter
                y: kruh.stredY - height/2
                verticalAlignment: Text.AlignVCenter
    
    
                // jestli neni celočíselnej ukazujem proměnou jenom se dvouma desetinovejma místama
                text: ( jeCelociselny ? parseInt(kruh.hodnota) : kruh.hodnota.toFixed(2) ) + znakyZaHodnotou
                color: kruh.barvaTextu
                width: kruh.polomer*1.2
                height: kruh.polomer*1.2
                
                // velikost fontu se vybírá sama podle width/height velikosti Text voběktu
                font.pointSize: 256
                minimumPointSize: 8
                fontSizeMode: Text.Fit
            }
            
            // klikací voblast kruhu
            // je aktivní jenom když čudlik muže publikovat 
            // funguje tak že když se klikne někde na kruhu tak se hodnota nastaví tak aby jakože tomu 
            // kliknutýmu místo proporcionacionálně vodpovídala
            MouseArea
            {
                anchors.fill: parent
                enabled: muzePublikovat
                onClicked:
                {
                    // spočitáme euklidovskou zdálenost
                    var zdalenost = Math.sqrt( (mouse.x - kruh.stredX)**2 + (mouse.y - kruh.stredY)**2 );
                    
                    // nastavujem hodnotu jenom když se myškou máčkne přímo tamten kruh
                    // věčí/menčí zdálenosti nepočitáme
                    if(zdalenost > kruh.polomer - kruh.polomerOffset && zdalenost < kruh.polomer + kruh.polomerOffset)
                    {      
                        // vodečtem vod máčknutý souřadnice střed kruhu takže střed kružnice je teďko jakoby na bode (0,0)
                        var x = mouse.x - kruh.stredX
                        var y = mouse.y - kruh.stredY
                        
                        // pomocí atan2 spočitáme jakej má bod máčknutí uhel v rosahu od mínus pí až plus pí
                        // tendleten uhel pak mužem převíst třeba na hodnotu v rosahu 0.0 až 2.0 atu pak násobit půlkou
                        // maximální možný hodnoty kterou čudlik muže ukazovat/mit 
                        kruh.hodnota = (1.0 - (Math.atan2(x, y) / Math.PI)) * kruh.rosahHodnot/2 + kruh.hodnotaMin;
                        
                        // nakonec pošlem
                        zpravaOdCudliku(mqttTopic, jeCelociselny ? parseInt(kruh.hodnota) : kruh.hodnota);
                    }
                    
                }
            }
        }
    
    
    }
    

    package/contents/ui/cudliky/Moznosti.qml

    import QtQml 2.2
    import QtQuick 2.15
    import QtQuick.Controls 1.4
    import QtQuick.Controls.Styles 1.4
    import QtQuick.Templates 2.4 as QtSablony
    
    //jeto vlastně combobox ve kterým je strčený nějaký políčko stringů ze kterýho si mužem vybírat jednu možnost dycky
    
    Cudlik
    {
        id: moznostiRoot
        
        nazev: 'moznosti'
        titulek.text: nazev
        property var seznamMoznosti: ['tady','by měl', 'bejt seznam','možností']
        
        function prijmout(zprava)
        {
            if(!muzePrijimat)
                return;
    
            // jestli přijatá zpráva vodpovídá některý hodnotě v poli možností tak se nastaví 
            // index právě vybraný možnosti
            // ( atribut currentText qml voběktu https://doc.qt.io/qt-5/qml-qtquick-controls-combobox-members.html je jenom pro čtení :O :/ )
            if(seznamMoznosti.includes(zprava))
                    vybiradlo.currentIndex = vybiradlo.find(zprava);
        }
    
        ComboBox
        {
            id: vybiradlo
            
            width: parent.width
            height: maTitulek ? parent.height - titulek.height : parent.height
            y: maTitulek ? titulek.height : 0
            
            model: seznamMoznosti
            
            // možnost je vybíratelná jenom když de publikovat
            selectByMouse: muzePublikovat
            
            // nahradíme původní barvičky tlačítka svejma nějakejma
            // neví někdo jak jako přestylovat do dropdownový menu :O :O
            // tendlecten návod hele https://doc.qt.io/qt-5/qtquickcontrols2-customize.html#customizing-combobox nefunguje :O :/
            style: ComboBoxStyle 
            {
                
                font.pointSize: 24
                textColor: 'black'
                selectedTextColor: barvaKontury
                selectionColor: barvaAktivni
                
                background: Rectangle
                {
                    height: control.height
                    width: control.width
                    color : barvaPozadi
                    border.color: barvaKontury
                    border.width: velikostOkraje
                    radius: zakulaceni
                }
                
                // text strčíme doprostřed a nafouknem aby byl co nejvíc nejvěčí
                label: Text    
                {
    
                    //verticalAlignment: Text.AlignVCenter
                    anchors.centerIn: vybiradlo
                    text:  control.editText
                    color: barvaTextu
                    width: control.width - velikostOkraje*2
                    height: control.height - velikostOkraje*2
                    
                    font.pointSize: 256
                    minimumPointSize: 8
                    fontSizeMode: Text.Fit
                }
                
            }
            
            onActivated:
            {
                zpravaOdCudliku(mqttTopic, seznamMoznosti[index]);
            }
        }
        
    
    
    }
    

    package/contents/ui/cudliky/Napis.qml

    import QtQml 2.2
    import QtQuick 2.15
    
    // takovej jakože hodně moc vobyčejnej čudlik kterej dělá jenom to že ukazuje text nějakej chycenej
    
    Cudlik
    {
        id: napisRoot
        
        nazev: "napis"
        titulek.text: nazev
        
        property alias text: napisElement.text
        
        // jestli má nějaký pozadí/vokraj 
        // když ne ukazuje se jenom samotnej textík přímo na widgetu
        property bool maOkraj: true
        
        function prijmout(zprava)
        {
            if(!muzePrijimat)
                return;
            text = zprava;
        }
    
        Rectangle
        {
            id: okraj
            width: parent.width
            height: maTitulek ? parent.height - titulek.height : parent.height
            radius: zakulaceni
            y: maTitulek ? titulek.height : 0
    
            color: barvaPozadi
            border.color: barvaKontury
            border.width: velikostOkraje
                    
            visible: maOkraj
        }
            
        Text
        {
            id: napisElement
            text: "napis"
            width: okraj.width - velikostOkraje * 2
            height: okraj.height - velikostOkraje * 2
            anchors.centerIn: okraj
            horizontalAlignment: Text.AlignHCenter
            verticalAlignment: Text.AlignVCenter
    
            color: barvaTextu
                    
            font.pointSize: 256
            minimumPointSize: 8
            fontSizeMode: Text.Fit
    
        }
        
        
    
    
    }
    

    package/contents/ui/cudliky/Prepinadlo.qml

    import QtQml 2.2
    import QtQuick 2.15
    
    // mačkátko který funguje jako takovej jakože přepínač
    // má dva stavy zapnuto vypnuto
    
    Cudlik
    {
        id: prepinadlo
        
        nazev: 'prepinadlo'
        
        // jestli je zapnutej nebo vypnutej
        property bool stav: false
        
        // podle jakýho vobsahu chycený zprávy mění svuj stav
        // todleto taky posílá při zapnutí/vypnutí
        property string zpravaPriOn: '1'
        property string zpravaPriOff: '0'
        
        // co je na něm jako napsaný při zapnutí/vypnutí
        property string onText: 'ON'
        property string offText: 'OFF'
        
        // vypnem normální titulek třídy Čudlik
        // budem si malovat nějakej nezávislej na to mačkátko přímo
        titulek.visible: false
    
        // mačkátko je takovej jakože čtvereček
        // velikost strany čtverečku bude to víc menčí z dýlky a šířky elementu 
        property real stranaTlacitka: Math.min(width, height)
        
        function prijmout(zprava)
        {
            if(!muzePrijimat)
                return;
            
            // nastavíme stav podle toho jestli jako string zprávičky vodpovídá
            // zpravaPriOff nebo zpravaPriOn a aktualizujem zobrazení čudliku
            if(zprava === zpravaPriOff)
            {
                stav = false;
                aktualizovatCudlik();
            }
            else if(zprava === zpravaPriOn)
            {
                stav = true;
                aktualizovatCudlik();
            }
        }
        
        // prostě jako přebarvíme součástky čudliku podle stavu kterej má
        // a změníme vobsah zobrazovanejch textů
        function aktualizovatCudlik()
        {
            if(stav)
            {
                mackatko.color = barvaAktivni;
                onOffText.color = barvaKontury;
                onOffTitulek.color = barvaKontury;
                onOffText.text = onText;
            }
            else
            {
                mackatko.color = barvaPozadi;
                onOffText.color = barvaTextu;
                onOffTitulek.color = barvaTextu;
                onOffText.text = offText;
            }
            
        }
        
        // když se nám změní hodnota proměný stav tak taky aktualizujem zobrazení čudliku
        onStavChanged: aktualizovatCudlik()
        
        Rectangle
        {
            id: mackatko
            radius: zakulaceni
            
            width: parent.stranaTlacitka
            height: parent.stranaTlacitka
            
            // vypolohujem doprostředka
            anchors.horizontalCenter: parent.horizontalCenter
            anchors.bottom: parent.bottom
            
            // barva a tloušťka vokraje rectanglu/čtverečku
            border.color: barvaKontury
            border.width: velikostOkraje
            
            MouseArea
            {
                id: mouseArea
                anchors.fill: parent
                enabled: muzePublikovat
                
                onClicked:
                {
                    prepinadlo.stav = !prepinadlo.stav;
                    zpravaOdCudliku(mqttTopic, prepinadlo.stav ? zpravaPriOn : zpravaPriOff);
                }
            }
            
            // text uprostřed čudliku kterej popisuje jestli je mačkátko zapnutý/vypnutý
            Text
            {
                id: onOffText
                anchors.centerIn: mackatko
                
                verticalAlignment: Text.AlignVCenter
                width: parent.width/2
                height: parent.height/2
                
                font.pointSize: 256
                minimumPointSize: 8
                fontSizeMode: Text.Fit
            }
            
            // titulek/název čudliku zobrazovanej přímo na mačkátku
            Text
            {
                id: onOffTitulek
                text: prepinadlo.nazev
                
                anchors.horizontalCenter: parent.horizontalCenter
                
                verticalAlignment: Text.AlignVCenter
                horizontalAlignment: Text.AlignHCenter
                width: parent.width/2
                height: parent.height/2
                
                font.pointSize: 256
                minimumPointSize: 8
                fontSizeMode: Text.Fit
            }
        }
    
    }
    

    package/contents/ui/cudliky/Soupatko.qml

    import QtQml 2.2
    import QtQuick 2.15
    import org.kde.plasma.components 3.0 as PlasmaComponents
    
    // takový posouvátko
    // jeto taková jakože vlastní trošičku horší varianta něčeho na
    // způsob slideru https://doc.qt.io/qt-5/qml-qtquick-controls-slider.html
    // máme nějakej čtvereček pomenovanej 'šoupací element' a ten mužem tahat po ose x
    
    Cudlik
    {
        id: soupatkoRoot
        nazev: 'soupatko'
        
        property int hodnotaMin: 0
        property int hodnotaMax: 100
        
        property string znakyZaHodnotou: '%'
        titulek.text: nazev + ' ' + 50 + znakyZaHodnotou
        
        
        function prijmout(zprava)
        {
            if(!muzePrijimat)
                return;
            
            var podil = (parseInt(zprava) - hodnotaMin) / (hodnotaMax - hodnotaMin);
            soupaciElement.x = maxRosah * podil + velikostOkraje;
            
            // jestli zobrazuje titulek za název připišem aktuální hodntou a znaky který za hodnotou ukazujem 
            if(maTitulek)
            {
                titulek.text = nazev + " " + poziceNaHodnotu() + znakyZaHodnotou;
            }
        }
        
        // přepočet xový hodnoty šoupacího elementu na hodntou
        function poziceNaHodnotu()
        {
            var podil = (soupaciElement.x - velikostOkraje) / maxRosah;
            return parseInt((hodnotaMax - hodnotaMin) * podil + hodnotaMin);
        }
        
        // možnej rosah xový souřadnice šoupacího elementu 
        property real maxRosah: okraj.width - soupaciElement.width - velikostOkraje*2
        
        // pozadí šoupátka
        Rectangle
        {
            id: pozadi
            height: parent.height/4
            width: parent.width
    
            anchors.verticalCenter: parent.verticalCenter
            color: barvaPozadi
            radius: zakulaceni
            
            // když pozadí máčken myšičkou tak taky aktualizujem polohu šoupátka + hodnotu čudliku
            MouseArea
            {
                anchors.fill: parent
                enabled: muzePublikovat
                onClicked:
                {
                    var x = mouse.x;
                    if(x < velikostOkraje)
                        x = velikostOkraje;
                    else if(x > maxRosah)
                        x = maxRosah + velikostOkraje;
                    
                    soupaciElement.x = x;
                    zpravaOdCudliku(mqttTopic, poziceNaHodnotu());
                }
            }
            
            // něco jako takovej jakože progress bar kterej vyplňuje voblast vod levýho vokraje až po šoupací element
            Rectangle
            {
                id: progress
                x: 1
                y: 1
                height: pozadi.height - 2
                width: soupaciElement.x + soupaciElement.width/2 -2
                color: barvaAktivni
                radius: zakulaceni
            }
            
            // vokraj šoupátka
            Rectangle
            {
                id: okraj
                border.color: barvaKontury
                border.width: velikostOkraje
                color: Qt.rgba(0,0,0,0);
                height: pozadi.height
                width: pozadi.width
                radius: zakulaceni
            }
            
            // samotnej šoupací element
            Rectangle
            {
                id: soupaciElement
                width: 32
                anchors.verticalCenter: pozadi.verticalCenter
                height: pozadi.height * 2
                radius: zakulaceni
                color: barvaTextu
                border.color: barvaKontury
                border.width: velikostOkraje
                
                // ždycky když se změní xová souřadnice tak aktualizujem titulek jestli ho zobrazujem teda
                onXChanged:
                {
                    if(maTitulek)
                        titulek.text = nazev + ' ' + poziceNaHodnotu() + znakyZaHodnotou;
                }
                
                MouseArea
                {
                    anchors.fill: parent
                    enabled: muzePublikovat
                    
                    // uděláme ho dragable/tahatelnej myšičkou
                    drag.target: soupaciElement
                    
                    // tahat pude jenom po ose x
                    drag.axis: Drag.XAxis
                    
                    // vodkaď až kam ho jako pude tahat
                    drag.minimumX: velikostOkraje
                    drag.maximumX: okraj.width - soupaciElement.width - velikostOkraje
                    
                    onReleased:
                    {
                        zpravaOdCudliku(mqttTopic, poziceNaHodnotu());
                    }
                    
                }
            }
            
            
        }
        
        
    }
    

    package/contents/ui/cudliky/Tlacitko.qml

    import QtQml 2.2
    import QtQuick 2.15
    import QtQuick.Controls 1.4
    import QtQuick.Controls.Styles 1.4
    import QtQuick.Templates 2.4 as QtSablony
    
    //jeto vlastně combobox ve kterým je strčený nějaký políčko stringů ze kterýho si mužem vybírat jednu možnost dycky
    
    Cudlik
    {
        id: tlacitkoRoot
        
        nazev: 'Tlacitko'
        titulek.text: nazev
        
        property string napis: nazev
        property string coPosila: 'tlacitko macknuty'
        
        function prijmout(zprava)
        {
            if(!muzePrijimat)
                return;
            
            console.log('tlacitko by asi jako nemelo bejt vubec schopny prijimat mqtt zpravy :O :O');
    
        }
    
        Button
        {
            id: tlacitko
            
            width: parent.width
            height: maTitulek ? parent.height - titulek.height : parent.height
            y: maTitulek ? titulek.height : 0
            
            // nahradíme původní barvičky svejma nějakejma
            style: ButtonStyle 
            {
                
                background: Rectangle
                {
                    height: control.height
                    width: control.width
                    color : tlacitko.pressed ? barvaAktivni : barvaPozadi
                    border.color: barvaKontury
                    border.width: velikostOkraje
                    radius: zakulaceni
                }
                
                // text strčíme doprostřed a nafouknem aby byl co nejvíc nejvěčí
                label: Text    
                {
    
                    verticalAlignment: Text.AlignVCenter
                    anchors.centerIn: tlacitko
                    text:  napis
                    color: tlacitko.pressed ? barvaPozadi : barvaTextu
                    width: control.width - velikostOkraje*2
                    height: control.height - velikostOkraje*2
                    
                    font.pointSize: 256
                    minimumPointSize: 8
                    fontSizeMode: Text.Fit
                }
                
    
                
    
            }
            
            onClicked:
            {
                zpravaOdCudliku(mqttTopic, coPosila);
            }
        }
        
    
    
    }
    
    
           

    Hodnocení: 100 %

            špatnédobré        

    Obrázky

    plazmový mqtt čudliky na plochu, obrázek 1

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

    Komentáře

    Vložit další komentář

    Petr Fiedler avatar 30.3.2021 01:25 Petr Fiedler | skóre: 35 | blog: Poradna | Brno
    Rozbalit Rozbalit vše Re: plazmový mqtt čudliky na plochu

    Současný desktop vypadá opravdu dobře.

    Gréta avatar 31.3.2021 19:40 Gréta | skóre: 36 | blog: Grétin blogísek | 🇮🇱==❤️ , 🇵🇸==💩 , 🇪🇺==☭
    Rozbalit Rozbalit vše Re: plazmový mqtt čudliky na plochu
    Max avatar 30.3.2021 09:40 Max | skóre: 72 | blog: Max_Devaine
    Rozbalit Rozbalit vše Re: plazmový mqtt čudliky na plochu
    Moc pěkná práce, díky.
    Zdar Max
    Měl jsem sen ... :(
    1.4.2021 13:28 Jaroš
    Rozbalit Rozbalit vše Re: plazmový mqtt čudliky na plochu
    Kam to nasadíš?

    Regards J.
    vencour avatar 30.3.2021 10:06 vencour | skóre: 56 | blog: Tady je Vencourovo | Praha+západní Čechy
    Rozbalit Rozbalit vše Re: plazmový mqtt čudliky na plochu
    Je někdo, kdo by viděl radši jednorožce místo tučňáků? A ve stejném smyslu jako jsou tu tučňáci?
    Ty nejhlubší objevy nečekají nutně za příští hvězdou. Jsou uvnitř nás utkány do vláken, která nás spojují, nás všechny.
    30.3.2021 10:17 figliar0 | skóre: 6 | blog: figliarstva | Košice
    Rozbalit Rozbalit vše Re: plazmový mqtt čudliky na plochu
    Ne.
    Max avatar 30.3.2021 11:28 Max | skóre: 72 | blog: Max_Devaine
    Rozbalit Rozbalit vše Re: plazmový mqtt čudliky na plochu
    Ne
    Zdar Max
    Měl jsem sen ... :(
    vencour avatar 30.3.2021 18:28 vencour | skóre: 56 | blog: Tady je Vencourovo | Praha+západní Čechy
    Rozbalit Rozbalit vše Re: plazmový mqtt čudliky na plochu
    Ok, jiný styl to vyřeší, někdo doma bude mít radost :-) až uvidí jednorožce :-)
    Ty nejhlubší objevy nečekají nutně za příští hvězdou. Jsou uvnitř nás utkány do vláken, která nás spojují, nás všechny.
    Max avatar 30.3.2021 11:29 Max | skóre: 72 | blog: Max_Devaine
    Rozbalit Rozbalit vše Re: plazmový mqtt čudliky na plochu
    BTW, nic ti asi nebrání v tom si vytvořit vlastní styl s jednorožcem místo tučňáka.
    Zdar Max
    Měl jsem sen ... :(
    vencour avatar 30.3.2021 12:01 vencour | skóre: 56 | blog: Tady je Vencourovo | Praha+západní Čechy
    Rozbalit Rozbalit vše Re: plazmový mqtt čudliky na plochu
    I tohle (2 tuxové) vypadá hezky. Občas se mi zápisek líbí víc než jindy ... nebo aspoň nějaké obraty.
    Ty nejhlubší objevy nečekají nutně za příští hvězdou. Jsou uvnitř nás utkány do vláken, která nás spojují, nás všechny.
    Gréta avatar 31.3.2021 12:52 Gréta | skóre: 36 | blog: Grétin blogísek | 🇮🇱==❤️ , 🇵🇸==💩 , 🇪🇺==☭
    Rozbalit Rozbalit vše Re: plazmový mqtt čudliky na plochu
    otasomil avatar 30.3.2021 17:19 otasomil | skóre: 39 | blog: puppylinux
    Rozbalit Rozbalit vše Re: plazmový mqtt čudliky na plochu
    Pekne, poucne.

    Info o mnozstvi CO2 mi pripomelo mrknout do technickeho slovniku z roku 1956 abych zjistil ze slozeni vzduchu je az do dneska prakticky stejne. Dnesek A tehdejsi udaje:
    Kyslik: 20,75%
    Dusik: 77.08%
    Oxid uhlicity: 0.03%
    Ostatni neuvadim pro nadbytecnost a zanedbatelna cisla.
    K čemu hudba, která nevede k extázi... Stop MDMA !!! I spam umí být roztomilý
    30.3.2021 21:28 Great Gréta
    Rozbalit Rozbalit vše Re: plazmový mqtt čudliky na plochu
    Příroda: nárůst CO2 o 30% za 70 let

    Otasomil: PRaKTicKy stEJné
    otasomil avatar 30.3.2021 21:53 otasomil | skóre: 39 | blog: puppylinux
    Rozbalit Rozbalit vše Re: plazmový mqtt čudliky na plochu
    JJ je to cca 30% + ovsem v celkove casti procentualniho slozeni vzduchu je CO2 takrka zanedbatelna polozka jak pred 70 lety tak dnes. Jo ekoteroristi reknou narust o 30% a hned tim vydesi celou planetu. Cili kdyz do litru vody naleju cca 0.3 ml slivovice tak mam hned narust alkoholu ve sklenici vody o 100% coz je desive nicmene nic to neznamena.
    K čemu hudba, která nevede k extázi... Stop MDMA !!! I spam umí být roztomilý
    Jendа avatar 31.3.2021 01:49 Jendа | skóre: 78 | blog: Jenda | JO70FB
    Rozbalit Rozbalit vše Re: plazmový mqtt čudliky na plochu
    ovsem v celkove casti procentualniho slozeni vzduchu je CO2 takrka zanedbatelna polozka jak pred 70 lety tak dnes
    A z hlediska té sledované aktivity? (absorpce odraženého/vyzářeného IR a z toho vyplývajíví vliv na teplotu a obecně klima)
    Cili kdyz do litru vody naleju cca 0.3 ml slivovice tak mam hned narust alkoholu ve sklenici vody o 100% coz je desive nicmene nic to neznamena.
    1) O nekonečně %, 2) Když ti pustím do pokoje 0.03% kyanovodíku tak se ti to taky nebude líbit. A přitom jsou to jenom 0.03%!
    otasomil avatar 31.3.2021 05:11 otasomil | skóre: 39 | blog: puppylinux
    Rozbalit Rozbalit vše Re: plazmový mqtt čudliky na plochu
    Kyanovodik je nejjedovatejsi latka co vubec existuje. Zato kdyz si do pokoje privedu slecnu tak za hodinu mi tam vyfuni tolik CO2 ze jeho hladina vzroste o stovky % takze cele to hrani si s tisicinama % CO2 mi zavani ekoterorismem.
    K čemu hudba, která nevede k extázi... Stop MDMA !!! I spam umí být roztomilý
    Max avatar 31.3.2021 08:59 Max | skóre: 72 | blog: Max_Devaine
    Rozbalit Rozbalit vše Re: plazmový mqtt čudliky na plochu
    slecnu tak za hodinu mi tam vyfuni tolik CO2 ze jeho hladina vzroste o stovky %

    Ty si ale věříš :D. To u mě za ty dvě minuty nestačí nadejchat CO2 ani pro jednu kytičku :).
    Zdar Max
    Měl jsem sen ... :(
    otasomil avatar 31.3.2021 16:13 otasomil | skóre: 39 | blog: puppylinux
    Rozbalit Rozbalit vše Re: plazmový mqtt čudliky na plochu
    To u mě za ty dvě minuty...
    Teda to je rychlovka. Musim se vsak omluvit ze jsem se nespravne genderove vyjadril a ze jsem misto slecny mel napsat clovek.
    K čemu hudba, která nevede k extázi... Stop MDMA !!! I spam umí být roztomilý
    Gréta avatar 31.3.2021 19:39 Gréta | skóre: 36 | blog: Grétin blogísek | 🇮🇱==❤️ , 🇵🇸==💩 , 🇪🇺==☭
    Rozbalit Rozbalit vše Re: plazmový mqtt čudliky na plochu

    přeci ji jako hnedka potom nestrčíš ven zadveře ne :D

    Max avatar 31.3.2021 20:17 Max | skóre: 72 | blog: Max_Devaine
    Rozbalit Rozbalit vše Re: plazmový mqtt čudliky na plochu
    To ne, je to naopak, za dveře jdu já :D
    Zdar Max
    Měl jsem sen ... :(
    Jendа avatar 31.3.2021 11:01 Jendа | skóre: 78 | blog: Jenda | JO70FB
    Rozbalit Rozbalit vše Re: plazmový mqtt čudliky na plochu
    Kyanovodik je nejjedovatejsi latka co vubec existuje.
    Takže to vypadá, že asi nejde tvrdit „je něčeho jenom 0.03%, nemůže to mít žádný vliv“, že?
    Zato kdyz si do pokoje privedu slecnu tak za hodinu mi tam vyfuni tolik CO2 ze jeho hladina vzroste o stovky % takze cele to hrani si s tisicinama % CO2 mi zavani ekoterorismem.
    Ale ono přece nejde o to, že by zvýšení CO2 z 270 na současných 420 nebo za pár let predikovaných 500 ppm nějak přímo škodilo člověku (jak se snažíš naznačit na příkladu s místností) ve smyslu dýchání, ale o to, že CO2 absorbuje infračervené záření a tím způsobuje oteplování.

    To je strawman, nebo tomu opravdu nerozumíš?
    31.3.2021 12:16 Mayhem
    Rozbalit Rozbalit vše Re: plazmový mqtt čudliky na plochu
    Herr Jenda, jak jste to meril? Jaka mate data, kdyz tvrdite udaje o PPM? A jake byly hodnoty teto veliciny v minulosti? Nebyly nahodou i nekolikanasobne vyssi? Opravdu si myslite, ze tech vasich 420PPM, ktera mate zmerena nevim odkud, jsou antropogenniho puvodu? A i kdyby, je na tom neco spatneho?
    Jendа avatar 31.3.2021 12:23 Jendа | skóre: 78 | blog: Jenda | JO70FB
    Rozbalit Rozbalit vše Re: plazmový mqtt čudliky na plochu
    Chápu správně, že tvrdíš, že ve vzduchu na zemi aktuálně není 420 ppm, že to je konspirace a ve skutečnosti je mnohem míň?

    Pak si bohužel nemáme co říct. Hezký den.
    31.3.2021 13:38 Mayhem
    Rozbalit Rozbalit vše Re: plazmový mqtt čudliky na plochu
    Ne, nechapes to spravne. Netvrdim, ze neni 420. Ja osobne to netusim. Zajima mne, jaka mas data pro podlozeni tohoto sveho tvrzeni. Nebo to beres jako dogma?
    31.3.2021 15:17 kek
    Rozbalit Rozbalit vše Re: plazmový mqtt čudliky na plochu
    *42069 ppm
    Gréta avatar 31.3.2021 13:10 Gréta | skóre: 36 | blog: Grétin blogísek | 🇮🇱==❤️ , 🇵🇸==💩 , 🇪🇺==☭
    Rozbalit Rozbalit vše Re: plazmový mqtt čudliky na plochu

    co2 prej teda jako pomáhá maši planetě zachytávat a udržovat teplo. noa díky tomu tady v noci neni taková zima jako třeba na měsíci když tam nesvítí sluníčko. chceš snad ze země mit nevobyvatelnou měsíční pustinu???? :O :O :D ;D

    31.3.2021 13:39 Mayhem
    Rozbalit Rozbalit vše Re: plazmový mqtt čudliky na plochu
    Presne. A diky otepleni klesne spotreba uhli, protoze strejcove nebudou muset tolik nakladat do kotlu, takze vyssi co2 bude mit pozitivni vliv na emise z uhli.
    Jendа avatar 31.3.2021 11:06 Jendа | skóre: 78 | blog: Jenda | JO70FB
    Rozbalit Rozbalit vše Re: plazmový mqtt čudliky na plochu
    A pedantická:
    Kyanovodik je nejjedovatejsi latka co vubec existuje.
    V žádném případě, existuje hromada zejména organických látek (např. botulotoxin), které jsou o mnoho řádů jedovatější.
    Zato kdyz si do pokoje privedu slecnu tak za hodinu mi tam vyfuni tolik CO2 ze jeho hladina vzroste o stovky % takze cele to hrani si s tisicinama % CO2 mi zavani ekoterorismem.
    V tomto okamžiku je už pro dorozumění se v diskuzi zásadní rozlišovat mezi procenty a procentními body, protože pokud jsi v obou případech myslel buď procenta, nebo procentní body, tak jsi napsal naprostý nesmysl.
    otasomil avatar 31.3.2021 16:20 otasomil | skóre: 39 | blog: puppylinux
    Rozbalit Rozbalit vše Re: plazmový mqtt čudliky na plochu
    Estli je ve zduchu neceho "jen nedychatelnyho" 0.03 nebo 0.04% tak se nemame ceho obavat a vse kolem je jen ekoterorismus.

    Jeden nejmenovany obchodni retezec "podvadel" ze v prodavane uzenine je 8% masa pritom inspekce zjistila ze je tam jen 6% cili maso tam zkratka neni a je uz uplne jedno jestli 6 nebo 8% kdyz to pes nezere a zakutali pod stul protoze nevi co s tim parkem ma delat.
    K čemu hudba, která nevede k extázi... Stop MDMA !!! I spam umí být roztomilý
    31.3.2021 16:27 Make Greta Great Again
    Rozbalit Rozbalit vše Re: plazmový mqtt čudliky na plochu
    A dokážeš myslet i dál než na konec svýho rypáku?
    31.3.2021 17:00 podlesh
    Rozbalit Rozbalit vše Re: plazmový mqtt čudliky na plochu
    Estli je ve zduchu neceho "jen nedychatelnyho"
    Já jsem pro každou srandu, ale tady mi ten vtip nějak uniká. Je to narážka na nějakou hlášku, něco co někdo řekl v televizi, nebo nějaký meme, nebo...?? Nechápu.
    otasomil avatar 31.3.2021 20:45 otasomil | skóre: 39 | blog: puppylinux
    Rozbalit Rozbalit vše Re: plazmový mqtt čudliky na plochu
    Neni to zadna narazka jen to ze za 70 let se zvysilo mnozstvi CO2 cca o 30% a tak mame dnes ve vzduchu misto 0.0300% CO2 0.0407% to je vse. Medialne je narust 30% totalni katastrofa ale prirustku 0.0107% by si nikdo nevsiml, nebylo by to popularni a uz vubec ne alarmujici, ekoteroristi by memeli cim argumentovat protoze opravdu uprimne hodnota 0.0107% neni nic co by vyvolalo jakekoli obavy laicke verejnosti. Vse je jen o tom jak to svetu podate, nic vic. To jestli nas prirustek 0.0107% zabije nebo zpusobi nejake globalni oteplovani je vec dalsi.
    K čemu hudba, která nevede k extázi... Stop MDMA !!! I spam umí být roztomilý
    1.4.2021 13:22 podlesh
    Rozbalit Rozbalit vše Re: plazmový mqtt čudliky na plochu
    To jestli nas prirustek 0.0107% zabije nebo zpusobi nejake globalni oteplovani je vec dalsi.
    To je právě to co nechápu - kdy'ž je tohle to "další", tak co je to první?

    Asi mi furt uniká na co to má být narážka...
    otasomil avatar 1.4.2021 16:54 otasomil | skóre: 39 | blog: puppylinux
    Rozbalit Rozbalit vše Re: plazmový mqtt čudliky na plochu
    Co je na tom k nepochopeni? 0.0107% nas rozhodne nezabije a ani nezpusobi zadne jine problemy ale 30% to je opravdu katastrofa.
    K čemu hudba, která nevede k extázi... Stop MDMA !!! I spam umí být roztomilý
    2.4.2021 13:29 podlesh
    Rozbalit Rozbalit vše Re: plazmový mqtt čudliky na plochu
    K nepochopení je kdes to vzal. Já jsem nikdy nic takového neslyšel.
    Gréta avatar 31.3.2021 19:36 Gréta | skóre: 36 | blog: Grétin blogísek | 🇮🇱==❤️ , 🇵🇸==💩 , 🇪🇺==☭
    Rozbalit Rozbalit vše Re: plazmový mqtt čudliky na plochu

    proto si jako ten co2 rudozelený 'experťy' vybraly protože je to taková duchařina :D ;D tvl blbá vodní pára má víc jak 60% podíl na tom údajným globálním voteplovaní proč se neřeší nějaký vysoušení potoků/rybníků??? toby mělo víc věčí význam než dělání s 0.00000000000000000% něčeho neviditelnýho/nemastnýho/neslanýho. ale tady ňák tak intujitivně cejtíme žeto je jakože uplně pitomej nápad bojovat proti vodě/vodní páře :O ;D

    bojovat proti co2 je stejná pitomina akorátže to rudozelený jakoby neviděj nebo vidět nechtěj :O :/

    Jendа avatar 31.3.2021 20:14 Jendа | skóre: 78 | blog: Jenda | JO70FB
    Rozbalit Rozbalit vše Re: plazmový mqtt čudliky na plochu
    Estli je ve zduchu neceho "jen nedychatelnyho" 0.03 nebo 0.04% tak se nemame ceho obavat a vse kolem je jen ekoterorismus.
    Ale „ekoteroristi“ přece nebojují proti CO2 kvůli tomu, že zhoršuje lidské dýchání (a v těchto koncentracích opravdu nijak znatelně nezhoršuje), ale kvůli tomu, že otepluje planetu!
    Gréta avatar 31.3.2021 13:08 Gréta | skóre: 36 | blog: Grétin blogísek | 🇮🇱==❤️ , 🇵🇸==💩 , 🇪🇺==☭
    Rozbalit Rozbalit vše Re: plazmový mqtt čudliky na plochu

    škoda žeto co2 moc na dělání globálního tepla nefunguje :O :/ si myslim že kdyby to co2 fakt jako fungovalo tak by bylo samo vo sobě uplně supr zelenou technologií na akumulaci ir záření/tepla a mohli by jsme si zněj udělat takovou jakože malilinkatou dysonovu sféru v atmosféře planety :D ;D

    xsubway avatar 30.3.2021 23:06 xsubway | skóre: 13 | blog: litera_scripta_manet
    Rozbalit Rozbalit vše Re: plazmový mqtt čudliky na plochu
    "Brno odpálit bum"? Nebudou se pražští cítit ochuzeni? :D
    Max avatar 30.3.2021 23:40 Max | skóre: 72 | blog: Max_Devaine
    Rozbalit Rozbalit vše Re: plazmový mqtt čudliky na plochu
    Naopak, pražští mají to tlačítko, brňáci ne :).
    Zdar Max
    Měl jsem sen ... :(
    Gréta avatar 31.3.2021 12:46 Gréta | skóre: 36 | blog: Grétin blogísek | 🇮🇱==❤️ , 🇵🇸==💩 , 🇪🇺==☭
    Rozbalit Rozbalit vše Re: plazmový mqtt čudliky na plochu

    jestli těto jako uklidní tak praha je na seznamu cílů taky :D :D ;D ;D

    Marián Kyral avatar 31.3.2021 08:00 Marián Kyral | skóre: 29 | blog: Sem_Tam | Frýdek-Místek
    Rozbalit Rozbalit vše Re: plazmový mqtt čudliky na plochu
    Mé oči krvácí…
    Gréta avatar 31.3.2021 12:47 Gréta | skóre: 36 | blog: Grétin blogísek | 🇮🇱==❤️ , 🇵🇸==💩 , 🇪🇺==☭
    Rozbalit Rozbalit vše Re: plazmový mqtt čudliky na plochu

    si mužeš nastavit nějaký svoje barvičky když seti tydlety jakože nelíběj :D ;D

    Marián Kyral avatar 2.4.2021 18:11 Marián Kyral | skóre: 29 | blog: Sem_Tam | Frýdek-Místek
    Rozbalit Rozbalit vše Re: plazmový mqtt čudliky na plochu
    To nejsou barvičky. To je zkriplená čeština co se se nedá číst. Si všichni nemusí zrovna brát příklad z Andreje.
    1.4.2021 22:44 Helmut
    Rozbalit Rozbalit vše Re: plazmový mqtt čudliky na plochu
    Tak si kup ochranu očí.
    31.3.2021 08:48 j
    Rozbalit Rozbalit vše Re: plazmový mqtt čudliky na plochu
    Koukam ze se ti konecne povedlo zprovoznit IPv5 ;D.

    Jinak soudruh programator rika, ze void je fujky fuj, ze by kazda funkce at uz dela cokoli mela neco vracet.

    ---

    Dete s tim guuglem dopice!
    Gréta avatar 31.3.2021 12:46 Gréta | skóre: 36 | blog: Grétin blogísek | 🇮🇱==❤️ , 🇵🇸==💩 , 🇪🇺==☭
    Rozbalit Rozbalit vše Re: plazmový mqtt čudliky na plochu

    akorátže když jakože přetěžuju metody poděděný z qt nebo tam mam nějakej danej ukazatel na funkci jako datovej typ definovanej vtom mqttasync.h tak stim toho jako moc nejde dělat :O ;D

    a jestli toje fujkyfuj nevim v c++ mužou funkce blejt vyjímky a to je asi jako víc zprávnější způsob jak to jako dělat :O :O

    Agent avatar 31.3.2021 18:54 Agent | blog: Life_in_Pieces | HC city
    Rozbalit Rozbalit vše Re: plazmový mqtt čudliky na plochu
    Radši nám ukaž tvoje dudlíky :-)
    Nevěděl zpočátku, co si počít, jak žít, co dělat, ale brzy se vpravil do role samotáře.
    Gréta avatar 31.3.2021 19:17 Gréta | skóre: 36 | blog: Grétin blogísek | 🇮🇱==❤️ , 🇵🇸==💩 , 🇪🇺==☭
    Rozbalit Rozbalit vše Re: plazmový mqtt čudliky na plochu

    Založit nové vláknoNahoru

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