Name eines Frames von String nehmen

Fragen zu Tkinter.
dh233
User
Beiträge: 37
Registriert: Samstag 8. Juli 2006, 08:26

Name eines Frames von String nehmen

Beitragvon dh233 » Freitag 28. Juli 2006, 16:21

Ich möchte ein Frame erzeugen, wobei der Name des Frames in einem String steht. Ich hätte mir das wie folgt gedacht:

Code: Alles auswählen

for i in range(1, self.frames+1):
                """frameName contains name, eg: nav1, nav2,..."""
                self.frameName="nav" + str(i)
                print self.frameName
               
                """creating navigation frames"""
                self.frameName = Frame(self.root, relief=RIDGE, bd=2, bg="white", height=15)
                self.frameName.pack(anchor="n", fill=X)


Wenn ich den Frame dann verwenden will, gibt es aber eine Fehlermeldung:

Code: Alles auswählen

self.buttonCount=0   
            for i in range (1, self.frames+1):
                """count contains current Frame number"""
                self.count=i
                self.actualFrame="nav"+ str(i)
               
               
               
                #print self.actualFrame
                """getting 7 elements"""
                for i in range(6):
                   
                    """checking if list still contains elements"""
                    if len(self.modules) > 0:
                   
                        #TODO: dynamically setting command for button
                        self.buttonText=self.modules.pop()
                        print self.buttonText
                       
                        self.ButtonName="button"+str(self.buttonCount)
                       
                        self.buttonName=Button(self.actualFrame, text=self.buttonText, width=15, font=("Times New Roman", 11))
                        self.buttonName.pack(side="left", expand="yes", fill="x")


Was mache ich falsch, bzw. wie kann ich es richtig machen?

Danke, lG

Edit (Leonidas): Code in Python-Tags gesetzt.
Benutzeravatar
Joghurt
User
Beiträge: 877
Registriert: Dienstag 15. Februar 2005, 15:07

Re: Name eines Frames von String nehmen

Beitragvon Joghurt » Freitag 28. Juli 2006, 21:19

dh233 hat geschrieben:Was mache ich falsch
Du sagst uns nicht, worum es geht.

Ich vermute mal, es geht um ein GUI-Toolkit. Aber welches? Tkinter, WxWidgets, Gt???
dh233
User
Beiträge: 37
Registriert: Samstag 8. Juli 2006, 08:26

Beitragvon dh233 » Freitag 28. Juli 2006, 22:23

Dabei handelt es sich um tkinter.

Das Problem ist eben, dass ich die Frames dynamisch generieren lassen möchte, wobei ein Frame 7 Buttons enthalten soll, ich aber vorher noch nicht weiß, wie viele Buttons es sein werden.

Das ganze ist so gedacht, dass die Anzahl der Buttons zur Laufzeit berechnet wird und dann je nach Anzahl der Buttons eben die entsprechende Anzahl an Frames generiert werden soll.
CrackPod
User
Beiträge: 205
Registriert: Freitag 30. Juni 2006, 12:56

Re: Name eines Frames von String nehmen

Beitragvon CrackPod » Samstag 29. Juli 2006, 10:46

dh233 hat geschrieben:Wenn ich den Frame dann verwenden will, gibt es aber eine Fehlermeldung:

Code: Alles auswählen

[...](Pythoncode)[...]

Wo is denn jetz genau die Fehlermeldung?
jAN
User
Beiträge: 170
Registriert: Samstag 4. Juni 2005, 18:51
Wohnort: Großmehlra (in Thüringen)
Kontaktdaten:

Beitragvon jAN » Samstag 29. Juli 2006, 23:28

eine Möglichkeit:

Code: Alles auswählen

>>> from Tkinter import *
>>> root=Tk()
>>> a=locals()
>>> a["Frame1"]=Frame(root)
>>> a["Frame2"]=Frame(root)
>>> a["Frame1"].pack()
>>> a["Frame2"].pack()
>>> root.mainloop()


vllt eine bessere Möglichkeit:

Code: Alles auswählen

>>> from Tkinter import *
>>> root=Tk()
>>> frames=[]
>>> frames.append(Frame(root))
>>> frames.append(Frame(root))
>>> frames[0].pack()
>>> frames[1].pack()
>>> root.mainloop()
#adios.py
import os,sys
while 1: os.startfile(sys.argv[0])
Benutzeravatar
HWK
User
Beiträge: 1295
Registriert: Mittwoch 7. Juni 2006, 20:44

Beitragvon HWK » Sonntag 30. Juli 2006, 00:05

