Syntax Fehler aber wo?

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
conray
User
Beiträge: 20
Registriert: Donnerstag 4. März 2010, 22:39

Hi @ all

Da ich mich in letzter Zeit etwas intensiver mit dem Thema Python beschäftigt habe , habe ich mich jetzt mal an GUI-Programmierung heran gewagt (Tkinter).

Das Script soll nur bei einem Button das System Herunterfahren beim anderen sich selbst beenden

Code: Alles auswählen

#!/usr/bin/python

from Tkinter import *
import os

class Application(Frame):
	def createWidgets(self):
		self.QUIT = Button(self)
		self.OUIT["text"] = "Herunterfahren"
		self.QUIT["command"] = os.system('init 0')
		
		self.QUIT.pack({"side": "left"})
		
		self.ABORT = Button(self)
		self.ABORT["text"] = "Abbrechen"
		self.ABORT["command"] = self.quit
		
    def __init__(self, master=None):
		Frame.__init__(self, master)
		self.pack()
		self.createWidgets()
		
app = Application()
app.mainloop()
python gibt mir beim Start das das zurück

Code: Alles auswählen

  File "./machaus.py", line 18
    def __init__(self, master=None):
                                   ^
IndentationError: unindent does not match any outer indentation level

aber wie kann da ein Fehler sein?
Oder ist der Fehler ganz woanders?
Version = Python 2.6.4
Hoffe auf Hilfe.
mfg
conray

edit: Name ERROR beseitigt
Zuletzt geändert von conray am Donnerstag 4. März 2010, 23:11, insgesamt 2-mal geändert.
DasIch
User
Beiträge: 2718
Registriert: Montag 19. Mai 2008, 04:21
Wohnort: Berlin

Die Zeilenangabe ist bei Einrückungs- und Syntaxfehlern nicht so genau zu nehmen. In deinem Code sieht man allerdings dass die Zeilen 10 und 16 falsch eingerückt sind. Application ein schlechter Name ist und du PEP8 nicht beachtest. Abgesehen davon hast du einen NameError in Zeile 21.
conray
User
Beiträge: 20
Registriert: Donnerstag 4. März 2010, 22:39

warum sind die Zeilen 10-16 falsch eingerückt? Oder bzw. wie müssen die richtig eingerückt werden?

liegt der Fehler nun an den Einrückungen?

ich muss zugeben das ich durch den ganzen Objektorientiertes Programmieren Kram noch nicht ganz durchsteig aber ich brauchte eben auf die schnelle so ein Fenter :D
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Hallo.

Ich sehe auch nichts, was das mit den Zeilen zu tun haben sollte. Dein Problem liegt in Zeile 18. Diese rückst du mit 4 Leerzeichen ein, Zeile 7 hingegen mit einem Tab. Ein Tab entspricht aber 8 Leerzeichen. Daher ist deine Einrückung kaputt.

Du solltest keine Tabs und Leerzeichen vermischen, nach PEP 8 verwende am besten nur Leerzeichen. Vier Stück pro Ebene. Stelle deinen Editor so um, dass Tabs durch vier Leerzeichen ersetzt werden.

Sebastian

Edit: Ach ja: und du möchtest auch keine *-Importe machen.
Das Leben ist wie ein Tennisball.
Benutzeravatar
numerix
User
Beiträge: 2696
Registriert: Montag 11. Juni 2007, 15:09

Du solltest nicht in einem geposteten Code herumbasteln - das macht es schwierig, Fehler aufzuspüren.

Den einzigen Fehler, der das Programm am Laufen hindert, sehe ich z.Zt. in Zeile 9, denn da steht OUIT statt QUIT. Nachdem ich das behoben habe, "lief" das Programm zumindest.

Insgesamt gilt aber: Kein gelungener Code. Einiges wurde schon dazu gesagt.
conray
User
Beiträge: 20
Registriert: Donnerstag 4. März 2010, 22:39

Also geschireben ist es mit Geany
Die Einrückung sind im Original immer 1 bzw 2 Tabs

was ist an *-Importen so schlimm? in den Beispielen die ich hier hab wird das immer so gemacht darum hab ichs einfach üebrnommen :D
Lieber import _tkinter ?

Habe die 4 Leerzeichen dur einen tab ersetzt, danach diese Meldung

Code: Alles auswählen

Traceback (most recent call last):
  File "./machaus.py", line 3, in <module>
    from Tkinter import *
  File "/usr/lib/python2.6/lib-tk/Tkinter.py", line 39, in <module>
    import _tkinter # If this fails your Python may not be configured for Tk
