Fehler beim Erstellen eines abgeleiteten Buttons

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
VolkerH
User
Beiträge: 20
Registriert: Dienstag 24. September 2013, 07:16
Wohnort: 46499 Hamminkeln

Hallo Pythongemeinde,

ich versuche seit geraumer Zeit ein Objekt (Button) von einer eigenen Klasse zu erstellen und komme einfach nicht weiter. Im Netz habe ich schon geschaut, aber leider keinen wirklichen Ansatz für mich gefunden und hoffe auf Eure Hilfe. Zu Testzwecken wurde die eigene Button-Klasse total abgespeckt (s. u.). Ziel meiner Bemühungen ist, dass mehrere Buttons per Thread erstellt werden und in ein Frame kommen. Wenn die Buttons direkt in der Funktion erzeugt werden (main), die der Thread aufruft, dann funktioniert es. Verwende ich aber meine Klasse, dann... leider nicht. Ich habe auch schon versucht einige Variablen nachzubilden, aber das hat auch nicht weitergeholfen.
Beim Ausführen des Hauptprogramms erhalte ich folgende Fehlermeldung (siehe unten).
Ich verwende Python 3.3 und tk.
Vielen Dank im voraus.

Viele Grüße,
Volker

Code: Alles auswählen

pydev debugger: starting
Unhandled exception in thread started by <__main__.NewThreadStartup object at 0x00000000032F4B38>
Traceback (most recent call last):
  File "P:\Program\eclipse-SDK-4.3-win32\eclipse\plugins\org.python.pydev_2.8.1.2013072611\pysrc\pydevd.py", line 207, in __call__
    return self.original_func(*args, **kwargs)
  File "P:\Program\workspace\Photo-Management\preview.py", line 106, in prepairePreView
    ThumbnailView.create_window(posNewThumbnail, 0, anchor=tkinter.NW, window=btn2)
  File "C:\Program Files\Python33\lib\tkinter\__init__.py", line 2302, in create_window
    return self._create('window', args, kw)
  File "C:\Program Files\Python33\lib\tkinter\__init__.py", line 2275, in _create
    *(args + self._options(cnf, kw))))
_tkinter.TclError: bad window path name ".52563920.53431768.53431992"

Code: Alles auswählen

import tkinter, pickle

class MyButton(tkinter.Button):
    '''
    classdocs
    '''


    def __init__(self, master):
        '''
        Constructor
        '''
        self._tclCommands = []
        self._w = "{}.{}".format(master,id(self))
        self._name = str(id(self))
        self.master = master

--------
Im main wird folgendes aufgerufen...
btn2 = MyButton(ThumbnailView)    #ThumbnailView ist der Ziel-Frame
ThumbnailView.create_window(posNewThumbnail, 0, anchor=tkinter.NW, window=btn2)
BlackJack

@VolkerH: Erstens musst Du die `__init__()` von der Elternklasse aufrufen. Und zweitens vertragen sich GUI-Toolkits und Threads in der Regel nicht. Das heisst sämtlicher Code der die GUI manipuliert muss in *einem* Thread laufen. Manche GUI-Toolkits schränken das sogar noch darauf ein, dass es sich um den Hauptthread handeln muss.

Die Docstrings sind keine Dokumentation, dann würde ich sie weg lassen. Streng genommen ist die „Un-Dokumentation” von der `__init__()` sogar falsch, weil das kein Konstruktor ist. Python kennt auch Konstruktoren und diese Methoden heissen `__new__()`. Die braucht man aber nur in eher exotischen Fällen.
VolkerH
User
Beiträge: 20
Registriert: Dienstag 24. September 2013, 07:16
Wohnort: 46499 Hamminkeln

Hi BlackJack,
vielen Dank für Deine (schnelle) Antwort, sie hat mir sehr geholfen. Ich habe es jetzt so verstanden, dass ich mit der Erstellung der Buttons in der 'main' dann schon richtig war. Ich finde es schade, dass das Erstellen und Einbinden der GUI-Komponenten per Subthread nicht möglich ist bzw. Probleme aufwirft. Ich werde gleich Deinen Tipp bzgl. der "__init__() umsetzen... bin gespannt. Danke, Volker
VolkerH
User
Beiträge: 20
Registriert: Dienstag 24. September 2013, 07:16
Wohnort: 46499 Hamminkeln

Es funktioniert nun prima, so wie ich es gewünscht hatte. :D
Danke.
Antworten