Das ist doch ideal für setattr und getattr:

Code: Alles auswählen

for i in range(1, self.frames+1):
    '''frameName contains name, eg: nav1, nav2,...'''
    frameName = 'nav' + str(i)
    print frameName
   
    """creating navigation frames"""
    setattr(self, frameName, Frame(self.root, relief=RIDGE, bd=2, bg="white",
                                   height=15))
    getattr(self, frameName).pack(anchor="n", fill=X)

MfG
HWK
BlackJack

Beitragvon BlackJack » Sonntag 30. Juli 2006, 07:53

Warum sollte man in den `locals()` oder als Attribute Namen haben wollen, die auf diese Weise berechnet sind, sich also nie im Quelltext per "literalem" Namen benutzen lassen!? So etwas gehört in ein `dict()`. Oder halt eine Liste wenn man die Namen gar nicht braucht.
jAN
User
Beiträge: 170
Registriert: Samstag 4. Juni 2005, 18:51
Wohnort: Großmehlra (in Thüringen)
Kontaktdaten:

Beitragvon jAN » Sonntag 30. Juli 2006, 15:59

es geht doch:

Code: Alles auswählen

>>> a=locals()
>>> a["antwort"]=21
>>> antwort*2
42


aber ich weiß was du meinst... deshalb ja auch die zweite favorisierte variante
#adios.py

import os,sys

while 1: os.startfile(sys.argv[0])
Benutzeravatar
HWK
User
Beiträge: 1295
Registriert: Mittwoch 7. Juni 2006, 20:44

Beitragvon HWK » Sonntag 30. Juli 2006, 21:29

Das geht natürlich auch mit der getattr-, settattr-Variante. Die Frames sind auch unter ihrem Namen nav1, nav2 etc. ansprechbar.
BlackJack

Beitragvon BlackJack » Sonntag 30. Juli 2006, 21:33

Es geht übrigens nicht! Versuch den Trick mal innerhalb einer Funktion oder Methode -- dann geht's nämlich nicht mehr weil `locals()` dort eine Kopie von der drunterliegenden Datenstruktur zurückgibt. Änderungen an dem Dictionary haben dann keinen Einfluss auf die lokalen Variablen.
Benutzeravatar
HWK
User
Beiträge: 1295
Registriert: Mittwoch 7. Juni 2006, 20:44

Beitragvon HWK » Sonntag 30. Juli 2006, 22:05

Hallo, BlackJack!

Deine Anmerkung betrifft aber doch nur die locals-Variante, nicht die getattr-, setattr-Variante, oder?
Übrigens eine durchaus nützliche Verwendung findet sich unter http://www.python-forum.de/viewtopic.php?p=40804.

MfG
HWK
BlackJack

Beitragvon BlackJack » Sonntag 30. Juli 2006, 22:16

Das hat aber mit diesem "Fall" nichts zu tun. Dort wird auf Attribute zugegriffen, die bekannt sind und nicht auf berechnete.
Benutzeravatar
HWK
User
Beiträge: 1295
Registriert: Mittwoch 7. Juni 2006, 20:44

Beitragvon HWK » Sonntag 30. Juli 2006, 22:32

Hier erst einmal der Beweis, dass es funktioniert:

Code: Alles auswählen

class MyClass:
    def __init__(self):
        for i in range(4):
            frameName = 'nav' + str(i + 1)
            setattr(self, frameName, i * i)
        print self.nav1
        print self.nav2

class_test = MyClass()
print class_test.nav3
print class_test.nav4

Das Beispiel hat schon etwas mit diesem 'Fall' zu tun. Ich hätte die Buttonnamen auch einfach durch Durchnummerierung berechnen lassen können, um mir keine Namen 'aus den Fingern saugen zu müssen'. Desweiteren zeigt es die Verwendung von getattr.
BlackJack

Beitragvon BlackJack » Montag 31. Juli 2006, 06:47

Wenn Du Dir keine Namen ausdenken willst, dann brauchst Du auch kein 'nav' vor Nummern setzen und kannst die Elemente gleich in eine Liste oder in ein Dictionary schmeissen mit den Zahlen als Index/Schlüssel.
dh233
User
Beiträge: 37
Registriert: Samstag 8. Juli 2006, 08:26

Beitragvon dh233 » Mittwoch 2. August 2006, 08:33

Hallo!

Danke für eure Antworten. Ich hab das jetzt mit setattr() und getattr() gemacht, so wie es HWK beschrieben hat.



lG


dh233

Wer ist online?

Mitglieder in diesem Forum: Yutorimoyasi