Seite 1 von 1
Additionsproblem
Verfasst: Montag 9. November 2009, 13:55
von mr.mc.mauser
Hallo,
ich habe ein kleies Addtionsproblem unter pyqt, ich würde gerne in einen Script ein + und ein + Button verwenden, dazu habe ich hier ein kleines demo script erstellt.
Code: Alles auswählen
#!/usr/bin/env python
import sys
from PyQt4 import QtCore, QtGui
X = 0
class MyWidget(QtGui.QWidget):
def __init__(self, parent=None):
QtGui.QWidget.__init__(self, parent)
plus = QtGui.QPushButton("Plus")
plus.setFont(QtGui.QFont("Times", 18, QtGui.QFont.Bold))
self.connect(plus, QtCore.SIGNAL("clicked()"),self.aktion)
layout = QtGui.QVBoxLayout()
layout.addWidget(plus)
self.setLayout(layout)
def aktion(self):
X += 1
print X
if __name__ == '__main__':
app = QtGui.QApplication(sys.argv)
widget = MyWidget()
widget.show()
sys.exit(app.exec_())
Mein Problem ist die Zeile X += 1 diese wird mir immer als Fehler ausgegeben, wie muss ich hier vorgehen ?
Ich möchte eine Startzahl haben (in diesem Beispiel X=5) und beim klick auf Plus soll X=6 sein beim weiteren klick X=7 usw...
Wäre Prima wenn jemand mir helfen könnte.
Gruß
mc.mauser
Verfasst: Montag 9. November 2009, 14:04
von lunar
Meinst Du nicht auch, dass auch der genaue Text der Fehlermeldung interessant wäre? In diesem Fall ist der Fehler zwar offensichtlich, aber das muss ja nicht so bleiben
Dein Fehler ist, dass "X" in der Methode "aktion" nicht existiert. Python unterscheidet zwischen Namen auf Modulebene "X = 0" und Namen in Klassen, Methoden und Funktionen.
Die Lösung ist, ein Exemplarattribut zu verwenden. Das "X = 0" in Zeile fünf ist zu löschen, dafür muss in "__init__()" ein "self.X = 0" stehen, und in "aktion()" muss es "self.X += 1" und "print self.X" heißen.
Falls Dir das nicht unmittelbar klar ist, dann lese Dir bitte im Tutorial den Abschnitt über Klassen durch. Deren Verständnis ist nämlich essentiell für gute GUI-Programme.
Re: Additionsproblem
Verfasst: Montag 9. November 2009, 14:07
von Hyperion
mr.mc.mauser hat geschrieben:
Mein Problem ist die Zeile X += 1 diese wird mir immer als Fehler ausgegeben, wie muss ich hier vorgehen ?
Lass mich raten, Du bekommst einen NameError? (Eine Fehlermeldung wäre ja schön gewesen!)
Ich möchte eine Startzahl haben (in diesem Beispiel X=5) und beim klick auf Plus soll X=6 sein beim weiteren klick X=7 usw...
Ich würde X niemals groß schreiben! Widerspricht auch PEP8 iirc.
Zu Deinem Problem:
Du solltest Dir noch einmal den Abschnitt über Klassen im Python Tutorial angucken (was Du ja sicherlich schon einmal getan hast

)
Damit wird das ganze trivial zu beantworten sein!
Mein Rat: Vergiss OOP erst einmal und auch GUIs und erlerne die Grundlagen von Python!
Verfasst: Montag 9. November 2009, 14:10
von franzf
Hyperion hat geschrieben:Lass mich raten, Du bekommst einen NameError?
Nein, es ist ein UnboundLocalError
google -> "python globale variable"
->
http://openbook.galileocomputing.de/pyt ... 10_003.htm
->
Verfasst: Montag 9. November 2009, 14:19
von Hyperion
franzf hat geschrieben:Hyperion hat geschrieben:Lass mich raten, Du bekommst einen NameError?
Nein, es ist ein UnboundLocalError
Ja, ich hatte das "X" auf Modul Ebene nicht gesehen, da ich nur auf die Klasse geguckt hatte
Aber das ist hier jetzt nicht Dein Ernst als Tipp, oder?
Verfasst: Montag 9. November 2009, 14:24
von lunar
@Hyperion: Das X auf Modulebene hat schlicht gar nichts damit zu tun. Auch ohne diese Zuweisung wird UnboundLocalError ausgelöst. Der Unterschied zwischen NameError und UnboundLocalError liegt in der Zuweisung.
Verfasst: Montag 9. November 2009, 14:32
von franzf
Hyperion hat geschrieben:
Aber das ist hier jetzt nicht Dein Ernst als Tipp, oder?
Ich darf doch annehmen, dass er weiß dass er X als globale Variable definiert, die dann nicht objektgebunden ist. Wahrscheinlich wollte er es nicht, aber ist ja wurscht

Verfasst: Montag 9. November 2009, 14:44
von lunar
@franzf: Der obligatorische Hinweis, dass global in diesem Fall keine gute Lösung ist, hättest Du im Interesse des OP aber schon noch niederschreiben können

