Počítačová hra Knytt napsaná v Multimedia Fusion 2 byla vydána před 20 lety. Při této příležitosti byl dnes představen moderní port (YouTube) této plošinovky na současné operační systémy pod názvem Knytt Classic. Je zdarma k dispozici na Steamu a GOG.com.
Americká technologická společnost Meta Platforms představila nový model umělé inteligence (AI) Muse Glimmer. Model je menší než přední modely AI od konkurence a má běžet přímo na počítačích uživatelů. Meta model zpřístupní jako open source, tedy otevřený software. Nový model je navržen tak, aby zvládal takzvané agentní úkoly na počítačích se spotřebitelskou grafickou kartou. Klade si tak za cíl uspokojit poptávku po systémech AI, které běží přímo na zařízeních uživatelů.
V pátek 28. srpna 2026 se v pražském Karlíně uskuteční již osmý Mobilní Hackday. Akce začne v 10:00 a potrvá až do večera. Setkání proběhne v prostorách SUSE Linux, s.r.o. na adrese Křižíkova 148/34, Praha 8 – Karlín. Nejbližší zastávkou je Křižíkova, kam se lze dostat tramvají i metrem. Na programu budou například novinky z posledních měsíců, možnosti, jak si zjednodušit práci s LLM/AI, a také nová linuxová distribuce BengalOS, včetně … více »
Jakub Vrána vydal Adminer ve verzi 6.0.0 s více než 130 změnami: "Většina změn vznikla s asistencí Claude Opus 5. Někteří lidi se bojí, že AI asistence může kód zamořit technickým dluhem. To je jistě pravda, pokud vývojář všechny změny bezduše odbouchne Enterem. Ale pokud si pořádně projde plán, vyjedná v něm změny a pak totéž udělá i s vygenerovaným kódem, kvalita kódu stoupne a technický dluh naopak klesne. Je to jako párové programování s
… více »Sam Aaron vydal novou major verzi 5.0.0 aplikace Sonic Pi (Wikipedie) určené také pro výuku programování pomocí skládání hudby. Přehled novinek na GitHubu. Instalovat lze také z Flathubu.
U příležitosti 30. výročí vydání počítačové hry Quake byla vydána nová epizoda s názvem Dawn of the Machine (Steam).
Vládní CERT upozorňuje (𝕏) na sérii bezpečnostních záplat (CVSS 9.9) v produktech Cisco řešících kritické zranitelnosti umožňující obejití autentizace, eskalaci oprávnění, vzdálené spuštění kódu a odepření služby. Úspěšné zneužití může útočníkům umožnit získat neoprávněný přístup k dotčeným systémům, kompromitovat zařízení Cisco Catalyst SD-WAN a Cisco IOS XE, spustit libovolný kód, zpřístupnit citlivé informace nebo narušit dostupnost postižených systémů.
Soud v americkém státě Nové Mexiko ve čtvrtek nařídil internetové společnosti Meta Platforms zaplatit 567 milionů dolarů (téměř 12 miliard Kč) za újmy, které její platformy působí mladým lidem. S přihlédnutím k dřívějšímu verdiktu tak má společnost celkem zaplatit 942 milionů dolarů, což je malý zlomek jejího ročního výnosu, který loni činil 60 miliard dolarů. Čtvrteční verdikt firmě také nařizuje, aby změnila způsob, jakým její
… více »Mark Russinovich (CTO v Microsoft Azure) se na LinkedIn pochlubil svým projektem MS Paint Doom napsaným pomocí Claude. Hru Doom umožňuje hrát v programu Malování (Microsoft Paint). Malování funguje jako monitor. Herní engine (ViZDoom) běží na pozadí a každý vykreslený snímek hry vkládá automaticky přes schránku (clipboard) do Malování.
Platformy ChatGPT i Roblox by mohly být zařazeny na seznam mimořádně velkých on-line platforem nebo internetových vyhledávačů, na něž se vztahují zvláštní podmínky podle nařízení o digitálních službách (DSA). Vzhledem k tomu, že ChatGPT i Roblox oznámily počet uživatelů nad prahovou hodnotou DSA, je toto označení „rozhodně možné“ a mohlo by „přijít dříve či později“. On-line platformy a vyhledávače zařazené na seznamy DSA musejí
… více »Kterak propojit C++ a Web v praktické aplikaci.
Ve firmě Hobrasoft vyvíjíme distribuovaný CRM systém Deko the CRM. Různých CRM systémů jsou na světě mraky, takže přijít s něčím novým je obtížné. Za výhodu našeho CRM považujeme nezávislost na připojení k internetu. Databáze CouchDB, na které je aplikace postavená, dovolí uživatelům pracovat offline a přitom nejsou nijak omezení ve sdílení dat. Deko je určené jak pro Windows, tak pro Linux.
Jedním z úkolů, před které nás potřeby aplikace postavily, byly tiskové sestavy. Celá aplikace je napsaná v C++ a Qt, takže se nabízela možnost použít C++ i pro tvorbu sestav. Ale tvořit něco v C++ je nepružné i pro nás a představa, že by si mohl uživatel sám vytvořit sdílenou knihovnu se sestavou je čirá utopie. Jak z takové situace ven?
Můj první nápad byl vlastní tabulkový kalkulátor vestavěný v aplikaci. Uživatelé jsou na tabulky zvyklí, nemuselo by jim to činit potíže. Malý průzkum bojem ale ukázal, že potíže by mohl činit tabulkový kalkulátor nám - naprogramovat něco použitelného je pracné.
Druhý nápad bylo použít HTML. Něco vzdáleně podobného už jsme měli hotové:
http://weko.hobrasoft.cz/timesheet/default/288KFTU
Ale to je napsané v PHP a potřebuje to celý ten veliký cirkus spojený s webovými aplikacemi - http server, php interpreter a napojení na databázi (u každého uživatele jiné).
Naštěstí k provádění nějakého programu ve webovém prohlížeči není potřeba PHP, webové prohlížeče už léta dokáží zpracovávat JavaScript a knihoven pro manipulaci HTML stránek je spousta. Spousta je i programátorů - na rozdíl od C++ dnes HTML a Javascript zvládá velké množství lidí.
Takže stačí už jen napsat a připojit k aplikaci webový prohlížeč. V Qt je situace jednoduchá: stačí přilinkovat webkit.
Sestavy obvykle čerpají své podklady z nějaké databáze. Databázi je proto nutné zpřístupnit i do webového prohlížeče. Prohlížeče získávají data dvojím způsobem: pomocí url, například:
nebo přes JavaScript, každý prohlížeč ve speciálním objektu document zpřístupňuje zobrazovanou html stránku:
var html = document.documentElement.outerHTML;
V aplikaci Deko jsme databázi zpřístupnili podobně. Jednak přes speciální url:
deko:///id-dokumentu-v-databazi
nebo přes objekt JavaScriptu:
var dokument = deko.get('id-dokumentu-v-databazi');
Vestavěný webkit se k tomu dá donutit poměrně snadno.
Třída WebView obsahuje webovou stránku, u níž musíme přepsat třídu QNetworkAccessManager, aby rozuměla i našemu schematu deko, zajistí to pár řádků kódu:
QNetworkAccessManager *om = f_view->page()->networkAccessManager(); REPORT_access_manager *nm = new REPORT_access_manager(om, this); f_view->page()->setNetworkAccessManager(nm);
Původní QNetworkAccessManager je nahrazený naším vlastním. Nedělá nic jiného, než že ověří url schema a pokud je schéma deko, vytvoří vlastní odpověď, jinak zavolá standardní proceduru:
class REPORT_access_manager : public QNetworkAccessManager {
Q_OBJECT
public:
REPORT_access_manager(QNetworkAccessManager *, QObject *);
QNetworkReply *createRequest( QNetworkAccessManager::Operation,
const QNetworkRequest&,
QIODevice*);
};
REPORT_access_manager::REPORT_access_manager(
QNetworkAccessManager *manager,
QObject *parent) : QNetworkAccessManager(parent) {
setCache (manager->cache());
setCookieJar (manager->cookieJar());
setProxy (manager->proxy());
setProxyFactory (manager->proxyFactory());
}
QNetworkReply *REPORT_access_manager::createRequest(
QNetworkAccessManager::Operation operation, const QNetworkRequest &request,
QIODevice *device) {
if (request.url().scheme() != "deko") {
return QNetworkAccessManager::createRequest(operation, request, device);
}
if (operation != GetOperation) {
return QNetworkAccessManager::createRequest(operation, request, device);
}
return new REPORT_reply (request.url());
}
Vrácená odpověď je mírně rozšířená třída QNetworkReply
class REPORT_reply : public QNetworkReply {
Q_OBJECT
public:
REPORT_reply(const QUrl&);
void abort() {} ;
qint64 bytesAvailable() const;
bool isSequential() const { return true; }
protected:
qint64 readData(char *data, qint64 maxSize);
private:
QByteArray content;
qint64 offset;
};
REPORT_reply::REPORT_reply(const QUrl& url) {
offset = 0;
open(ReadOnly | Unbuffered);
// REQUEST je naše třída pro přístup do databáze, vrací obvykle JSON řetězec
// Při vaší vlastní implementaci sem doplňte vlastní přístup do databáze
REQUEST rq;
rq.setBinary(true);
rq.get(url.path().toUtf8());
content = rq.data();
setHeader(QNetworkRequest::ContentTypeHeader, rq.contentType().toString());
setHeader(QNetworkRequest::ContentLengthHeader, QVariant(content.size()));
QTimer::singleShot(0, this, SIGNAL(metaDataChanged()));
QTimer::singleShot(0, this, SIGNAL(readyRead()));
QTimer::singleShot(0, this, SIGNAL(finished()));
}
qint64 REPORT_reply::bytesAvailable() const {
qint64 bc = content.size() - offset;
return bc;
}
qint64 REPORT_reply::readData(char *data, qint64 maxSize) {
if (offset < content.size()) {
qint64 number = qMin(maxSize, content.size() - offset);
memcpy(data, content.constData() + offset, number);
offset += number;
return number;
} else {
return -1;
}
}
K webové stránce zobrazené ve webkitu lze snadno připojit libovolný QObject:
QWebFrame *frame = f_view->page()->mainFrame();
frame->addToJavaScriptWindowObject("deko", m_report_script);
Pod jménem deko bude objekt m_report_script přístupný ve webové stránce pomocí JavaScriptu.
U tohoto objektu uvedu pouze deklaraci, samotný kód už není tak důležitý:
class REPORT_SCRIPT : public QObject {
Q_OBJECT
public:
REPORT_SCRIPT(QObject *parent);
Q_INVOKABLE QString id();
Q_INVOKABLE QVariant get(const QString& id);
Q_INVOKABLE QVariant document(const QString& id);
Q_INVOKABLE QVariant linksToMe(const QString& id);
Q_INVOKABLE QVariant linksFromMe(const QString& id);
Q_INVOKABLE QString hash(const QString& text);
Q_INVOKABLE void begin() { emit jobBegin(); }
Q_INVOKABLE void end() { emit jobEnd(); }
Q_INVOKABLE QString userid();
signals:
void jobBegin();
void jobEnd();
};
Makrem Q_INVOKABLE deklaruji metodu jako přístupnou z JavaScriptu. Zajímavé je předávání výsledné hodnoty (podobně lze předávat i parametry). Vrací-li metoda QVariant, použije se v JavaScriptu taková hodnota jako objekt. V C++ vypadá vytvoření takového objektu například takto:
QVariantMap data; data["_id"] = "id-meho-objektu"; data["name"] = "Jmeno objektu"; QVariantList list; list << "abcd" << "1234"; data["list"] = list; return data;
V Javascriptu se interpretuje stejně, jako by se interpretoval tento JSON literár:
{ "_id": "id-meho-objektu", "name": "Jmeno objektu", "list": [ "abcd", "1234"] }
V Javascriptu je použití snadné:
var x = deko.metoda();
var id = x._id;
var name = x.name;
for (var i=0; i<x.list.length; i++) {
// Udělej něco
neco( deko.list[i] );
}
Nakonec několik ukázek: Vestavěná google mapa, hotová sestava a kus zdrojového tvaru sestavy. S webkitem dostanete i luxusní debugger - ten je vidět na posledním obrázku.
Tiskni
Sdílej:
QNetworkAccessManager a ReportAccessManager, nebo ještě lépe Report::NetworkAccessManager.
CamelCase... jdu blejt...
Díky za zápisek. Taky se chystám pustit do jednoho projektu s Qt(WebKitem), tak mě potěšilo, že tam jsou tyhle věci celkem jednoduché.
Ta VELKÁ písmena a podtržítka v názvech tříd se mi taky nelíbí, ale nevím, jaké jsou konvence v okolním kódu, tak to nechci hodnotit.
Mám ale jednu věcnou připomínku k návrhu: jak funguje třída REQUEST („…je naše třída pro přístup do databáze“)? To je nějaký singleton? Kde vezme spojení do databáze nebo jiné zdroje? IMHO by bylo lepší, aby je dostávala jako parametr z toho kontextu, ve kterém je používána, ne že si je někde obstará sama.
...proxy objekt...To mě zajímá. Nevyznám se příliš ve webových technologiích, nevím, co si pod tím představit. Jinak vlastní protokol používám právě proto, že nepředpokládám použití jinde, než v rámci aplikace. Navíc v režimu, kdy předem nevím, jak připojení k databázi vypadá a kdy jednu sestavu může používat více lidí s naprosto odlišným připojením k databázi.
/hello/world namísto http://example.org/hello/world či deko:/hello/world. Pak je můžeš vzít jak jsou a poslat po HTTP do běžného prohlížeče.
No a aby fungovalo připojení k databázi, tak místo deko objektu, který máš teď, tam dáš proxy objekt, což je v Javascriptu implementovaný obyčejný objekt přeposílající volání metod na server a vracející obdržené odpovědi. Na serveru pak bude za nějakým HTTP API schovaný skutečný deko objekt, který udělá všechnu dřinu. Pokud proxy i originál budou mít stejné API, můžeš bezezměn zveřejnit tiskové sestavy na webu i v aplikaci a navíc to bude skoro bez práce (stačí udělat jen ten proxy objekt a aplikaci spustit jako démona bez GUI).
Pointa je v tom, aby jsi si teď nezadělal na problémy v budoucnu, kdy s tím budeš chtít něco dělat a budeš mít spoustu hotových sestav.
QWebView::setUrl("deko:/hello/world/"); by mělo stačit.
QWebView::setHtml( html, QUrl("deko:///hello/world") );
Html se bere z externího editoru