string zu no string konvertieren ?

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.
smashed to pieces
User
Beiträge: 38
Registriert: Samstag 24. November 2007, 16:50

Beitragvon smashed to pieces » Freitag 7. November 2008, 16:15

Aja ok. Hab noch nie Klassen verwendet, also bin ich mir jetzt ziemlich unsicher.
Hab mir jetzt vergestellt, dass ich 4 Klassen definiere eine zum erstellen des Cubes, eine zum Verdrehen, eine zum Loesen und schlussendlich eine zum Abbilden. Sollte man das so aufteilen. Oder verwendet man normalerweise mehr Klassen?
Das Graphisch ist eine eigene Klasse, somit auch vom rechnerischem getrennt:

http://paste.pocoo.org/show/90474/

Code: Alles auswählen

    def root_building(self):
        self.root = Tk()
        self.canvas = Canvas(self.root, width=650, height=220, bg='grey')
        self.canvas.place(x=30,y=30)

    def build_field(self, color, position):
        self.canvas.create_rectangle(position[0],position[1],position[2],position[3],fill=color)#,outline=color)
   
    def placing_fields(self):
        self.build_field('red', (325,20,345,40))##versuch


Allerdings komm ich mit Klassen noch nicht ganz so zurecht. Wie kann ich in der Funktion build_field jetzt auf canvas zugreifen, welches in einer anderen Funktion definiert ist?
Benutzeravatar
cofi
Moderator
Beiträge: 4432
Registriert: Sonntag 30. März 2008, 04:16
Wohnort: RGFybXN0YWR0

Beitragvon cofi » Freitag 7. November 2008, 17:05

In dem Code sind ein paar grausame Dinger.
Klassen sind dazu da um Objekte logisch abzubilden.
Im Klartext heisst das hier: Du hast eine Klasse Würfel und der Würfel hat die Methoden die du - warum auch immer - in andere Klassen packst.

Les am besten mal die Seiten im Tutorial zur OOP.
Y0Gi
User
Beiträge: 1454
Registriert: Freitag 22. September 2006, 23:05
Wohnort: ja

Beitragvon Y0Gi » Freitag 7. November 2008, 17:25

Kleine Faustregel: Alle Methoden, in dessen Rumpf du das `self`-Objekt nicht verwendest, kannst du in Funktionen umwandeln.
Benutzeravatar
Leonidas
Administrator
Beiträge: 16023
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Beitragvon Leonidas » Freitag 7. November 2008, 17:37

smashed to pieces hat geschrieben:Hab mir jetzt vergestellt, dass ich 4 Klassen definiere eine zum erstellen des Cubes, eine zum Verdrehen, eine zum Loesen und schlussendlich eine zum Abbilden. Sollte man das so aufteilen. Oder verwendet man normalerweise mehr Klassen?

Nein, für sowas verwendet man 0 Klassen. Klassen repräsentieren Dinge, deine Klassen sind Aktionen. Dafür gibt es andere Strukturen, man nennt die Teile die etwas machen "Funktionen".
My god, it's full of CARs! | Leonidasvoice vs Modvoice
smashed to pieces
User
Beiträge: 38
Registriert: Samstag 24. November 2007, 16:50

Beitragvon smashed to pieces » Sonntag 9. November 2008, 17:44

Ok, das heisst ich brauche nur 2 Klassen. Eine fuer den Cube und eine fuer das Graphische, ja? :? .
Ist es auch ok wenn ich die erste 'Cube_building' und die zweite 'Presentating' nenne oder sind Unterstriche in Klassennamen schlecht?

Weiters:
wie schafft man es in einer for-Schleife, das iVar den Wert von iWert annimmt und gleichzeitig auch oVar den Wert von oWert?
Hab schon solche Sachen ausprobiert:

Code: Alles auswählen

for iVar, oVar in iWert, oWert:
    ...
oder
for iVar and oVar in iWert and oWert:
    ...

Hab auch mit Klammern rumprobiert. Aber ja, hoffe ihr versteht wenigstens was ich meine :/ .
BlackJack

Beitragvon BlackJack » Sonntag 9. November 2008, 17:59

Also ich persönlich würde noch eine Klasse für eine Seite eines Würfels springen lassen. Die gibt IMHO genug Daten und Operationen her, um eine eigene Klasse zu rechtfertigen.

Und die GUI kann man sicher auch auf mehrere Klassen aufteilen, also zum Beispiel mindestens ein Widget als "View" (und vielleicht auch "Controller") aus MVC für den Würfel, dass dann in die Anwendung eingebaut werden kann.

Für die ``for``-Frage: Schau Dir mal die Funktionen `zip()`, `itertools.izip()`, und `enumerate()` an.
smashed to pieces
User
Beiträge: 38
Registriert: Samstag 24. November 2007, 16:50

Beitragvon smashed to pieces » Mittwoch 12. November 2008, 21:18

Hatte mir eingebildet das die zip-Funktion keine dictionarys zusammenfassen kann. Funktioniert allerdings einfandfrei :) , danke.