Schließlich ist ja ziemlich offensichtlich, dass der OP nicht so genau weiß, was er tut.
Verfasst: Montag 9. November 2009, 14:44
von mr.mc.mauser
Danke euch allen,
ich werde das nächste mal eine Fehlermeldung mit Posten !!
zu dem Problem kam es übrigens weil vorher da stand
und das hatte geklappt !!
also hatte ich mir überlegt das wenn X angezeigt wird, dann kannst du es ja auch benutzen, gut war nicht so.
Mir ist sehr wohl bewusst das man Variablen oder Objekte nicht X nennt, aber ich wollte halt auf die schnelle ein Skript machen was mein Problem darstellt.
Das mit dem
global X ist eigentlich genau das was ich wissen wollte.
vielen vielen Dank.
Übrigens habe ich schon 2 Bücher über Python gelesen, nur manchmal sieht man den Wald vor lauter Bäumen eben nicht mehr, zumal ja wie oben beschrieben die Ausgabe von X funktioniert hat.
Nochmals vielen vielen Dank
Gruß
mc.mauser
Verfasst: Montag 9. November 2009, 15:39
von lunar
@mr.mc.mauser: Nein, "global" ist nicht das, was Du gesucht hast. Vergiss am besten, dass es dieses Schlüsselwort überhaupt gibt. Von wenigen Ausnahmen abgesehen ist seine Verwendung ein Zeichen mangelnder Qualität.
Die richtige und sinnvolle Lösung habe ich Dir genannt.
Verfasst: Montag 9. November 2009, 16:23
von Hyperion
lunar hat geschrieben:@Hyperion: Das X auf Modulebene hat schlicht gar nichts damit zu tun. Auch ohne diese Zuweisung wird UnboundLocalError ausgelöst. Der Unterschied zwischen NameError und UnboundLocalError liegt in der Zuweisung.
Guter Hinweis, da war ich beim Testen zu "faul":
Code: Alles auswählen
In [6]: x += 1
---------------------------------------------------------------------------
NameError Traceback (most recent call last)
C:\Dokumente und Einstellungen\MECL User 1\<ipython console> in <module>()
NameError: name 'x' is not defined
Dabei entsprach die Situation diesem hier:
Code: Alles auswählen
In [7]: def foo():
...: x += 1
...:
...:
In [8]: foo()
---------------------------------------------------------------------------
UnboundLocalError Traceback (most recent call last)
C:\Dokumente und Einstellungen\MECL User 1\<ipython console> in <module>()
C:\Dokumente und Einstellungen\MECL User 1\<ipython console> in foo()
UnboundLocalError: local variable 'x' referenced before assignment
Mit einer geposteten Fehlermeldung wäre das natürlich einfacher gewesen
@OP: Welche Bücher denn? Man ahnt da ja was

Verfasst: Montag 9. November 2009, 17:15
von mr.mc.mauser
@Hyperion du fragst welche Bücher:
Das Python Praxisbuch von Farid Hajji
Python Openbook von Gallileo Press
diese Beiden habe ich gelesen
dann habe ich noch das Python Ge-Packt von Michael Weigend
und Python kurz und Gut von O'reilly
und Natürlich das Wkibook Python unter Linux
diese Bücher nehme ich mehr oder weniger zum Nachschlagen
bestellt habe ich mir noch das Rapid GUI Programming with Python and QT von Mark Summerfield.
Jetzt habe ich mal im Praxisbuch nachgelesen was ich wollte (Seite 232), mir hatte eigentlich nur das Stichwort gefehlt.
Und ich habe definitiv die sache mit dem Global gemeint !
denn diese Variable brauche ich nicht nur in dieser Klasse sondern in meinem gesamten Programm immer und immer wieder
das war auch der Grund warum ganz oben X gesetzt wurde !!
Gruß
mc.mauser
Verfasst: Montag 9. November 2009, 17:21
von cofi
mr.mc.mauser hat geschrieben:Und ich habe definitiv die sache mit dem Global gemeint !
denn diese Variable brauche ich nicht nur in dieser Klasse sondern in meinem gesamten Programm immer und immer wieder
das war auch der Grund warum ganz oben X gesetzt wurde !!
Mag sein, dass du das gemeint hast, allerdings solltest du dir vor Augen halten, dass globale Variablen zu aendern eine sehr grosse Fehlerquelle ist, die man vermeiden sollte.
Verfasst: Montag 9. November 2009, 20:17
von lunar
@mr.mc.mauser: Das fällt dann genau unter den erwähnten Punkt "mangelnde Qualität". Wenn Du globale Attribute benötigst, ist beim Entwurf etwas schief gegangen.
Globale Attribute führen zu hoher Koppelung einzelner Teile der Anwendung, die in der Folge nicht mehr isoliert betrachtet werden können. Sie sind folglich nur in geringem Maße wiederverwendbar, zudem sehr schlecht wartbar, weil Änderungen Auswirkungen auf völlig unzusammenhängende Programmteile haben können, und schlecht testbar, weil jede einzelne Komponenten dann nicht nur einen internen Zustand hat, sondern auch von einem globalen Zustand abhängt.
Es hat schon seine Gründe, warum ich Dir sage, dass Du global nicht nutzen solltest.