Radicle byl vydán ve verzi 1.6.0 s kódovým jménem Amaryllis. Jedná se o distribuovanou alternativu k softwarům pro spolupráci jako např. GitLab.
Zemřel Scott Adams, tvůrce komiksových stripů Dilbert parodujících pracovní prostředí velké firmy.
Sdružení CZ.NIC vydalo novou verzi Knot Resolveru (6.1.0). Jedná se o první vydanou stabilní verzi 6, která je nyní oficiálně preferovanou a doporučovanou verzí, namísto předešlé verze 5. Více o Knot Resolveru 6 je možné se dočíst přímo v dokumentaci.
Byl vydán Linux Mint 22.3 s kódovým jménem Zena. Podrobnosti v přehledu novinek a poznámkách k vydání. Vypíchnout lze, že nástroj Systémová hlášení (System Reports) získal mnoho nových funkcí a byl přejmenován na Informace o systému (System Information). Linux Mint 22.3 bude podporován do roku 2029.
Wine bylo po roce vývoje od vydání verze 10.0 vydáno v nové stabilní verzi 11.0. Přehled novinek na GitLabu. Vypíchnuta je podpora NTSYNC a dokončení architektury WoW64.
Byl vydán Mozilla Firefox 147.0. Přehled novinek v poznámkách k vydání a poznámkách k vydání pro vývojáře. Firefox nově podporuje Freedesktop.org XDG Base Directory Specification. Řešeny jsou rovněž bezpečnostní chyby. Nový Firefox 147 bude brzy k dispozici také na Flathubu a Snapcraftu.
Asociace repair.org udělila anticeny těm nejhorším produktům představeným na veletrhu CES 2026. Oceněnými jsou například šmírující kamery Amazon Ring AI, chytrý běžecký pás od společnosti Merach, která otevřeně přiznává, že nedokáže zabezpečit osobní data uživatelů, případně jednorázové lízátko, které rozvibrovává čelisti uživatele a tak přehrává hudbu. Absolutním vítězem je lednička od Samsungu, která zobrazuje reklamy a kterou lze otevřít pouze hlasovým příkazem přes cloudovou službu.
Íránští protirežimní aktivisté si všímají 30% až 80% ztráty packetů při komunikaci se satelity služby Starlink. Mohlo by se jednat o vedlejší důsledek rušení GPS, kterou pozemní přijímače Starlinku používají k výpočtu polohy satelitů a kterou se režim rovněž snaží blokovat, podle bezpečnostního experta a iranisty Amira Rashidiho je ale pravděpodobnější příčinou terestrické rušení přímo satelitní komunikace Starlinku podobnou
… více »Evropská komise (EK) zvažuje, že zařadí komunikační službu WhatsApp americké společnosti Meta mezi velké internetové platformy, které podléhají přísnější regulaci podle unijního nařízení o digitálních službách (DSA). Firmy s více než 45 miliony uživatelů jsou podle DSA považovány za velmi velké on-line platformy (Very Large Online Platforms; VLOP) a podléhají přísnějším pravidlům EU pro internetový obsah. Pravidla po
… více »Tržní hodnota technologické společnosti Alphabet poprvé v historii přesáhla čtyři biliony dolarů (83 bilionů Kč). Stalo se tak poté, co Apple oznámil, že bude na poli umělé inteligence (AI) spolupracovat s dceřinou firmou Alphabetu, společností Google.
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.