Free Software Foundation (FSF) spustila projekt Librephone, jehož cílem je vytvoření svobodného operačního systému pro mobilní telefony. Bez binárních blobů.
Byla vydána verze 7 s kódovým název Gigi linuxové distribuce LMDE (Linux Mint Debian Edition). Podrobnosti v poznámkách k vydání. Linux Mint vychází z Ubuntu. LMDE je postaveno na Debianu.
Byl vydán Mozilla Firefox 144.0. Přehled novinek v poznámkách k vydání a poznámkách k vydání pro vývojáře. Vypíchnout lze lepší správu profilů. Řešeny jsou rovněž bezpečnostní chyby. Nový Firefox 144 bude brzy k dispozici také na Flathubu a Snapcraftu.
Discord potvrdil únik osobních údajů přibližně 70 000 uživatelů. Incident se týká uživatelů po celém světě, především těch, kteří v rámci ověřování svého věku nahráli do aplikace doklad totožnosti. Únik informací se netýkal systémů samotné platformy, ale došlo k němu přes kompromitovaný účet pracovníka zákaznické podpory u externího poskytovatele služeb.
Americká společnost OpenAI, která provozuje chatbota ChatGPT, kvůli výrobě vlastních procesorů pro umělou inteligenci (AI) spojí síly s firmou Broadcom. Firmy o tom informovaly (en) ve svém včerejším sdělení. OpenAI se snaží zajistit si výpočetní výkon potřebný k uspokojení rostoucí poptávky po svých službách. Akcie Broadcomu po zprávě výrazně zpevnily.
O víkendu 18. a 19. října lze na brněnském výstavišti navštívit s jednou vstupenkou dvě akce: Maker Faire Brno, "festival tvořivosti, vynálezů a bastlířské radosti", a GameDev Connect, "akci určenou pro všechny současné a hlavně budoucí herní vývojáře, kteří touží proniknout do jednoho z nejúžasnějších průmyslů na světě".
Do 20. října do 19:00 běží na Steamu přehlídka nadcházejících her Festival Steam Next | říjen 2025 (YouTube) doplněná demoverzemi, přenosy a dalšími aktivitami. Demoverze lze hrát zdarma.
O zavedení nástroje na monitorování online konverzací v rámci boje proti dětské pornografii (tzv. Chat Control) měli ministři vnitra rozhodovat na úterním společném zasedání v Lucemburku. Plán dánského předsednictví Rady EU ale před pár dny ztroskotal, když se ukázalo, že Chat Control nemá dostatečnou podporu.
Již toto úterý proběhne každoměsíční akce Virtuální Bastlírna, kterou pořádá projekt MacGyver. Jde o virtuální posezení u piva a volné klábosení o různých zajímavostech ze světa elektroniky, softwaru i techniky. V posledním měsíci se stalo nemálo zajímavostí týkajících se spousty bastlířů - kupříkladu Arduino nyní patří pod Qualcomm, Raspberry Pi vydalo nový počítač, ale potichu i miniaturní compute module. Pro AMS od Bambu Lab se
… více »Google zpřístupňuje své AI nástroje českým univerzitním studentům prostřednictvím předplatného Google AI Pro na 12 měsíců bez poplatku. Platnost nabídky vyprší 9. prosince 2025.
Programoval jsem pár aplikací v Pythonu s použitím PyQt. Dlouho jsem zkoumal, jaký je nejlepší způsob inicializace grafického rozhraní ze souboru *.ui
vygenerovaného pomocí QDesigneru. V jinak dobré dokumentaci je tohle téma poněkud strohé. Takže tady uvedu moje poznatky.
Základním zdrojem informací je oficiální manuál [1]. Dále jsem našel pěkný příklad v diskusním fóru [2]. V zásadě jsou dva druhy přístupu. První spočívá v tom, že soubor *.ui
se přechroustá pomocí utilitky pyuic4
(nainstaluje se při instalaci PyQt
) a vznikne tak pythonovský soubor, který se dá naimportovat a použít (je tedy nutný mezikrok, který se v lepším případě provádí pomocí makefile
, v horším ručně). Tento způsob je v oficiální dokumentaci [1] dobře posán i s příklady. Druhý způsob je použití modulu uic
(přesněji PyQt4.uic
), který umožňuje dynamicky načítat přímo soubor *.ui
a není potřeba žádný mezikrok. Tento způsob je v dokumentaci [1] popsán poněkud stručněji a bez příkladů. Upřednostňuji druhý způsob, který teď rozeberu.
Zatímco v příkladech na internetu jsou krátké skripty, které nejsou psány objektově, v praxi je potřeba zapouzdřit kód do objektu, se kterým se dá pracovat odjinud. V následujících příkladech budu tedy vytvářet třídy, které stačí v ideálním případě naimportovat a jedním příkazem spustit, aniž by se člověk musel zabývat konkrétním použitím knihovny PyQt
. Můj prográmek umí jenom to, že při kliknutí na tlačítko vypíše zprávu na standardní výstup.
Dokumentace popisuje 3 způsoby použití. Bez dědění, s jednoduchou dědičností a dvojitou dědičností. Takže začneme od začátku.
Nejdřív si vytvoříme soubor priklad.ui
, který popisuje jednoduché okno aplikace, které obsahuje tlačítko (QPushButton
) s názvem pushButton
. Tlačítko je zatrhávací (checkable
), aby se ve výpisech aspoň střídaly 0 a 1.
Soubor priklad.ui
vypadá takto.
<?xml version="1.0" encoding="UTF-8"?> <ui version="4.0"> <class>MainWindow</class> <widget class="QMainWindow" name="MainWindow"> <property name="geometry"> <rect> <x>0</x> <y>0</y> <width>98</width> <height>46</height> </rect> </property> <property name="windowTitle"> <string>MainWindow</string> </property> <widget class="QWidget" name="centralwidget"> <widget class="QPushButton" name="pushButton"> <property name="geometry"> <rect> <x>9</x> <y>9</y> <width>75</width> <height>23</height> </rect> </property> <property name="text"> <string>PushButton</string> </property> <property name="checkable"> <bool>true</bool> </property> </widget> </widget> </widget> <resources/> <connections/> </ui>
#!/usr/bin/env python import sys from PyQt4 import QtGui, uic class MyApplication: def __init__(self): pass def run(self): self.app = QtGui.QApplication(sys.argv) self.ui = uic.loadUi("priklad.ui") self.ui.pushButton.clicked.connect(self.method_with_some_weird_name) self.ui.closeEvent = self._closeEvent self.ui.show() self.app.exec_() def method_with_some_weird_name(self, value): print "Clicked %d" % value def _closeEvent(self, event): print "Close event" event.accept() if __name__ == '__main__': MyApp = MyApplication() MyApp.run()
Výhody
Qt
, nehrozí konflikt jmen. Při množství metod a vlastností tříd v Qt
je každé pěkné jméno už použito.QtGui.QApplication
si můžu vytvořit ve vlastní třídě ještě před inicializací grafických objektů*.ui
se dá podstrčit až za běhu a měl by jít i za běhu vyměnit.self.ui
budu psát self.__ui
(takový pseudo soukromý atribut), donutí mě to napsat si vlastní funkce na všechno co potřebuji (udělat wrapper). Zbytku programu je potom jedno, jaké grafické rozhraní se používá (a jestli vůbec grafické). Kdybych chtěl aplikovat vzor MVC, asi bych to dělal takhle.Nevýhody
self.ui.pushButton.clicked.connect...
)Qt
je stavěno tak, že se dědí a předefinovává jako na běžícím pásu. Viz předefinování close event (řádek: self.ui.closeEvent = self._closeEvent)Přístup bez dědičnosti ukazuje, že není třeba bezhlavě dědit, i když to znamená práci navíc (viz výše). Pro aplikace s jednoduchým grafickým rozhraním je tento přístup vhodný.
#!/usr/bin/env python import sys from PyQt4 import QtGui, QtCore, uic class MyApplication(QtGui.QMainWindow): def __init__(self): QtGui.QMainWindow.__init__(self) uic.loadUi("priklad.ui", self) def run(self): self.show() self.app.exec_() @QtCore.pyqtSlot(bool, name="on_pushButton_clicked") def method_with_some_weird_name(self, value): print "Clicked %d" % value @QtCore.pyqtSlot(bool) # without this line the slot catches two signals: clicked() and clicked(bool) def on_pushButton_clicked(self, value): print "Clicked2 %d" % value def closeEvent(self, event): print "Close event" event.accept() def main(): app = QtGui.QApplication(sys.argv) MyApp = MyApplication() MyApp.app = app MyApp.run() if __name__ == '__main__': main()
Všimněte si, že při volání metody loadUi
přibyl nepovinný parametr self
.
výhody
clicked()
připojena hned dvojice metod (slotů) pomocí dekorátorů (to jen tak pro ukázku, většinou člověk chce připojit jeden slot). V případě metody method_with_some_weird_name
jsme museli napovědět, k jaké je to vlastně události, kdežto metoda on_pushButton_clicked
už má správný název a nic jsme dělat nemuseli. Samozřejmě nic nám nebrání připojovat sloty ručně jako v případě bez dědičnosti.close event
je jednodušší, prostě se předefinuje metoda closeEvent
. To platí i pro jiné jevy, které však v tomto jednoduchém příkladu nenastávají.nevýhody
Qt
, musím si hlídat jména svých metodQtGui.QApplication
ve vlastní třídě (musela by to být první instrukce konstruktoru), proto ta komplikace s funkcí main
.
Při použití jednoduché dědičnosti získáme pohodlí. Připojení slotů se dá udělat pomocí dekorátorů (ty se můžou řetězit, takže můžeme například všechna kliknutí směřovat do jednoho slotu), předefinování vlastností hlavního okna je rovněž o chlup pohodlnější. Platíme za to silnou závislostí na Qt
, takže například výběr alternativního rozhraní by se musel udělat o patro výš.
#!/usr/bin/env python import sys from PyQt4 import QtGui, QtCore, uic form, formbase = uic.loadUiType( "priklad.ui" ) class MyApplication(formbase, form): def __init__(self): formbase.__init__(self) self.setupUi(self) # inherited from form def run(self): self.show() self.app.exec_() @QtCore.pyqtSlot(bool, name="on_pushButton_clicked") def method_with_some_weird_name(self, value): print "Clicked %d" % value @QtCore.pyqtSlot(bool) # without this line the slot catches two signals: clicked() and clicked(bool) def on_pushButton_clicked(self, value): print "Clicked2 %d" % value def closeEvent(self, event): print "Close event" event.accept() def main(): app = QtGui.QApplication(sys.argv) MyApp = MyApplication() MyApp.app = app MyApp.run() if __name__ == '__main__': main()
Oproti jednoduché dědičnosti je tu ještě komplikace s tím, že se musí předem vytvořit typy form
a formbase
(volání funkce loadUiType
), které se pak použijí jako předek mé třídy.
Třída formbase
je třída z Qt, která je hlavním widgetem v souboru *.ui
. V tomto případě to je PyQt4.QtGui.QMainWindow
.
Třída form
je obyčejná třída, která dědí jenom object
(je to tedy tzv. new style class), není tedy potomkem žádné třídy z Qt
(to je důležité, neboť násobné dědění tříd z Qt
dokumentace zakazuje [3]). Dá se říct, že při použití funkce loadUi
dostanu instanci typu, který vrátí funkce loadUiType
.
výhody
nevýhody
*.ui
a nedá se za běhu změnit
V tomto případě to je použití funkce loadUiType
poněkud velký kalibr, který navíc nepřinesl žádné ulehčení pro programátora. Funkce loadUiType
asi najde využití ve větších aplikacích, kde je třeba vytvářet velké množství stejných oken.
Použití dvojité dědičnosti z mého pohledu nepřináší žádný přínos oproti jednoduché dědičnosti. Aplikací, kde by byla opravdu nutná, je asi hodně málo.
Qt
- http://www.riverbankcomputing.co.uk/static/Docs/PyQt4/html/gotchas.html#multiple-inheritance
Tiskni
Sdílej:
udělej z toho článek:)
nedá se použít automatické připojení slotů a signálů (viz řádek self.ui.pushButton.clicked.connect...)
Dá, ak sa objekt bude deidiť z QObject-u (QMetaObject.connectSlotsByName).
K dvojitej dedičnosti by som dodal ešte veľkú nevýhodu - prvky ui sú public. U C++ sa to rieši privátnou dedičnosťou, takže tam sa dá ešte dvojitá dedičnosť tolerovať, ale v pythone radšej zvyšné spôsoby.
Inak pekný článok, po dlhom čase niečo linuxové ;)
Dá, ak sa objekt bude deidiť z QObject-u (QMetaObject.connectSlotsByName).U postupu bez dědičnosti jsem chtěl opravdu nic nedědit, takže jsem oželel vymoženosti frameworku Qt. S tím problémem u dvojité dědičnosti--public prvky -- to záleží na použití. Třeba se najde někdo, kdo chce míchat logiku aplikace s grafickým rozhraním, a u jednoúčelových miniaplikací na tom až tak nesejde.