Jetzt ist allerdings ein neues Problem aufgetaucht:
Ich erstelle, mit einer Klasse, ein Fenster und mainloope es. Normalerweise konnte ich, nachdem ich diesen mainloop ausgefuehrt hatte, weiterhin die Oberflaeche, ich diesem Fall eine canvas Oberflaeche veraendern und um es erscheinen zu lassen, updaten:

Code: Alles auswählen

class Root(object):
    def __init__(self):
        self.fieldlist = {'bottom': ((206, 81, 223, 98), (226, 81, 243, 98), (246, 81, 263, 98),
                                     (206, 101, 223, 118), (226, 101, 243, 118), (246, 101, 263, 118),
                                     (206, 121, 223, 138), (226, 121, 243, 138), (246, 121, 263, 138)),
                          'front': ((326, 141, 343, 158), (346, 141, 363, 158), (366, 141, 383, 158),
                                    (326, 161, 343, 178), (346, 161, 363, 178), (366, 161, 383, 178),
                                    (326, 181, 343, 198), (346, 181, 363, 198), (366, 181, 383, 198))}       
       
        self.root = Tk()
        self.root.title("Ein Rubik Cube Programm")
        self.bgcanvas = Canvas(self.root, width=710, height=400, bg='#2ff2ff2ff').pack()
        self.canvas = Canvas(self.root, width=650, height=220, bg='grey')
        self.canvas.place(x=30,y=30)
       
        self.root.mainloop()
   
    def placing_fields(self,colorlist=Cube().main()):
        for seite in self.fieldlist:
            for position in zip(self.fieldlist[seite],colorlist[seite]):
                self.canvas.create_rectangle(position[0][0],position[0][1],position[0][2],position[0][3],fill=position[1])
        self.root.update()
       
Root().placing_fields()


Jetzt kommt allerdings folgende Fahlermeldung:

Traceback (most recent call last):
File "C:\Dokumente und Einstellungen\workspace\Training - Python\src\uebung.py", line 157, in <module>
Root().placing_fields()
File "C:\Dokumente und Einstellungen\workspace\Training - Python\src\uebung.py", line 154, in placing_fields
self.canvas.create_rectangle(position[0][0],position[0][1],position[0][2],position[0][3],fill=position[1])
File "C:\Python25\lib\lib-tk\Tkinter.py", line 2166, in create_rectangle
return self._create('rectangle', args, kw)
File "C:\Python25\lib\lib-tk\Tkinter.py", line 2145, in _create
*(args + self._options(cnf, kw))))
_tkinter.TclError: invalid command name ".12420240"


Das Fenster oeffnet sich wie gewohnt, wenn ich den mainloop aus Zeile 22 loesche und ihn statt dem update in Zeile 28 aufrufe. Doch dann ist das Programm logischerweise unbrauchbar.
Benutzeravatar
numerix
User
Beiträge: 2696
Registriert: Montag 11. Juni 2007, 15:09

Beitragvon numerix » Mittwoch 12. November 2008, 21:32

Du hast noch Schwierigkeiten im Verständnis der OOP.
Statt mit Instanzen zu operieren, operierst du mit Klassen. Eine Klasse ist im Prinzip aber nichts anderes als ein Bauplan für eine Instanz.

Also erzeugst du erst eine Instanz von diesem Bauplan und arbeitest dann mit dieser Instanz.

Also nicht "Root().machwas", sondern z.B. :

Code: Alles auswählen

app = Application()
app.machwas()


Und: Es ist immer hilfreich, wenn du alles an Code postest, was man zum Testen braucht. Die Klasse Cube fehlt aber.

Und: Du solltest dir angewöhnen, Tkinter nicht über *-Import einzubinden. Beliebt ist:

Code: Alles auswählen

import Tkinter as tk

root = tk.Tk()
label = tk.Label(root,text="Ich bin ein Label")
label.pack()
root.mainloop()


Und: Vergiss, dass es den place()-Geometriemanager gibt. :wink:
smashed to pieces
User
Beiträge: 38
Registriert: Samstag 24. November 2007, 16:50

Beitragvon smashed to pieces » Mittwoch 12. November 2008, 22:13

Hm, und wie soll das ohne place() funktionieren :? ?
Codeteil ist da:
http://paste.pocoo.org/show/90990/
Wie man sieht verwend ich die place Funktion reichlich oft ^^.
Stattdessen grind verwenden oder wie war das gemeint ? Weil pack reicht ja nicht aus um mehrerer Buttons zu plazieren.

Zum Code ist noch zu sagen, dass die Fehlermeldung erst beim schliessen des Tk-Fensters kommt.
Wenn man die mainloop-Anweisung statt der update-Anweisung hinschreib, erscheint, beim Ausfuehren des Programmes, das Tk-Fenster, welches eigenltich erscheinen sollte.

und das importieren von Tkinter als tk hat den Sinn das sich Namensraeume nicht ueberschneiden ?
Benutzeravatar
numerix
User
Beiträge: 2696
Registriert: Montag 11. Juni 2007, 15:09

