Konstruktor wird nicht durchlaufen

Programmierung für GNOME und GTK+, GUI-Erstellung mit Glade.
Antworten
PyGtk-Novice
User
Beiträge: 4
Registriert: Dienstag 25. April 2006, 13:54

Dienstag 25. April 2006, 14:12

Für eine Anwendung muß ich eine von gtk.Window abgeleitete Klasse implementieren.
Erzeuge ich direkt ein Objekt dieser abgeleiteten Klasse ist alles fein (z.B.:

Code: Alles auswählen

w = tkl.Window( "TKL_Window" )
).
Verwende ich jedoch

Code: Alles auswählen

gobject.new( tkl.Window )
oder versuche ich ein Objekt dieser Klasse über ein Glade-Formular zu bilden, so wird der Konstruktor (__init__) meiner Klasse und damit die DoRegister-Funktion nicht durchlaufen. Das zurückgelieferte Objekt hat aber den Type meiner abgeleiteten Klasse (d.h. es wird meine destroy-Funktion gerufen). Leider bin ich aber darauf angewiesen... :(

Beispiel-Code (tkl.py):

Code: Alles auswählen

import gtk
import gobject

class Window( gtk.Window ):
    registered = False
    
    def __init__( self, name="" ):
        self.__gobject_init__()
        DoRegister( self, name )

    def destroy( self ):
        UndoRegister( self )
        gtk.Window.destroy( self )
        
def main():
    gtk.main()

def main_quit():
    gtk.main_quit()

def DoRegister( wnd, name ):
  if False == wnd.registered:
    wnd.registered = True
    print "DoRegister "+name
  else:
    print "already registered"

def UndoRegister( wnd ):
  if True == wnd.registered:
    wnd.registered = False
    print "UndoRegister "
  else:
    print "not registered"

gobject.type_register( Window )
tkl.glade

Code: Alles auswählen

<?xml version="1.0" standalone="no"?> <!--*- mode: xml -*-->
<!DOCTYPE glade-interface SYSTEM "http://glade.gnome.org/glade-2.0.dtd">

<glade-interface>

<widget class="GtkWindow" id="TKL_Window">
  <property name="visible">True</property>
  <property name="can_focus">False</property>
  <property name="title" translatable="yes">small</property>
  <property name="type">GTK_WINDOW_TOPLEVEL</property>
  <property name="window_position">GTK_WIN_POS_CENTER</property>
  <property name="modal">False</property>
  <property name="resizable">True</property>
  <property name="destroy_with_parent">False</property>
  <signal name="destroy" handler="OnDestroy" last_modification_time="Wed, 19 Apr 2006 13:01:04 GMT"/>

  <child>
    <widget class="GtkButton" id="destroy">
      <property name="visible">True</property>
      <property name="can_focus">True</property>
      <property name="label" translatable="yes">Bang! Bang!</property>
      <property name="use_underline">True</property>
      <property name="relief">GTK_RELIEF_NORMAL</property>
      <signal name="clicked" handler="OnClicked" last_modification_time="Wed, 19 Apr 2006 13:01:50 GMT"/>
    </widget>
  </child>
</widget>

</glade-interface>
und test.py

Code: Alles auswählen

import pygtk
pygtk.require( "2.0" )

import tkl, gobject, gtk, gtk.glade

def OnDestroy( *args ):
  print "but I did not shoot the deputy!"
  wnd.hide()
  tkl.main_quit()

def OnClicked( *args ):
  print "I shot the sheriff,"
  wnd.destroy()

xml = gtk.glade.XML( fname="tkl.glade", typedict={'GtkWindow':'tkl+Window'} )
xml.signal_autoconnect( { "OnDestroy" : OnDestroy, "OnClicked" : OnClicked } )
wnd = xml.get_widget( "TKL_Window" )

tkl.main()
Hat irgendwer eine Lösung für mein Dillema?
:?:

Edit (Leonidas): Code in Python-Tags gesetzt.
Leonidas
Administrator
Beiträge: 16024
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Dienstag 25. April 2006, 15:43

Wofür willst du die gtk.Window Subklasse überhaupt verwenden? GTK kann man auch wunderbar ohne die verwenden, außer du hast Spezialanforderungen.
My god, it's full of CARs! | Leonidasvoice vs Modvoice
PyGtk-Novice
User
Beiträge: 4
Registriert: Dienstag 25. April 2006, 13:54

Mittwoch 26. April 2006, 06:25

Ja, leider hab ich genau diese Anforderung...
Ist eine Schnittstellen-Klasse, die ich einem Dritten zur Verfügung stellen soll und der soll's verwenden können wie ein gtk.Window, jedoch mit dem Nebeneffekt, daß automatisch das Erzeugen und Zerstören des Fensters mitprotokolliert wird...
D.h. Ich muß den Konstruktor und Destruktor manipulieren und das ohne PyGtk zu patchen, sondern durch Ableitung.
Leonidas
Administrator
Beiträge: 16024
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Mittwoch 26. April 2006, 15:59

Geht doch:

Code: Alles auswählen

import gtk
import gobject

class Window(gtk.Window):
    registered = False
   
    def __init__(self, name=""):
        self.__gobject_init__()
        #print 'running'
        DoRegister(self, name)

    def destroy(self):
        UndoRegister( self )
        gtk.Window.destroy( self )
       
def main():
    gtk.main()

def main_quit():
    gtk.main_quit()

def DoRegister(wnd, name):
    if False == wnd.registered:
        wnd.registered = True
        print "DoRegister %s" % name
    else:
        print "already registered"

def UndoRegister(wnd):
    if True == wnd.registered:
        wnd.registered = False
        print "UndoRegister "
    else:
        print "not registered"

gobject.type_register(Window)

w = Window()
print w.registered
Das das bei dir nicht so recht geht, liegt daran, dass die Glade-Datei eingelesen wird und diese ein GtkWindow erstellt, was nicht deine Klasse nutzt sondern eben gtk.Window.
My god, it's full of CARs! | Leonidasvoice vs Modvoice
PyGtk-Novice
User
Beiträge: 4
Registriert: Dienstag 25. April 2006, 13:54

Donnerstag 27. April 2006, 14:29

Ja, direkt ein Objekt meiner Klasse zu erzeugen geht natürlich, aber es über

Code: Alles auswählen

gobject.new( jh.Window )
oder eben ein Glade-Formular (drum wird per typedict ja aus "GtkWindow" ein "tkl+Window" gemacht) zu machen geht eben nicht. :?

Code: Alles auswählen

xml = gtk.glade.XML( fname="r:\\usr\\demo\\python.glade", typedict={'GtkWindow':'jh+Window'} )
Es kommt zwar ein Objekt meiner Fenster-Klasse zurück (sieht man, weil die richtige destroy-Funktion gerufen wird), aber die __init__-Funktion wird nicht durchlaufen.
Man könnte übrigens auch ins Glade-Formular statt "GtkWindow" direkt "tkl+Window" schreiben, der Effekt bleibt derselbe.

Code: Alles auswählen

<?xml version="1.0" standalone="no"?> <!--*- mode: xml -*-->
<!DOCTYPE glade-interface SYSTEM "http://glade.gnome.org/glade-2.0.dtd">

<glade-interface>

<widget class="tkl+Window" id="small">
  <property name="visible">True</property>
  <property name="can_focus">False</property>
  <property name="title" translatable="yes">small</property>
  <property name="type">GTK_WINDOW_TOPLEVEL</property>
  <property name="window_position">GTK_WIN_POS_CENTER</property>
  <property name="modal">False</property>
  <property name="resizable">True</property>
  <property name="destroy_with_parent">False</property>
  <signal name="destroy" handler="OnDestroy" last_modification_time="Wed, 19 Apr 2006 13:01:04 GMT"/>

  <child>
    <widget class="GtkButton" id="destroy">
      <property name="visible">True</property>
      <property name="can_focus">True</property>
      <property name="label" translatable="yes">Bang! Bang!</property>
      <property name="use_underline">True</property>
      <property name="relief">GTK_RELIEF_NORMAL</property>
      <signal name="clicked" handler="OnClicked" last_modification_time="Wed, 19 Apr 2006 13:01:50 GMT"/>
    </widget>
  </child>
</widget>

</glade-interface>
Antworten