ImportError: libtk8.5.so: cannot open shared object file: No such file or directory
Habe das jetzt mit import _tkinter gemacht

Code: Alles auswählen

Traceback (most recent call last):
  File "./machaus.py", line 3, in <module>
    from Tkinter import *
  File "/usr/lib/python2.6/lib-tk/Tkinter.py", line 39, in <module>
    import _tkinter # If this fails your Python may not be configured for Tk
ImportError: libtk8.5.so: cannot open shared object file: No such file or directory
Kann es sein das die libtk8.5.so nicht installiert ist? Wenn ja wo ist die dabei?
Insgesamt gilt aber: Kein gelungener Code. Einiges wurde schon dazu gesagt.
Tut mir Leid ich bin noch Anfänger.
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Zu den "nur" Tabs sagt dein Code aber etwas anderes ;-)

Du solltest keine *-Importe benutzen, weil du dir damit den ganzen Namensraum zumüllst und Namenskonflikte vorprogrammiert sind. In Beispielen ist das OK, aber in richtigem Code haben sie nichts zu suchen.

Du solltest "import Tkinter", bzw. "import tkinter" (anhängig von der Pythonversion) benutzen, dann sollte deine letzte Fehlermeldung auch verschwinden.

Edit: Richtige Sätze gebaut.
Das Leben ist wie ein Tennisball.
Benutzeravatar
/me
User
Beiträge: 3555
Registriert: Donnerstag 25. Juni 2009, 14:40
Wohnort: Bonn

conray hat geschrieben:was ist an *-Importen so schlimm?
Du versaust dir deinen Namensraum wenn du völlig unkritisch einfach alles aus einem Modul holst, egal ob du es brauchst oder nicht. Es kommt gar nicht mal so selten vor, dass sich unerfahrene Programmierer durch einen Sternchen-Import andere Sachen überschreiben.
conray hat geschrieben:Habe die 4 Leerzeichen dur einen tab ersetzt, [...]
Mach es umgekehrt und verwende Leerzeichen statt Tabulatoren. Lies mal den Python Style Guide PEP-8, der neben vielen anderen sinnvollen Hinweisen auch dazu etwas sagt.
conray
User
Beiträge: 20
Registriert: Donnerstag 4. März 2010, 22:39

habe das pkg gefunden es heist tkgeomap

Jetzt kommt diese Meldung

Code: Alles auswählen

Traceback (most recent call last):
  File "./machaus.py", line 6, in <module>
    class Application(Frame):
NameError: name 'Frame' is not defined
Definier ich Frame nicht mit dem class Application(Frame) ?


Lese mir den Style Guide gerade durch.
man verzeie mir meine Anfängerfehler :)

mfg
conray
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Da hast du doch ein schönes Beispiel was passiert, wenn man *-Import bentutz. Man weiß nicht mehr, woher welcher Name kommt. Wenn du keine *-Importe verwendest, dann musst du auch qualifiziert auf die Elemente zugreifen:

Code: Alles auswählen

import tkinter
tkinter.Frame

#oder

import tkinter as tk
tk.Frame
Das Leben ist wie ein Tennisball.
conray
User
Beiträge: 20
Registriert: Donnerstag 4. März 2010, 22:39

okay das leuchtet ein :)

Code: Alles auswählen

#!/usr/bin/python

import Tkinter
import os

Tkinter.Frame

class Application(Frame):
	
	
	def createWidgets(self):
		self.QUIT = Button(self)
		self.QUIT["text"] = "Herunterfahren"
		self.QUIT["command"] = os.system('init 0')
		
		self.QUIT.pack({"side": "left"})
		
		self.ABORT = Button(self)
		self.ABORT["text"] = "Abbrechen"
		self.ABORT["command"] = self.quit
		
	def __init__(self, master=None):
		Frame.__init__(self, master)
		self.pack()
		self.createWidgets()

		
app = Application()
app.mainloop()
So sieht es jetzt aus aber es kommt noch die selbe Meldung

Code: Alles auswählen

Traceback (most recent call last):
  File "./machaus.py", line 8, in <module>
    class Application(Frame):
NameError: name 'Frame' is not defined
Benutzeravatar
/me
User
Beiträge: 3555
Registriert: Donnerstag 25. Juni 2009, 14:40
Wohnort: Bonn

OK, es ist schon spät. Solltest du Kaffeetrinker sein, dann setz einen Kaffee auf, stell dich 5 Minuten vor die Tür an die frische Luft, geh dann wieder rein und trink einen großen Schluck Kaffee. Anschließend gehst du zum Computer und schaust dir an was du da gerade verbrochen hast.

