Portál AbcLinuxu, 30. dubna 2025 11:25
V dnešním díle si povíme o podmínkách a cyklech v Pythonu. Naučíme se definovat vlastní funkce a vytvářet v okně tlačítka, která budou horizontálně nebo vertikálně uspořádána, a nemine nás ani vkládání textu do okna.
Python
Vstup - raw_input()
If - podmínky
For - cykly
While
Vlastní funkce
PyQT
Signály a sloty
QPushButton - tlačítko
Layouty
QLabel - textový výstup
Textový vstup lze v Pythonu provést funkcí raw_input()
.
Parametrem funkce může být text, který se vypíše před samotným zadáváním
textu. Pokud budeme chtít přetypovat text na číslo, zajistí to funkce
int()
. Uvedeme si opět malý příklad.
text = raw_input("Zadejte text: ")
x = int(raw_input("Zadejte pocet opakovani textu: "))
print text*x
Podmínky v Pythonu se příliš neliší od podmínek v ostatních jazycích.
Dostáváme se zde ovšem k důležité vlastnosti Pythonu, kterou je jeho čistá
syntaxe. Zatímco například v jazyku C nebo PHP se kód, který má být vykonán
podmínkou, vkládá mezi složené závorky, v Pythonu se rozlišuje tabulátorem
nebo rozumným počtem mezer, kterých musí být po celý kód stejný počet.
Pokud podmínka neplatí, vykonává se kód za příkazem else:
.
Pokud byste chtěli vykonat za příkazem else
další podmínku,
můžete zkrátit zápis
else: if x==1:
na
elif x==1:
Příkaz else:
je dobrovolný a není nutné jej v podmínce
udávat. V následující tabulce si ukážeme, jaké operátory můžeme v podmínkách
používat.
<
- Pravá strana je větší, než strana levá.>
- Levá strana je větší, než strana pravá.==
- Obě strany se rovnají.<=
- Levá strana je vetší nebo rovna pravé.>=
- Pravá strana je větší nebo rovne levá.!=
- Levá strana se nerovná pravé.Na pochopení podmínek bude opět stačit jednoduchý příklad jejich použití.
x = int(raw_input("Zadejte cislo: ")) if x < 0: print "cislo je vetsi nez 0\n" elif x == 0: # else: if x==0: print "cislo je rovno nule\n" else: print "cislo je mensi nez 0\n"
Je možné také vkládat víc podmínek k jednomu if
. V tom
případě se podmínky spojují pomocí logických operátorů and
nebo or
.
x = int(raw_input("Kolik je vam let?")) if x < 0 or x > 120: print "Tolik vam urcite neni\n" x = int(raw_input("Zadejte cislo od 50 do 100")) if x > 50 and x < 100: print "To je spravne cislo\n" else: print "Cislo neni v intervalu 50 az 100\n"
Cyklem for
můžeme procházet jednoduše prvky pole.
Následující příklad vypíše jednotlivé prvky pole a ke každému jeho
velikost. Velikost zjistíme funkcí len(prvek)
, která vrací
vrací velikost prvku.
list=["autobus","vlak","auto"] # definujeme pole
# urcime, ze dokud se nedostaneme na konec pole,
# bude v promenne 'text' ulozena polozka pole a bude
# se opakovat nasledujici kod:
for text in list:
print text,len(text)
K cyklům je přidružena i funkce range()
, která generuje
posloupnost čísel a vrací ji jako pole. Pokud chceme určitou část kódu
vykonat například 10x po sobě, jednoduše vygenerujeme pole čísel od 0 do 9
pomocí range(10)
a pak ho budeme procházet jedno po druhém
jako v prvním příkladu. Můžeme samozřejmě generovat čísla i od jiného
počátku než 0. Například range(5,20)
vygeneruje pole s čísly
od 5 do 19. Následující příklad vygeneruje 10 násobků čísla 11.
for i in range(10):
# vysledkem funkce range je pole [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
print 11*i
Příkazem while
můžeme vykonávat určitý kód, dokud platí
určitá podmínka. Program v příkladu bude po uživateli vyžadovat
zapsání čísla 2006 a dokud uživatel toto číslo nezadá, program se
neukončí.
cislo=0 while cislo!=2006: # dokud neni cislo rovno 2006, konej kod cislo = int(raw_input("Zadejte cislo 2006: "))
Definování funkce se v Pythonu provádí pomocí příkazu def
,
který je následován názvem funkce a jejími parametry. V příkladu si
vytvoříme funkci, která bude vracet druhou mocninu čísla, které jí dáme
jako parametr. O navrácení druhé mocniny se stará příkaz
return
.
def mocnina(cislo):
return cislo*cislo
x = int(raw_input("Zadejte cislo pro druhou mocninu: "))
print mocnina(x)
Signály a sloty jsou základem pro tvorbu grafického rozhraní. Jednoduše
jde o to, že každý prvek (okno, tlačítko, menu) má signály a sloty. Signály
jsou generovány, když dojde k nějaké změně stavu prvku (například kliknutí
na tlačítko, vybrání položky z menu atd.). Sloty jsou funkce, pomocí
kterých můžeme prvek ovládat (měnit jeho velikost, určovat jeho text). V
praxi se signály a sloty propojují. Propojení signálu se slotem je možné
pomocí funkce connect()
. Je možné napojovat signály i na
vlastní funkce nebo funkce jiných objektů. Příklad jsme mohli vidět již v
prvním díle (Python a
PyQt - 1 (úvod)). My si dnes ukážeme, jak propojit signál tlačítka s
funkcí close()
okna. Na tomto příkladu si celý proces i lépe
vysvětlíme.
Tlačítko patří bezesporu ke klasickým ovládacím prvkům v grafických
programech. K jeho vytvoření zavoláme jednoduše
QPushButton(rodic,nazev)
. Rodic
je název objektu,
který je tlačítku nadřazen. V našem případě to bude samotné okno programu.
Nazev
je interní název tlačítka (nikoliv text, který se
zobrazí přímo na tlačítku). Popisek přiřadíme tlačítku funkcí
setText(popisek)
. Všechny sloty a signály tlačítka můžete
vidět v oficiálni dokumentaci k němu. My budeme používat signál
clicked()
, který je generován po stisknutí tlačítka. Nyní již
víme vše, abychom mohli do našeho okna zobrazit tlačítko s nápisem "Hello
world". Po kliknutí na tlačítko bude generován signál
clicked()
, který bude napojen na funkci quit()
našeho okna. Dojde tedy k zavření posledního, a také jediného, okna. Tím
pádem se vygeneruje signál lastWindowClosed()
a aplikace se
uzavře.
from qt import *
app=QApplication([])
win=QMainWindow()
win.button=QPushButton(win,"Hello") # vytvorime tlacitko
win.button.setText("Hello World") # nastavime text tlacitka
win.show()
app.connect(app, SIGNAL("lastWindowClosed()"), app, SLOT("quit()"))
app.connect(win.button, SIGNAL("clicked()"),win.close)
# zajistime zavreni okna po kliknuti na tlacitko
app.exec_loop()
Aby bylo možné vložit do okna více objektů (v našem případě tlačítek), a
aby objekty reagovaly na změnu velikosti okna, je nutné použít layout.
Jedná se vlastně o tabulku, do které budeme jednotlivé prvky umisťovat.
Existuje několik druhů layoutů. K těm nejzákladnějším patří QHBoxLayout a QVBoxLayout. QHBoxLayout
řadí prvky
horizontálně vedle sebe. QVBoxLayout
řadí prvky vertikálně pod
sebe. Práce s layouty spočívá v jejich vytvoření a následném přidávání
objektů do nich. Jak funkce QVBoxLayout
tak i
QHBoxLayout
mají stejnou syntaxi. Layout vytvoříme pomocí
QVBoxLayout(rodic,odsazeni,mezera,nazev)
.
rodic
je objekt, na kterém layout leží.odsazeni
je číslo udávající počet pixelů od kraje
layoutu.mezera
udává mezeru mezi objekty.nazev
pouze interní název.Nové objekty se do layoutu přidávají pomocí funkce
addWidget(objekt)
, kde objekt
je objekt, který
bude přidán. Na následujícím příkladu si ukážeme, jak udělat okno s více
tlačítky, která budou reagovat na jeho změnu velikosti.
from qt import *
app=QApplication([])
win=QMainWindow()
win.layout=QVBoxLayout(win,0,1,"Layout") # vytvorime layout
win.button1=QPushButton(win,"b1")
win.button1.setText("Button 1")
win.layout.addWidget(win.button1) # vlozime win.button1 do layoutu
win.button2=QPushButton(win,"b1")
win.button2.setText("Button 2")
win.layout.addWidget(win.button2) # vlozime win.button2 do layoutu
win.show()
app.connect(app, SIGNAL("lastWindowClosed()"), app, SLOT("quit()"))
app.connect(win.button1, SIGNAL("clicked()"),win.close)
app.connect(win.button2, SIGNAL("clicked()"),win.close)
app.exec_loop()
Pomocí objektu QLabel
můžeme v okně zobrazovat text. QLabel vytvoříme pomocí
QLabel(rodic,nazev)
. Nový text vložíme funkcí
setText(text)
. Na závěr si můžeme procvičit vše, co jsme dnes
v PyQT probrali, na jednoduché aplikaci. Jde o aplikaci, která pomocí
funkce raw_input()
přečte řetězec a následně ho zobrazí v
okně.
from qt import *
text=raw_input("Zadejte text: ") # ziskame text a ulozime ho do promenne
app=QApplication([])
win=QMainWindow()
win.layout=QVBoxLayout(win,0,1,"Layout") # vytvorime layout
win.label=QLabel(win,"text") # vytvorime QLabel
win.label.setText(text) # vlozime do label text v promenne text
win.layout.addWidget(win.label) # vlozime win.label do layoutu
win.konec=QPushButton(win,"quit")
win.konec.setText("Konec")
win.layout.addWidget(win.konec) # vlozime win.konec do layoutu
win.show()
app.connect(app, SIGNAL("lastWindowClosed()"), app, SLOT("quit()"))
app.connect(win.konec, SIGNAL("clicked()"),win.close)
app.exec_loop()
def foo(): _print 'a' _for i in range(10): _____________print 'b' _____________print 'c'Nicméně takhle dělat je to IMHO blbost. Ale lze.
pyuic
.
Pre podrobnejšie info navštívte stránku pyqt. A google je tiež váš kamarát .ui
soubor, který se v Pythonu načte pomocí QWidgetFactory
. Nějak takto
class UserInterface(QMainWindow): def __init__(self): QMainWindow.__init__(self) self.win = QWidgetFactory.create("layout.ui") def show(self): self.win.show() def main(argv): app = QApplication(sys.argv) ui = UserInterface() app.setMainWidget(ui) app.connect(app, SIGNAL("lastWindowClosed()"), app, SLOT("quit()")) ui.show() ret = app.exec_loop() sys.exit(ret)
pyuic
, ale toto vyzerá krajšie.
Nemáte aj nejaké porovnanie o týchto dvoch prístupoch? Na nete som toho veľa nenašiel. Napríklad nie je takéto dynamické loadovanie pomalšie? A poskytujú oba spôsoby rovnako dobrú funkcionalitu?
import sys
import sip
from qt import *
from mainformsub import *
def main(args):
app=QApplication(args)
mainformapp=mainformsub()
mainformapp.show()
app.connect(app, SIGNAL("lastWindowClosed()"), app, SLOT("quit()"))
app.exec_loop()
if __name__=="__main__":
main(sys.argv)
from qt import *
from qtui import *
#from mainform import mainform
from pysqlite2 import dbapi2 as sqlite
import os, sys, sha
import fmlibcz
from progressformsub import *
from printformsub import *
class mainform(QMainWindow):
def __init__(self,parent = None,name = None,fl = 0):
QMainWindow.__init__(self,parent,name,fl)
self.win = QWidgetFactory.create("mainform.ui")
def show(self):
self.win.show()
class mainformsub(mainform):
def __init__(self,parent = None,name = None,fl = 0):
mainform.__init__(self,parent,name,fl)
#optimalizacia velkosti okna
self.spolu_tl.setMinimumWidth(self.zoznam_listView.columnWidth(0)+self.zoznam_listView.columnWidth(1)-6)
self.spolu_lv.setMinimumHeight(self.spolu_lv.header().height()+QListViewItem(self.spolu_lv).height() + 2)
self.zoznam_listView.setMinimumHeight(self.zoznam_listView.header().height()+QListViewItem(self.zoznam_listView).height()*3 +2)
self.adjustSize()
Traceback (most recent call last):
File "fm3000cz_paska.py", line 14, in ?
main(sys.argv)
File "fm3000cz_paska.py", line 8, in main
mainform=mainformsub()
File
"/home/denix/server/devel/python/fm3000cz_paska/mainformsub.py", line 25, in __init__
self.spolu_tl.setMinimumWidth(self.zoznam_listView.columnWidth(0)+self.zoznam_listView.columnWidth(1)-6)
AttributeError: spolu_tl
Robiť layouty ručne je určite zaujímavé, ale nebolo by na škodu povedať čitateľom, že takto sa to proste nerobíProc se deti uci ve skole nasobilku - vzdyt takhle se to nedela, vezme se na to prece kalkulacka. Mam takove podezreni, ze graficka prostredi zatemnuji lidem mozek, vubec pak jiz nedokazi normalne uvazovat a vse co neni klikaci je jaksi k nicemu ...
Btw, qtdesignéra používa aj dosť programátorov z KDE. Ak si myslíte, že sú to všetko lamy, ktoré vedia len klikať, tak už nemám viac argumentov.Na takovou argumentaci se da rici vzdy jen nasledujici: "lidi zerte fekalie, miliardy much se prece nemohou mylit!" Dotknul jsem se pouze toho povrchniho ve vasem prispevku, protoze je to skutecne ztrata casu o te technicke problematice s vami diskutovat. Ale mozna, ze by nam k tomu disputu neco mohl rici nas "abclinuxu-ovsky" psychoanalytik pan Jilek?
require 'gtk2' Gtk.init button = Gtk::Button.new("Hello World") button.signal_connect("clicked") { puts "Hello World" } window = Gtk::Window.new window.signal_connect("destroy") { Gtk.main_quit } window.add(button) window.show_all Gtk.main
app.connect(app, SIGNAL("lastWindowClosed()"), app, SLOT("quit()"))Nezdaji se mi tam jeste nejmene tri dalsi veci, ktere jsou opravdu minoritni. Co me ale doopravdy dostalo je importovani celeho qt a pojmenovavani trid jako "QTyp". Kdyz se qt neimportuje, tak je to napr. qt.QVBoxLayout? K cemu v tom pythonu proboha ty namespaces vubec mate, kdyz potom delate takovehle prasarny? Dival jsem se, jestli to je pythonovska tendence likvidovat namespaces, ale asi ne, protoze v PyGTK je to udelany tak, jak by clovek ocekaval:
window.add(gtk.Button("Hello World"))o 100% lepsi nez tahle katastrofa:
win.button=QPushButton(win,"Hello") win.button.setText("Hello World")Navic to vypada, ze je to doslovna kopie C++ interface, akorat se to pise v Pythonu. K cemu pak psat v Pythonu, kdyz v nem pisu to same jako v C++? Neni lepsi to pak uz delat rovnou v C++? No nic, alespon me ten clanek utvrdil v tom, ze jsem si zvolil spravnej jazyk i toolkit ;).
connect(ob1, SIGNAL, ob2, SLOT)
prakticky to najlepšie, čo sa dá vymyslieť a mne to pripadá veľmi elegantné. Preto ani v pythone s tým nemám problém, aj keď v ňom by sa vďaka jeho dynamickej náture dalo vymyslieť aj niečo lepšie. Ale bloky zatiaľ nemá import gtk def hClicked(button): print "Hello World" button = gtk.Button("Hello World") button.connect("clicked", hClicked) window = gtk.Window() window.connect("destroy", gtk.main_quit) window.add(button) window.show_all() gtk.main()To je myslím čitelnější než Ruby. Například je v Pythonu jasně vidět rozdíl mezi předáním odkazu na metodu (např. gtk.main_quit) a mezi voláním metody (např. gtk.main()). V Ruby to není rozlišeno, to velmi stěžuje čtení takového programu, není na první pohled jasné co program dělá.
* C/GTK versus C/QT (na to jsem v QT opravdu zvedav ;)
* C++ v GTK versus C++ v QT (vetsina programatoru tvrdi, ze C++/GTK je lepsi, protoze maximalne vyuziva nove vlastnosti C++, a po shlednuti tohoto clanku tomu dost verim)
* Python/GTK versus Python/QT (na prvni pohled se zda, ze GTK je elegantnejsi a lepe navrzene).
* Ruby/GTK versus Ruby/QT (GTK je mnohem lepsi - QT wrapper neni nic jineho, nez programovani C++ v Ruby, stejne jako u PyQT)
* Java/GTK versus Java/QT
* Mono/GTK versus Mono/QT
* Perl/GTK versus Perl/QT
* PHP/GTK versus PHP/QT
...
P.S. Jeden z hlavnich cilu pri vyvoji GTK bylo, aby se na nej dobre vytvarely wrappery. Proto je taky udelany v C. Jeho programatori totiz netrpeli predstavou, ze jejich prog. jazyk je jediny spravny na svete, jak je tomu u hodne C++/PHP programatoru :) (bez urazky - konstatovani faktu - prosim noflame).
To s vami souhlasim, akorat me po tom, co jsem vsude cetl Qtckare se vytahovat, jak uzasne jsou v Qt delany signaly, docela udivuje, ze jsou az takhle nepekne.
"Například je v Pythonu jasně vidět rozdíl mezi předáním odkazu na metodu (např. gtk.main_quit) a mezi voláním metody (např. gtk.main())"
To je v Ruby taky, protoze GTK.main_quit nikdy nebude nic jineho, nez volani metody. V Ruby totiz neni nic jineho nez volani metod. Odkazy se delaji jinak. Coz je v Ruby myslim lepsi, nez v Pythonu, protoze netreba psat prazdne zavorky ;) (viz napriklad GTK::Button.new
a puts "hello"
a str.strip.reverse.split
, atd.). Uznavam ale, ze je to pouze drobna vychytavka pro pohodli programatoru, takze se o tom netreba dohadovat.
Na prvni pohled nevidite, co program dela, protoze neznate bloky, to je cele. Ale netreba zoufat, myslim ze novy Python se inspiroval a bude je mit taky. Samozrejme ze budou muset byt nejakym zpusobem ohnute, aby do Pythonu pasovaly, ale porad lepsi nez klackem do oka ;).
P.S. Odkazy na metody jsem prakticky v Ruby jeste nevidel pouzivat. Vsechno se resi pres bloky, coz je imho uplne jina liga.
Ad. vice signalu: napriklad zdedenim Buttonu a predefinovanim signalu, nebo predanim toho sameho bloku nekolikrat:
muj_signal = proc { puts "Hello" } button1.signal_connect("clicked", &muj_signal) button2.signal_connect("clicked", &muj_signal)Samozrejme to lze udelat i odkazem na metodu.
Protoze Ruby zrejme neznate, nebudeme asi zbytecne pokracovat v diskusi. Zkuste si precist tento text od Pythonisty, ktery oba jazyky srovnava: Ruby and Python. Je to ale ponekud starsiho data...
Ja to vidim podobne jako tvurce Ruby on Rails:
Yes, functionally, Ruby and Python are really close. In terms of elegance and consistency, though, Ruby feels (this is both subjective and non-quantifiable) way ahead to me. Especially when it comes to the level object-orientedness and the widespread use of blocks.
muj_signal = proc { puts "Hello" } button1.signal_connect("clicked", &muj_signal) button2.signal_connect("clicked", &muj_signal)se nijak nelisi od reseni v Pythonu:
def muj_signal(butt): print "Hello" button1.connect("clicked", muj_signal) button2.connect("clicked", muj_signal)Jen by me zajimalo, jak dostanete do toho sveho bloku promenne, ktere ten signal predava. Ze byste musel pouzit jeste jine reseni?
Jestli vam jde o to nalezt takove zadani, aby se nedaly efektivne pouzit bloky nebo alespon closures, tak co treba implementace algoritmu 1+1
;) ?
Tak tady je to teda s jednou promennou, se dvema to ale uz psat nebudu:
muj_signal = proc {|button| puts "Hello" } button1.signal_connect("clicked", &muj_signal) button2.signal_connect("clicked", &muj_signal)Jestli chcete o Ruby vedet neco vic, tak si o nem prosim prectete tuhle knizku: http://www.ruby-doc.org/docs/ProgrammingRuby/ - uz me to tu nebavi :(.
Abych tuhle diskusi uzavrel, tak opakuji jeste jednou, co se tyce funkcionality, jsou na tom Python i Ruby obdobne. A budou si porad bliz, protoze vetsina jazyku zacala Ruby featury postupne implementovat (Python, novy Perl, jazyky nad .Netem, ...). Pak uz je rozdil pouze v tom, zda je jazyk pro dane featury primo navrzen, nebo jsou do jazyka postupne dosroubovany.
def mujSignal(button=None): pass
Umim dobre spoustu prog. jazyku, takze mi nenamluvite ze ma Python syntaxi podobnou konvecnim jazykum, nebo ze neni v mnoha ohledech velmi podivna. I ten priklad co jste tu ted uvedl nema s konvencnimi jazyky vubec nic spolecneho a kdyby jste ho napsal do diskuse o C/PHP/Perlu/Ruby/Jave/... tak by nad ni vsichni ohrnuli nos.
"Nevím proč mi píšete, že vás o tu nebaví, sám jste s v dikuzi pod článkem o Pythonu rozhodnul dělat osvětu o Ruby"
Nemam v umyslu tu ztracet cas vyvracenim demagogie :(. Uvedl jsem zde priklad, ktery je elegantnejsi, nez v Pythonu. Potom jste mne primel napsat priklad, ktery je podobny alternative v Pythonu, ale je silnejsi. Tady je o neco slozitejsi priklad, ktery je znovu o dost jednodussi a elegantnejsi nez jeho pripadna alternativa v Pythonu:
5.times {|i| button = Gtk::Button.new("Hello_#{i}") button.signal_connect("clicked") { puts i } vbox.add(button) }
Takhle bychom mohli pokracovat nekolik let, ale postradam v tom smysl (podobnych srovnavacich stranek existuji desitky). Zkuseny Pythonista nema duvod prechazet na novy jazyk (i kdyz mu neuskodi dalsi jazyk se naucit) a zacatecnikum jsem zde ukazal, ze existuje stejna nebo dokonce lepsi alternativa k PyQt a PyGtk, ktera stoji za to aby se na ni podival. Jak jste jiz psal, at se kazdy rozhodne sam...
To uz je opravdu konec - at uz vymyslite libovolnou provokaci ;).
5.times {|i| button = Gtk::Button.new("Hello_#{i}") button.signal_connect("clicked") { puts i } vbox.add(button) }To si nemyslím, vy jen asi Python příliš dobře neznáte.
for i in xrange(5): button = gtk.Button("Hello %d"%i) button.connect("clicked", puts, i) vbox.add(button)
Zkuste to ted napsat tak, aby to melo stejnou silu jako Ruby predloha. Byla to tedy stejne silna alternativa, o kterou me slo, a kterou lze resit temer vsechny problemy daneho typu (mimo zmenu promenne o uroven vyse, kterou Python neumi) a nemusi se na kazdy podobny problem vymyslet jiny trik (lambdy, generatory, ...). Myslim tim dve zanorene funkce...
P.S. Defaultni parametry do bloku samozrejme predavat lze. Uz jsem tu ukazal i priklad, kdy lze parametr uplne zahodit. Kdyby se vas kolega na ruby podival alespon z rychliku, nemusel by tu psat porad takove bludy ;). Navic si u kazdeho signalu muzu konecne volani prizpusobit, jak uznam za vhodne. Muzu tak pouzit naprosto nekompatibilni handler. Samozrejme zase konzistentnim a elegantnim zpusobem - pomoci bloku.
Dalsi odkazy, kde se obchazi neexistence closures a bloku v Pythonu pomoci lambd a podobne:
http://ivan.truemesh.com/archives/000411.html
http://ivan.truemesh.com/archives/000392.html
Stranky Pythonu na wikipedii, kde tvrdi, ze umi closures (ale ve skutecnosti je k tomu potreba pouzit triku v prvnim odkazu):
http://en.wikipedia.org/wiki/Python_programming_language
(je tam odkaz i na wikepedia stranku o Closures)
Ano, GTK je lepší toolkit než Qtjj, to urcite. a nejlip je na tom GTK s pametovymi naroky a naroky na procesor, ktere jsou zcela jiste mensi, nez u Qt. A taky ma hlavne na vsech OS nativni look, to kazdopadne
ano, GTK ma mensi pametove naroky - je to videt uz na sockua co GNOME...to si za tu lennost muze samo? Kdykoliv jsem porovnaval veci v GTK a Qt, Qt bylo sviznejsi a chovalo se k pameti slusneji.
ano, GTK ma na vsech OS nativni look - na Windows dlouho (spec. tema) a na OSX nove.vy asi vaze nemate poneti, co to je nativni look. Pokus o imitaci WinAPI se jakz takz zdaril, i kdyz file chooser a dalsi veci porad nejsou prizpusobeny. Ale rikat nedavnemu rozchozeni GTK+ na OS X bez X serveru nativni look...za to by vas jakykoliv Macar ukamenoval. Pokus je to hezky a mnoho veci zjednodusi, ale uz jen to, ze menu aplikace neni tam, kde ma byt, je z pohledu uzivatele OS X neodpustitelny prohresek. A to radsi nemluvim treba o klavesovych zkratkach ci desgnu toolbaru, ktere ztezi budou nekompromisne vyhovovat Apple HIG...
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 21016 jiri 15 0 29140 14m 11m S 0.0 2.8 0:00.84 python-qt 21056 jiri 15 0 16640 9.9m 6464 S 0.0 2.0 0:00.45 python-gtkKdyz v Gnome na neco cekam, tak je to disk. Problem s Linuxovyma GUI aplikacema je podle mne v tom, ze otviraji prilis velke mnozstvi souboru. Tohle to jen potvrzuje:
Dave Jones, recently did some profiling of what’s called through the kernel during startup. He traced stat()s, open()s, and commands exec()ed. There were some pretty amazing results. Some of the highlights include: * Executing /sbin/hotplug 317 times * Over 470 exec() calls during startup * cups, during startup stats 1212 times and opens 172 files * cups fires up printconf-backend which does another 1304 stats and 155 opens * hal does 1980 open calls and 7106 stat calls. Dave says “Wow.” * Xorg during startup does 2420 stat calls and 370 open calls * gdm calls stat 1871 times and 314 open calls. And it opens 126 fonts. There’s a lot more than that, but those are the highlights.Nevim, jestli uz Qt dela double buffering - GTK ho dela. A nejpomalejsi je samozrejme Pango, ktere na druhou stranu nema v kvalite u Qt alternativu - nebo uz ano?
Opravdu vim, co je to nativni look, ale vy jste si to zrejme spletl s "native look and feel". Jo, to je presne to, co mi Qt na mem desktopu kazi ;). Proto nepouzivam zadne Qt aplikace.
Ja se sice v OS-X nevyznam, ale tohle mi pripada, jako ze ma menu nahore: http://gtk-cocoa.sourceforge.net/Gtk+-Cocoa.jpg . Mam pocit, ze se ty veci pro OS-X porad vyviji, takze bych je za pouhy pokus zatim neoznacoval.
Navic tady programujeme v Pythonu, takze nam jde hlavne o rychlost a jednoduchost vyvoje a myslim si, ze zrovna OS-X u nas moc resit nemusime. Plus napriklad me docela na Linuxu zalezi, takze radsi budu podporovat toolkit, kterej z Linuxu nedela kripla z hlediska komercniho vyvoje.
něco.něco_jiného
je v Ruby vždyvolání metody, stejně jako ve Smalltalku. ISSN 1214-1267, (c) 1999-2007 Stickfish s.r.o.