pywin, Handler für Button richtig verknüpfen?

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
jochbein
User
Beiträge: 4
Registriert: Mittwoch 24. Juli 2013, 14:43

Hallo,

da ich ein Programm erweitern soll, dessen GUI mit Pywin erzeugt wurde, versuche ich mich gerade in die Materie einzuarbeiten. Mittlerweile habe ich herausgefunden, wie man Fenster, z.B. Dialoge erstellt und anzeigt. Leider gelingt es mir nicht, die eingefügten Controls (z.B. Buttons) auch zu nutzen.

Im Folgenden ein Minimalbeispiel eines Dialogs mit einem einzelnen Knopf:

Code: Alles auswählen

from pywin.mfc import dialog
import win32ui
import win32con

def MakeDlgTemplate():           
    style = (win32con.DS_MODALFRAME |
    win32con.WS_POPUP |
    win32con.WS_VISIBLE |
    win32con.WS_CAPTION |
    win32con.WS_SYSMENU |
    win32con.DS_SETFONT)
    cs = (win32con.WS_CHILD |
    win32con.WS_VISIBLE)
    
    dlg = [["Button Test",
    (0, 0, 90, 30),
    style,
    None,
    (8, "MS Sans Serif")],
    ]
    return dlg

class TestDialog(dialog.Dialog):
    def OnInitDialog(self):
        rc = dialog.Dialog.OnInitDialog(self)
        self.pbutton = win32ui.CreateButton()
        self.pbutton.CreateWindow("TestButton", win32con.BS_PUSHBUTTON | win32con.WS_VISIBLE , (10, 10, 120, 35), self, win32ui.IDC_BUTTON1)
        self.HookCommand(self.onButton(), win32ui.IDC_BUTTON1)        
        return rc
    
    def onButton(self):
        print "Button pushed!"
    
def demo():
    d = TestDialog (MakeDlgTemplate())
    d.DoModal()
    

if __name__=='__main__':
    demo()
Dabei ging ich davon aus, dass der Befehl HookCommand(Handler, id) bestimmt, was bei einem Klick auf den Button passieren soll - in diesem Fall also ein Aufruf von onButton(). Führe ich das Programm aus, wird jedoch nur ein einziges Mal bei der Initialisierung des Dialogs "Button pushed!" ausgegeben. Klickt man zu Laufzeit des Programms auf den Button, passiert leider gar nichts.

Hat jemand von euch eine Idee, was ich hier falsch gemacht habe?

Vielen Dank im Voraus und beste Grüße,
jochbein
Benutzeravatar
pillmuncher
User
Beiträge: 1484
Registriert: Samstag 21. März 2009, 22:59
Wohnort: Pfaffenwinkel

Bitte vergleiche:

Code: Alles auswählen

self.HookCommand(self.onButton(), win32ui.IDC_BUTTON1)
vs.

Code: Alles auswählen

self.HookCommand(self.onButton, win32ui.IDC_BUTTON1)
In specifications, Murphy's Law supersedes Ohm's.
jochbein
User
Beiträge: 4
Registriert: Mittwoch 24. Juli 2013, 14:43

Vielen Dank für die schnelle Antwort pillmuncher.

Code: Alles auswählen

self.HookCommand(self.onButton(), win32ui.IDC_BUTTON1)
tut einfach gar nichts, während

Code: Alles auswählen

self.HookCommand(self.onButton, win32ui.IDC_BUTTON1)
folgende Fehlermeldung liefert:

(null)
TypeError: onButton() takes exactly 1 argument (3 given)

Die Fehlermeldung taucht dann aber jedes mal auf, wenn der Button gedrückt wird. Das würde ja darauf hindeuten, dass HookCommand tatsächlich so funktioniert, wie ich denke, d.h. dass ein Klick auf den Button onButton() aufruft. Umso mehr wundere ich mich, dass in der Console nichts ausgegeben wird.
Benutzeravatar
/me
User
Beiträge: 3555
Registriert: Donnerstag 25. Juni 2009, 14:40
Wohnort: Bonn

jochbein hat geschrieben:TypeError: onButton() takes exactly 1 argument (3 given)
Das sieht schwer so aus, als müssten in der Methodendefinition von onButton neben self noch zwei weitere Parameter definiert werden.
jochbein
User
Beiträge: 4
Registriert: Mittwoch 24. Juli 2013, 14:43

Astrein! Herzlichen Dank /me!

Mit folgender Definition von TestDialog klappt es:

Code: Alles auswählen

class TestDialog(dialog.Dialog):
    def OnInitDialog(self):
        rc = dialog.Dialog.OnInitDialog(self)
        self.pbutton = win32ui.CreateButton()
        self.pbutton.CreateWindow("TestButton", win32con.BS_PUSHBUTTON | win32con.WS_VISIBLE , (10, 10, 120, 35), self, win32ui.IDC_BUTTON1)
        self.HookCommand(self.onButton, win32ui.IDC_BUTTON1)        
        return rc
    
    def onButton(self, controlID, code):
        print "Button pushed!"
Cheers,
jochbein
BlackJack

@jochbein: Die erste Variante tut nicht gar nichts sondern ruft die `onButton()`-Methode auf, also wird etwas per ``print`` ausgegeben. Und dann wird an `HookCommand()` als erstes Argument der Rückgabewert der `onButton()`-Methode übergeben — was hier implizit `None` ist.
jochbein
User
Beiträge: 4
Registriert: Mittwoch 24. Juli 2013, 14:43

@BlackJack: Vielen Dank für den Hinweis, jetzt hab ich das auch etwas besser verstanden.

Grüße,
jochbein
Antworten