...

...

...

...

An der Stelle wo du im alten Code einfach Frame verwendet hast solltest du Tkinter.Frame verwenden. Du solltest nicht Tkinter.Frame einfach lustig irgendwo in den Quellcode schreiben.
conray
User
Beiträge: 20
Registriert: Donnerstag 4. März 2010, 22:39

:D
ok es ist wirklich spät da läuft das Hirn nur noch auf Reserve :D

Habe jetzt alle Frame und Button durch Tkinter.Fram und Tkinter.Button ersetzt und jetzt gehts (endlich :))

Vielen Dank an euch alle das ihr mich zu dieser späten Stunde noch so Tatkräftigt unterstützt habt!
Habe nebenbei auch einiges gelernt :)
Danke nochmal.
mfg
conray

(kann geclosed werden)
Benutzeravatar
/me
User
Beiträge: 3555
Registriert: Donnerstag 25. Juni 2009, 14:40
Wohnort: Bonn

conray hat geschrieben:Vielen Dank an euch alle das ihr mich zu dieser späten Stunde noch so Tatkräftigt unterstützt habt!
<rant>
In Anbetracht mancher Fragen hier ist man ja froh, wenn mal jemand kommt der sinnvolle Fehlermeldungen angibt und dann auch noch mitdenkt.
</rant>

Viel Spaß noch mit Python - und bis zur nächsten Frage. :-)
conray
User
Beiträge: 20
Registriert: Donnerstag 4. März 2010, 22:39

Eine Frage hätte ich noch dazu.
Ich habe den Code ganze nur geschrieben weil ich im LXDE kein Ausschalten Button gefunden habe. Also habe ich selbst einen gemacht , den wollt ich aber nicht nur den Shutdownbefehl mitgeben weil es dann ja sofort runterfährt wenn man draufklickt und dieser Klick kann ja auch mal aus Versehen passieren. Also sollte das Fenster kommen wo man zur Not auch Abbrechen drücken kann :D
Jetzt ist es aber so das wenn ich das Programm hier (machaus) aus der Konsole bzw das Programm mittels Ausschaltenbutton starte fährts gleich runter.
Also der Herunterfahren Button wird gleich aktiviert.
Wie bekomm ich es hin das Programm auf einen Klick wartet?
liegts vllt an dem app.mainloop() ?
mfg
conray
dahaze
User
Beiträge: 75
Registriert: Freitag 13. März 2009, 10:57
Wohnort: im Schwabenland

Versuchs mal so:

Code: Alles auswählen

self.QUIT = Tkitner.Button(self)
self.QUIT["text"] = "Herunterfahren"
self.QUIT["command"] = lambda :os.system('init 0')
oder am besten gleich:

Code: Alles auswählen

self.QUIT = Tkinter.Button(self, text='Herunterfahren', command=lambda :os.system('init 0'))
EDIT:
Tkinter will an dieser Stelle nur einen Pointer auf eine Funktion sehen und diese Funktion wird dann mit dem "Button-Click"-Event verbunden.
Schreibst du an dieser Stelle "os.system('init 0')" bindest du sozusagen nicht die Funktion an das Event sondern den Rückgabewert der Funktion. => Die Funktion wird bereits zu Beginn ausgeführt.

Bsp.:

Code: Alles auswählen

>>> def test():
... 	return 'Die Funktion wurde aufgerufen!'
... 
>>> a = test
>>> b = test()
>>> print a
<function test at 0x00E20808>
>>> print b
Die Funktion wurde aufgerufen!
>>> 
Gruß,
dahaze

EDIT2:
Da war ich wohl zu langsam mit meiner Erklärung! :D
Zuletzt geändert von dahaze am Freitag 5. März 2010, 12:43, insgesamt 2-mal geändert.
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Vielleicht noch zum Verständnis. Mach dir mal den Unterschied klar:

Code: Alles auswählen

>>> def spam(eggs) : print eggs
...
>>> spam
<function spam at 0x2657848>
>>> spam("foo")
foo
Das Leben ist wie ein Tennisball.
conray
User
Beiträge: 20
Registriert: Donnerstag 4. März 2010, 22:39

Code: Alles auswählen

self.QUIT["command"] = lambda :os.system('init 0')
Das hats gebracht :)
Jetzt funktioniert alles so wie ich es wollte :)
Vielen Dank!
mfg
conray

PS @EyDu habs erst nach einigem Überlegen verstanden was dort passiert . Aber gut zu wissen für spätere scripte :) thx
Antworten