Inhalt eines Objekts innerhalb des selben Objekts ändern

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
ichbinsisyphos
User
Beiträge: 120
Registriert: Montag 4. Juni 2007, 19:19

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?
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.
ichbinsisyphos
User
Beiträge: 120
Registriert: Montag 4. Juni 2007, 19:19

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.
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

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.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
ichbinsisyphos
User
Beiträge: 120
Registriert: Montag 4. Juni 2007, 19:19

Gibts eine andere Möglichkeit, zu tun was ich tun möchte oder muss ich in Python ohne das leben?
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

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.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
ichbinsisyphos
User
Beiträge: 120
Registriert: Montag 4. Juni 2007, 19:19

Du meinst eine neue Klasse "Pic", ohne Vererbung von QPixmap und die Pixmap nur als Attribut, oder wie man das nennen möchte einbinden?
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

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 :roll:
Das Leben ist wie ein Tennisball.
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

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.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
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.
ichbinsisyphos
User
Beiträge: 120
Registriert: Montag 4. Juni 2007, 19:19

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.
Antworten