Beitragvon numerix » Mittwoch 12. November 2008, 22:25

smashed to pieces hat geschrieben:Hm, und wie soll das ohne place() funktionieren :? ?
Codeteil ist da:
http://paste.pocoo.org/show/90990/
Wie man sieht verwend ich die place Funktion reichlich oft ^^.
Stattdessen grind verwenden oder wie war das gemeint ? Weil pack reicht ja nicht aus um mehrerer Buttons zu plazieren.


Doch sicher, pack() reicht aus.

smashed to pieces hat geschrieben:und das importieren von Tkinter als tk hat den Sinn das sich Namensraeume nicht ueberschneiden ?


Ja.

Ich verstehe dein vorrangiges Ziel "Hauptsache es läuft", aber das ist kein guter Weg. Setz dich zunächst mal noch weiter mit Tkinter auseinander, bis du die Zusammenhänge und auch die Grundlagen der OOP verstanden hast. Dann kannst du deine jetzigen Probleme selbst lösen.

Zur Lektüre empfohlen: http://www.ferg.org/thinking_in_tkinter/all_programs.html
BlackJack

Beitragvon BlackJack » Mittwoch 12. November 2008, 22:39

@smashed to pieces: Wenn Du die `mainloop()` aufrufst, dann war's das. Da übernimmt Tk dann das Ruder und Du kannst nur noch auf Rückrufe aus der GUI reagieren, die Du vorher "verdrahtet" hast. Das Konzept nennt sich "ereignisbasierte Programmierung".
Benutzeravatar
numerix
User
Beiträge: 2696
Registriert: Montag 11. Juni 2007, 15:09

Beitragvon numerix » Mittwoch 12. November 2008, 22:40

Noch eine Ergänzung zum place()-Geometriemanager: Damit ist dein Layout völlig unflexibel.

Keine Ahnung wie es bei dir aussieht, aber vermutlich nicht so wie auf meinem System (hoffentlich!):

Bild

Mit pack() wäre das nicht passiert ... :wink:
Benutzeravatar
wuf
User
Beiträge: 1368
Registriert: Sonntag 8. Juni 2003, 09:50

Beitragvon wuf » Donnerstag 13. November 2008, 01:31

Hallo smashed to pieces

Hier ist noch die Variante mit dem Pack-Manager, wie es 'numerix' vorschlägt. Dabei kannst du so richtig verschwenderisch mit dem Tk-Widget 'Frame' umgehen. Mit den Pack-Optionen 'side', 'fill', 'expand', 'padx', 'pady' kannst du dann deiner kreativen Begabung freien Lauf lassen :wink:

[Code ausgelagert]

Bild

Gruss wuf :wink:
Zuletzt geändert von wuf am Donnerstag 13. November 2008, 10:10, insgesamt 1-mal geändert.
Take it easy Mates!
smashed to pieces
User
Beiträge: 38
Registriert: Samstag 24. November 2007, 16:50

Beitragvon smashed to pieces » Donnerstag 13. November 2008, 06:59

Ok danke. Also ersteinmal auf place umruesten. :)


@smashed to pieces: Wenn Du die `mainloop()` aufrufst, dann war's das. Da übernimmt Tk dann das Ruder und Du kannst nur noch auf Rückrufe aus der GUI reagieren, die Du vorher "verdrahtet" hast. Das Konzept nennt sich "ereignisbasierte Programmierung".

Das mit dem mainloopen versteh ich jetzt allerdings nicht mehr. Weil ich brauch doch eine mainloop Anwendung damit sich das Fenster erst einmal oeffnet/zeigt. Wenn man dann nicht mehr das Ausstehn aendern kann ist das doch irgendwie falsch, da sich andauernt graphische Oberflaechen bei Programmen veraendern.

Da funktioniert es doch auch so, dass erst ein mainloop erfolgt und spaeter mithilfer der update funktion das Fenster erneuert wird !?
http://paste.pocoo.org/show/91022/
Benutzeravatar
Leonidas
Administrator
Beiträge: 16023
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Beitragvon Leonidas » Donnerstag 13. November 2008, 08:33

smashed to pieces hat geschrieben:Das mit dem mainloopen versteh ich jetzt allerdings nicht mehr. Weil ich brauch doch eine mainloop Anwendung damit sich das Fenster erst einmal oeffnet/zeigt. Wenn man dann nicht mehr das Ausstehn aendern kann ist das doch irgendwie falsch, da sich andauernt graphische Oberflaechen bei Programmen veraendern.

Die Oberflächen verändern sich bei bestimmten Aktionen/Events. Wenn diese Events ausgelöst werden, dann wird in der Regel der Event-Callback aufgerufen, der dann irgendwelche Aktionen ausführt.

Also angenommen du hast einen Button. Dann bindest du eine Funktion an den Button die dann ausgeführt wird, wenn jemand diesen Button klickt.
My god, it's full of CARs! | Leonidasvoice vs Modvoice

Wer ist online?

Mitglieder in diesem Forum: darktrym