Paintbox leeren
-
DocShoe schrieb:
Such mal nach Double Buffering...
Wie schon DocShoe geschrieben hat such mal nach Double Buffering bzw.
in der Hilfe unter Form->DoubleBuffered.Nur leider haben ein paar Komponenten paar Probleme damit wie z.B. TListView usw.
Deshalb kannst du auch ein Double Buffering selbst machen, indem du statt direkt
auf den Bildschirm zu zeichnen erst in ein TBitmap zeichnest und wenn du fertig bist das komplette Bitmap in die Paintbox malst.
-
VergissEs schrieb:
...Deshalb kannst du auch ein Double Buffering selbst machen, indem du statt direkt
auf den Bildschirm zu zeichnen erst in ein TBitmap zeichnest und wenn du fertig bist das komplette Bitmap in die Paintbox malst.Das habe ich jetzt getan... meine Linie flackert jetzt auch nciht mehr, aber mein Hintergrund dafür... ach ich zeige euch einfach mal meinen Code:
void TForm1::zeichne(){ Label_Pts->Caption = pts; // Hintergrund färben: ImageBuffer->Canvas->Brush->Color = clSilver; ImageBuffer->Canvas->Rectangle(0,0,721,561); // (wohin damit er immer da ist und nicht flackert?) ImageBuffer->Canvas->Pen->Color = clFuchsia; ImageBuffer->Canvas->Ellipse(nom.getPositionX()-2, nom.getPositionY()-2, nom.getPositionX()+3, nom.getPositionY()+3); ImageBuffer->Canvas->Pen->Color = clBlack; ImageBuffer->Canvas->Pen->Width = 5; ImageBuffer->Canvas->MoveTo(Pos[0].getPositionX(), Pos[0].getPositionY()); for(int i=0; i<Pos[0].size(); i++){ ImageBuffer->Canvas->LineTo(Pos[i].getPositionX(), Pos[i].getPositionY()); } } void __fastcall TForm1::PaintBox1Paint(TObject *Sender){ zeichne(); PaintBox1->Canvas->Draw(0, 0, ImageBuffer->Picture->Graphic); } void __fastcall TForm1::Timer1Timer(TObject *Sender){ //... PaintBox1->Invalidate(); //... }
-
VergissEs schrieb:
Nur leider haben ein paar Komponenten paar Probleme damit wie z.B. TListView usw.
Ja, unter anderem auch TPanel. Darauf die PaintBox und TPanel::DoubleBuffered = true. Das sollte eigentlich reichen. Auf dem Panel sollten sich alle zu zeichnenden Objekte befinden.
Ansonsten könnte es auch helfen, den ImageBuffer vorzubereiten, bevor die OnPaint aufgerufen wird.
-
inwiefern vorbereiten?
-
Psychedelixx schrieb:
... meine Linie flackert jetzt auch nicht mehr, aber mein Hintergrund dafür...
das Problem habe ich jetzt... "verkleinert", in dem ich eine Shape mit der Hintergrundfarbe der Paintbox in den Hintergrund gelegt habe. Dennoch flackert zwischendurch die Farbe des Formulars durch (aber weniger als vor dieser Maßnahme)... warum?
edit: ich korrigiere mich: die Shape machts nur noch schlimmer. So flackert die Linie auch wieder...
-
Psychedelixx schrieb:
inwiefern vorbereiten?
Indem du das Image bereits in der Timer-Routine zeichnest, bevor du überhaupt Invalidate aufrufst.
-
irgendwas mache ich falsch
der Hintergrund flackert viel weniger, aber immernoch ein bisschen...
also so mache ich es jetzt:
1. Berechnung
2. Zeichne in unsichtbares BufferImage
3. Kopiere von Image nach PaintBox (im OnPaint Ereignis)
--> wiederhole 1. - 3.Also der Hintergrund meines Formulars ist violett. Die Paintbox soll einen silbernen Hintergrund haben. Hat sie auch größtenteils, aber bei jedem Interrupt erscheint ein horizontaler violetter Streifen im Bild...
-
Überprüfe mal ob dein ImageBuffer auch die Größe hat von der PaintBox
//ImageBuffer->Width
//ImageBuffer->Height
Falls das Bitmap kleiner ist scheint natürlich der Hintergrund durch.
-
Ausserdem dürfte, da du jetzt ins Bitmap zeichnest, der Ablauf nicht mehr stimmen.
Die OnPaint-Methode der PaintBox braucht damit auch keinen Code.In OnTimer:
1. Berechnung
2. Zeichne in unsichtbares BufferImage
3. Kopiere von Image nach PaintBoxDu brauchst kein Invalidate, da der Timer ja jedesmal ein neues Bild zu PBox schiebt.
Warum lese ich immer Image? Du hast doch ein TBitmap ?
-
kpeter schrieb:
Ausserdem dürfte, da du jetzt ins Bitmap zeichnest, der Ablauf nicht mehr stimmen.
Die OnPaint-Methode der PaintBox braucht damit auch keinen Code.In OnTimer:
1. Berechnung
2. Zeichne in unsichtbares BufferImage
3. Kopiere von Image nach PaintBoxDu brauchst kein Invalidate, da der Timer ja jedesmal ein neues Bild zu PBox schiebt.
Warum lese ich immer Image? Du hast doch ein TBitmap ?
mein Held... natürlich, danke
sieht super aus.
Ich hab ein TImage... ist das schlecht?
-
Es ist letztendlich eine Resourcenfrage.
Wenn du das Image sowieso unsichtbar hältst, weil es nix anzeigen soll/braucht,
könntest du gleich ein TBitmap nehmen.
-
worin genau besteht denn der Unterschied?
-
TImage ist eine visuelle Komponente, die du zur Entwurfszeit aufs Formular ziehen kannst.
TBitmap ist hingegen eine nicht visuelle Klasse und wird zur Laufzeit erzeugt und gelöscht.
Das TImage kapselt weitere Klassen (TPicture, TGraphic) und auch ein TBitmap, um es halt zur Designzeit anzeigen zu können.Ein TBitmap nimmt man gern für grafische Operationen, die nicht über den Screen laufen müssen(Zwischenbitmaps).
Ums dir mal zu erleichtern, hier ein einfaches Beispiel zum Erzeugen eines TBitmap:
*.h
#include <stdlib.h> . . . private: Graphics::TBitmap* bmp; public: __fastcall TForm1(TComponent* Owner); __fastcall ~TForm1(void); // Destruktor
*.cpp
__fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner) { bmp = new Graphics::TBitmap; bmp->Width = 200; bmp->Height = 200; PaintBox1->Width = 200; PaintBox1->Height = 200; randomize(); } //--------------------------------------------------------------------------- __fastcall TForm1::~TForm1(void) { delete bmp; } //--------------------------------------------------------------------------- void __fastcall TForm1::Timer1Timer(TObject *Sender) { bmp->Canvas->Brush->Color = clSilver; bmp->Canvas->Rectangle(0, 0, 200, 200); bmp->Canvas->Brush->Color = clRed; bmp->Canvas->Ellipse(random(100), random(100), 100 + random(100), 100 + random(100)); PaintBox1->Canvas->Draw(0, 0, bmp); } //---------------------------------------------------------------------------
-
ahhh vielen vielen Dank :)(auch allen anderen für die Bemühungen)