1. GTK-Prog und ein paar Fragen

Programmierung für GNOME und GTK+, GUI-Erstellung mit Glade.
Antworten
Benutzeravatar
noisefloor
User
Beiträge: 3856
Registriert: Mittwoch 17. Oktober 2007, 21:40
Wohnort: WW
Kontaktdaten:

Hallo,

Vorwort: bis jetzt habe ich Qt + PySide für "Python mit GUI" genommen. Eben habe ich mir mal ein erstes Miniprogramm in Python + GTK zusammen gehackt:

Code: Alles auswählen

#!/usr/bin/python
# -*- coding: utf-8 -*-
 
import gtk
 
class Simpel(object): 
    def __init__(self):
        self.window = gtk.Window(gtk.WINDOW_TOPLEVEL)
        self.window.set_title("Simpel GTK+")
        self.window.set_default_size(200, 100)
        self.window.connect("delete_event", self.event_delete)
        self.window.connect("destroy", self.destroy)
        vbox = gtk.VBox(False, 20)
        self.eingabe = gtk.Entry()
        self.eingabe.show()
        vbox.pack_start(self.eingabe)
        button = gtk.Button("Quadrieren")
        button.connect("clicked", self.rechnen)
        button.show()
        vbox.pack_start(button)    
        self.label = gtk.Label("Ergebnis...")
        self.label.show()
        vbox.pack_start(self.label)
        self.window.add(vbox)
        vbox.show()
        self.window.show()
        
    def rechnen(self,data=None):
        try:
            wert = int(self.eingabe.get_text())
        except:
            text = 'Die Eingabe ist keine ganze Zahl!'
            dialog = gtk.MessageDialog(
                flags=gtk.DIALOG_MODAL,
                buttons=gtk.BUTTONS_OK,
                message_format=text)
            dialog.set_title("Fehler!")
            dialog.run()
            dialog.destroy()
            return
        self.label.set_text(str(wert*wert))
        return

    def event_delete(self, widget, event, data=None):
        return False
 
    def destroy(self, data=None):
        gtk.main_quit()
 
    def main(self):
        gtk.main()
 
if __name__ == "__main__":
    e = Simpel()
    e.main()
Was auch funktioniert. :-)

Die eigentlichen Fragen sind:

Sind "destroy" und "event_delete" Pflicht für jedes GTK-basierte Programme? Nicht, dass das schlimme wäre ;-) aber bei Qt ist es nicht notwendig.

Kennt GTK Validatoren für Eingabe, z.B. mit deren Hilfe man festlegen kann, dass "eingabe" nur Integer-Werte nimmt?

Sonstige Anmerkungen sind auch willkommen. :-)

Gruß, noisefloor
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Sorry, wollte gestern antworten aber dann hat die Kombination aus Browser und schlechter Internetverbindung meinen Post gefressen und dann war ich zu genervt um ihn zu reproduzieren, stattdessen flogen erstmal Geräte und Beschimpfungen durch die Luft.

Also, du brauchst nicht extra nen Handler für ``destroy``, um das Fenster zuzumachen reicht auch ``delete_event`` und selbst das kann man vereinfachen:

Code: Alles auswählen

self.window.connect("delete_event", gtk.main_quit)
Außerdem ist es nicht nötig dass du bei jedem Widget ``.show()`` aufrufst, es reicht ``self.window.show_all()`` am schluss, welches rekursiv alle Widgets anzeigt.

Daneben: Bitte kein ``except:`` verwenden, weil angenommen du änderst ``self.eingabe`` mal in ``self.input`` dann fliegt ein ganz anderer Fehler, nämlich ein ``NameError`` und die Fehlermeldung passt dann gar nicht. Besser Fehler nicht behandeln, als sie mit der falschen Fehlerbehandlung zu traktieren.

Validatoren kennt GTK+ meines wissens nicht, aber du kannst deine eigene Validierungsfunktion etwa an das ``changed``-Signal des Eingabewidgets binden und dann den Bestätigungsbutton aktivieren und deaktivieren.

Auch ist die Frage, ob du bei neuen Programmen noch auf PyGTK und damit auf GTK+ 2.x setzen solltest, oder ob es nicht mehr Sinn macht PyGObject zu verwenden, welches der Nachfolger von PyGTK ist.

Achja, weil ichs noch sehe: das ``return`` ohne speziellen Wert gibt ``None`` zurück, also das exakt gleiche was die Funktion so auch zurückgeben würde. Also kannst du das ersatzlos streichen.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Benutzeravatar
noisefloor
User
Beiträge: 3856
Registriert: Mittwoch 17. Oktober 2007, 21:40
Wohnort: WW
Kontaktdaten:

