Seite 1 von 1
Inhalt eines Objekts innerhalb des selben Objekts ändern
Verfasst: Montag 27. April 2009, 10:56
von ichbinsisyphos
lol, sorry für den Titel ...
Wie erklär ich das verständlich ...
Ich hab eine Klasse Pic, die eine Unterklasse von PyQt4.QtGui.QPixmap ist.
Code: Alles auswählen
class Pic(QtGui.QPixmap):
def _init_(self, filename):
QtGui.QPixmap._init_(self, filename)
def rotate(self, angle):
w_old = self.width()
h_old = self.height()
qm = QtGui.QMatrix()
qm.rotate(angle)
self = self.transformed(qm)
w = self.width()
h = self.height()
self = self.copy(QtCore.QRect((w - w_old)/2, (h - h_old)/2 , w_old, h_old))
Unter anderem möchte ich die Bilder rotieren, beschneiden, womöglich spiegeln, etc...
Im Hauptprogramm stell ich mir vor:
Code: Alles auswählen
picture = Pic("Bild0001.jpg")
picture.rotate(45)
self.display_area.setPixmap(picture)
Funktioniert aber nicht, im Gegensatz zu:
Code: Alles auswählen
picture = Pic("Bild0001.jpg")
picture = picture.rotate(45)
self.display_area.setPixmap(picture)
self.display_area ist ein QtGui.QLabel des main window, in dem das Bild angezeigt werden soll.
Ich versteh irgendwie nicht, wo das Problem liegt. Mit "self =" sollte er doch den Inhalt ändern, und nicht irgendwie ein Kopie erzeugen und zurückliefern ... Wo liegt mein Denkfehler?
Verfasst: Montag 27. April 2009, 12:27
von lunar
"self" ist nur ein Name, nicht mehr. Eine Zuweisung an "self" bindet nur diesen Namen an ein neues Objekt. Der Inhalt des vorher gebundenen Objekts wird dadurch nicht angetastet.
Qt4 erlaubt es nicht, Bilder direkt zu manipulieren, jede Manipulation erzeugt eine Kopie. Im Übrigen ist QPixmap nicht unbedingt die geeignete Klasse für Bildmanipulation. Dafür gibt es QImage.
Wenn es dir nur darum geht, dass Bild gedreht anzuzeigen, ist es möglicherweise klüger, direkt mit QPainter auf ein QWidget zu zeichnen. QPainter bietet fertige Methoden zum Drehen, dass dürfte einfacher sein. Für umfangreichere Darstellungen wäre dann QGraphicsView zu empfehlen.
Davor aber steht noch wohl noch einiges an Python-Grundlagen auf dem Plan.
Verfasst: Montag 27. April 2009, 12:44
von ichbinsisyphos
Ich kenn Klassen bisher nur von C++, und dort geht sowas auf alle Fälle.
Die Zuweisung bindet "self" an ein neues Objekt, der neue Inhalt ist dann aber nicht unter dem alten "äußeren" Namen (also picture) abrufbar?
Gibt's in Python die Möglichkeit das Verhalten von "*this" in C++ nachzuahmen?
Von all den Klassen die ich probiert hab (QImage, QPixmap, QPainter, ...) ist für meine Zwecke QPixmap die unkomplizierteste, deswegen QPixmap und nicht QImage. Kann schon sein, dass ich mir die anderen nochmal ansehe, hat aber keine Priorität.
Verfasst: Montag 27. April 2009, 13:37
von Leonidas
ichbinsisyphos hat geschrieben:Die Zuweisung bindet "self" an ein neues Objekt, der neue Inhalt ist dann aber nicht unter dem alten "äußeren" Namen (also picture) abrufbar?
Ja, weil es Referenzen sind, nicht Pointer.
Verfasst: Montag 27. April 2009, 14:18
von ichbinsisyphos
Gibts eine andere Möglichkeit, zu tun was ich tun möchte oder muss ich in Python ohne das leben?
Verfasst: Montag 27. April 2009, 14:27
von Leonidas
Du könntest in deiner ``Pic``-Klasse die ``QPixmap`` durch deine neue, rotierte ``QPixmap`` ersetzen. Allerdings musst du schauen, wie das mit dem GUI-Toolkit zusammenspielt.
Verfasst: Montag 27. April 2009, 14:38
von ichbinsisyphos
Du meinst eine neue Klasse "Pic", ohne Vererbung von QPixmap und die Pixmap nur als Attribut, oder wie man das nennen möchte einbinden?
Verfasst: Montag 27. April 2009, 14:45
von EyDu
Du könntest es so versuchen:
Code: Alles auswählen
>>> class Picture(object):
... def test(self):
... print "test"
...
>>> class Spam(object):
... def __init__(self):
... self.data = Picture()
... def eggs(self):
... print "eggs"
... def __getattr__(self, name):
... try:
... return self.__dict__[name]
... except KeyError:
... return getattr(self.__dict__["data"])
...
>>> spam = Spam()
>>> spam.test()
test
>>> spam.eggs()
eggs
>>> spam.data
<__main__.Picture object at 0x18d6d10>
>>>
Oder natürlich eine sinnlos große Lösung mit Metaklassen

Verfasst: Montag 27. April 2009, 17:02
von Leonidas
ichbinsisyphos hat geschrieben:Du meinst eine neue Klasse "Pic", ohne Vererbung von QPixmap und die Pixmap nur als Attribut, oder wie man das nennen möchte einbinden?
Ja, genau. Komposition statt Vererbung.
Verfasst: Montag 27. April 2009, 20:10
von lunar
ichbinsisyphos hat geschrieben:Gibts eine andere Möglichkeit, zu tun was ich tun möchte oder muss ich in Python ohne das leben?
Nein. In Python kannst du eine Klasseninstanz nicht von innen heraus über eine Zuweisung ändern. Ein Ansatz über Komposition, wie er hier vorgeschlagen wurde, funktioniert bei Qt4 auch nicht.
Im Übrigen bezweifele ich, dass eine Zuweisung an "*this" bei C++ und Qt4 funktioniert. Qt4 speichert QPixmap auf allen Unix-Derivaten nicht clientseitig, sondern im X-Server. Daher ist QPixmap auch nicht geeignet für Bildmanipulation, da das unter X11 über die Serververbindung sehr langsam ist.
Verfasst: Mittwoch 29. April 2009, 17:25
von ichbinsisyphos
Also die Komposition funktioniert auf alle Fälle. Ich hab keine Ahnung was du da für Probleme erwartest.
QPainter muss mit einer QPixmap oder QImage initialisiert werden.
QImage kann auch nur mit Transformationsmatrix rotiert werden.
So wie das sehe erspare ich mir, wenn ich gleich QPixmap nehme, je nachdem 2 bis 3 Schritte vom Laden bis zur Anzeige. Ich will keine Bilder manipulieren, nur eine Anzeige, eine Art Vorschau. Die Manipulation an den source-files mach ich mit imagemagick.