Seite 1 von 1

[gelöst]eine pixmap in ein label schreiben

Verfasst: 25. November 2007 23:37
von qtNiko
hi,

durch Probieren habe ich herausbekommen, wie ich ein QPixmap, pixmap, in ein QLabel, graphView reinkriege, sodass es dann auch sichtbar ist.
QLabel graphView befindet sich auf einem QWidget Form. Grafiktest ist ein aus QWidget und Form abgeleitetes Objekt.
Nach den Beispielen, die ich gefunden habe, müsste es so gehen:

Code: Alles auswählen

void Grafiktest::paintEvent(QPaintEvent * /* event */)  { 
	
	QPainter painter(graphView);     <--- graphView ist ein QLabel
	painter.drawPixmap(0, 0, bild);   <--- bild ist ein QPixmap und hier bereits von Datei geladen
	graphView->update();
}
painter soll auf das Label graphView schreiben. Vielleicht tut er das auch, aber ich sehe jedenfalls kein Bild auf diese Weise.
Wenn ich anstelle "QPainter painter(graphView)" schreibe "QPainter painter(this)", dann erscheint das Bild auf dem QLabel graphView. Wie denn das?

Schreibe ich anstelle "graphView->update()" dagegen "update()", so erscheint das Bild auf meinem QWidget Form, was einleuchtet.

Leider konnte ich bisher noch keine Beschreibung über derartige Zusammenhänge finden. Ich finde die Lösung total unlogisch und würde gerne verstehen, was abläuft. Die Probiermethode ist nichts auf Dauer.

Verfasst: 26. November 2007 09:10
von upsala
1. Kann man bei einem QLabel das Pixmap direkt setzen
2. Sollte es auf der Konsole eine Fehlermeldung geben, warum er das nicht tut.
3. In der Doku von QPainter gibt es auch die gewünschte Erklärung dazu.

Verfasst: 26. November 2007 22:26
von qtNiko
Leider ist mir der Mechanismus, wie die Grafiken erzeugt werden, einfach nicht klar.
1. Kann man bei einem QLabel das Pixmap direkt setzen
Das wird mein nächster Versuch. Aber ich möchte erst verstehen, wie das Schreiben mit QPainter funktioniert, siehe unten.
2. Sollte es auf der Konsole eine Fehlermeldung geben, warum er das nicht tut.
Auf der Konsole läuft sogar ständig Text durch. Die folgenden beiden Zeilen werden laufend wiederholt:
  • QPainter::begin: Widget painting can only begin as a result of a paintEvent
    QPainter::setMatrix: Painter not active
aber leider hilft mir das nicht weiter. Es fehlt offensichtlich das paintEvent, aber warum? Wer oder was müsste es auslösen?
3. In der Doku von QPainter gibt es auch die gewünschte Erklärung dazu.
Nun, zu QPainter heißt es, dass er auf alles schreiben kann, was ein QPaintDevice geerbt hat. Da QLabel über QFrame von QWidget abgeleitet ist, nahm ich an, dass auf QLabel geschrieben werden könne. Allerdings steht dann unter QPaintDevice:
"The drawing capabilities of QPaintDevice are currently implemented by the QWidget, QImage, QPixmap, QGLPixelBuffer, QPicture, and QPrinter subclasses"
Nun, das ist jetzt klar - muss man aber auch erst mal finden :(

Meine Tests ergaben, dass ich auf ein QWidget mit QPainter schreiben kann. In der Version, mit der ich die beschriebenen Probleme habe, ist meine GUI-Struktur:
QWidget Form
|-- QLabel graphView
|-- QPushButton okButton
mit folgendem Code innerhalb Grafiktest::paintEvent(): (Grafiktest ist das aus Form und QDialog abgeleitete Objekt)

Code: Alles auswählen

QPainter painter(this);
painter.drawPixmap(0, 0, bild);
update();
konnte ich das Bild auf das QWidget Form schreiben. Ich will aber das Bild innerhalb von graphView sehen.
Logisch, dann mache ich eben anstelle QLabel graphView einfach QWidget graphView und der Code

Code: Alles auswählen

QPainter painter(graphView);
painter.drawPixmap(0, 0, bild);
graphView->update();
müsste das gewünschte Ergebnis bringen - denkste! Es wird wieder kein Bild angezeigt - und warum das nun?
Wo kann man denn nachlesen, wie das alles zusammenhängt, um zu verstehen, woran es hakt?
Tipps, die mir auf die Sprünge helfen, sind sehr willkommen.

Verfasst: 27. November 2007 09:04
von upsala
Warning: When the paintdevice is a widget, QPainter can only be used inside a paintEvent() function or in a function called by paintEvent();

Verfasst: 27. November 2007 16:24
von Zandru
wenn du auf das Label graphView selber malen willst, dann musst du es so machen, dass du das paintevent von graphView selbst implementierst.

Du kannst in einem paintevent immer nur auf "this" zugreifen.

schau dir mal http://doc.trolltech.com/4.3/tutorial-t8.html an, da wird auf das Widget cannonField "gemalt".

Verfasst: 27. November 2007 16:26
von qtNiko
hi,

vielen Dank, jetzt ist es klar.

Das Schreiben mit QPainter war schon in einer paintEvent()-function, aber derjenigen von QWidget/Form und nicht von QWidget/graphView.
Ich dachte halt, dass der paintEvent() von Form alles, d.h. auch sein Child graphView neu zeichnet. Aber das sind eben die Feinheiten, auf die es ankommt :wink:

Verfasst: 28. November 2007 00:26
von qtNiko
alles klar - hatte ich gedacht, d.h. das Schreiben in ein Widget ist mir jetzt schon klar, aber die Probleme gehen doch weiter!

Auf den Tipp von upsala probierte ich es mit dem QLabel direkt. Solange ich nur ein von Datei eingelesenes Bild darstellen möchte, klappt das auch:

Code: Alles auswählen

bild.load(fileName);   // bild ist ein QPixmap
graphView->setPixmap(bild);    // graphView ist ein QLabel
Jetzt möchte ich jedoch das Bild vergrößern und dann darstellen.

Code: Alles auswählen

bild.load(fileName);
QPixmap pixmap = bild.scaled(2,2);
graphView->setPixmap(pixmap);
Das Bild ist nicht zu sehen! Was fehlt denn jetzt wieder - ich reiß mir noch die letzten Haare aus! :evil:

Verfasst: 28. November 2007 07:09
von Burgpflanze
scaled(2,2)
2x2 Pixel? Das ist sehr schwer zu sehen :wink:

Verfasst: 28. November 2007 16:22
von qtNiko
ho, ho

da wir ich in Gedanken beim Skalierungsfaktor :)

Vielen Dank für die Tipps.