Hallo,

Danke für die Rückmeldung. :-)

Beim "except" fehlt in der Tat der "ValueError".

Zu PyGTK bs. PyGObject: Das ist mir in den Grundzügen schon bewußt, allerdings ist doch - AFAIK - der Übergang noch nicht ganz vollzogen, oder? Insbesonders unter Win hackt es nich, meine ich gelesen zu haben.

Da ich das Programm eh' nur für einen kleine Vergleich brauche und normalerweise GUI-basierte Sachen mit PySide mache, habe ich halt PyGTK genommen.

Gruß, noisefloor
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

noisefloor hat geschrieben:Zu PyGTK bs. PyGObject: Das ist mir in den Grundzügen schon bewußt, allerdings ist doch - AFAIK - der Übergang noch nicht ganz vollzogen, oder? Insbesonders unter Win hackt es nich, meine ich gelesen zu haben.
Unter Windows und Mac OS X ist GTK+ IMHO eh das falsche Tool. Bei Windows geht es noch unter Umständen, wenn man die ganze umständliche Runtime mitschleppt, aber soweit ich weiß gibts nicht mal einen nativen Mac-Port sondern es benötigt X11... das ist jetzt von PyGTK und PyGObject völlig unabhängig :)
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Benutzeravatar
noisefloor
User
Beiträge: 3856
Registriert: Mittwoch 17. Oktober 2007, 21:40
Wohnort: WW
Kontaktdaten:

Hallo,

hier die aktualisiert Version, basierend auf PyGObject:

Code: Alles auswählen

#!/usr/bin/python
# -*- coding: utf-8 -*-
 
from gi.repository import Gtk
 
class SimpelGtk(Gtk.Window): 
    def __init__(self):
        Gtk.Window.__init__(self, title='Simpel Gtk+')
        self.connect('delete-event', Gtk.main_quit)
        self.set_default_size(200, 100)
        self.vbox = Gtk.Box(False, 0, orientation = Gtk.Orientation.VERTICAL)
        self.add(self.vbox)
        self.eingabe = Gtk.Entry()
        self.vbox.pack_start(self.eingabe, True, True, 5)
        self.button = Gtk.Button('Quadrieren')
        self.button.connect('clicked', self.rechnen)
        self.vbox.pack_start(self.button, True, True, 5)    
        self.label = Gtk.Label('Ergebnis...')
        self.vbox.pack_start(self.label, True, True, 5)
        self.show_all()
        
    def rechnen(self,data=None):
        try:
            wert = int(self.eingabe.get_text())
        except ValueError:
            text = 'Die Eingabe ist keine ganze Zahl!'
            dialog = Gtk.MessageDialog(self, 0, Gtk.MessageType.ERROR,
                Gtk.ButtonsType.CANCEL, 'Fehler bei der Eingabe')
            dialog.format_secondary_text(
                'Der eingegebene Wert ist keine ganze Zahl!')
            dialog.run()
            dialog.destroy()
        else:
            self.label.set_text(str(wert*wert))

    def main(self):
        win = Gtk.Window()
        Gtk.main()
 
if __name__ == "__main__":
    e = SimpelGtk()
    e.main()
Kommentare sind willkommen. :-)

Gruß, noisefloor
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

  • Simpel != Simple. Musst dich schon entscheiden welche Sprache du nutzt ;) Generell auch die anderen Identifier. Ich persönlich würde alles englisch machen, aber ``SimpelGtk`` wirkt schon echt seltsam.
  • PEP8 beachten. Bei Funktionsaufrufen sind um das ``=`` keine Leerzeichen.
  • Würde in der Klasse keine ``main`` machen, sondern diese ins Modul tun. Ist ja eigentlich auch keine Methode die bei einem Fenster Sinn macht, nicht wahr?
  • Persönlich würde ich from ``gi.repository import Gtk as gtk`` machen, weil ich Lowercase-Modulnamen bevorzuge und weil das zum Stil von PyGTK und soweit ich mich erinnere auch GTK+ passt.
Ansonsten passts, denk ich.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Benutzeravatar
noisefloor
User
Beiträge: 3856
Registriert: Mittwoch 17. Oktober 2007, 21:40
Wohnort: WW
Kontaktdaten:

Hallo,

Danke für's Feedback.

Das mit dem Denglisch ist manch Mal echt schwer... ;-)

Gruß, noisefloor
Antworten