Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi Image wieder blank machen (https://www.delphipraxis.net/102458-image-wieder-blank-machen.html)

Avicenna 29. Okt 2007 13:03


Image wieder blank machen
 
Hallo,
mein Delphi-Programm soll wie folgt funktionieren:
Es besteht aus einem Image-Feld, und in procedure TForm1.Timer1Timer(Sender: TObject); ist folgendes zu finden:
Code:
image1.canvas.ellipse(10+6*sekunde,10,15+6*sekunde,15);
, wobei zugleich gilt:
Code:
sekunde:=sekunde+1;
D.h., jede Sekunde kommt ein neuer Kreis hinzu, und nach 60 Sekunden sind 60 Kreise gemalt worden. Nun sollen alle Kreise wieder verschwinden und die Prozedur von vorne losgehen.
Aber wie mache ich das?

Gruß,
Avicenna

Bastler 29. Okt 2007 13:08

Re: Image wieder blank machen
 
einfach das Image wieder mit nem Recheck überzeichnen...

Also:
Delphi-Quellcode:
procedure image_blank;
var bc,pc:Tcolor;
begin
with Form1.Image1.canvas do
  begin
  pc:=Pen.Color;                              //alte Farben speichern
  bc:=Brush.Color;
  Pen.Color:=clwhite;
  Brush.Color:=clwhite;
  Rectangle(0,0,image1.Width, image1.Height); //übermalen
  Pen.Color:=pc;                              //alte Farben wieder zuweisen
  Brush.Color:=bc;
end;
end;
so würd ich's machen...

Avicenna 29. Okt 2007 13:28

Re: Image wieder blank machen
 
Danke für deine Antwort, aber du verwendest zu viele Sachen, die ich noch gar nicht gelernt habe (z. B. with-do). Die Lehrerin beschrieb es so: Man muss das Rechteck einfach wieder weiß machen.

Kennt jemand einen einfacheren Weg als der von Bastler?

leddl 29. Okt 2007 13:54

Re: Image wieder blank machen
 
Zitat:

Zitat von Avicenna
Die Lehrerin beschrieb es so: Man muss das Rechteck einfach wieder weiß machen.

:gruebel: Und genau das hat dir Bastler doch auch geraten... Wenn dir der Code zu kompliziert ist, musst du ihn ja nicht benutzen. Fakt ist aber, dass er dir ja auch schon gesagt hat, was du tun musst. Und nachdem auch die Lehrerin den Tipp gegeben hat, werdet ihr wohl auch schon über die nötigen Kenntnisse verfügen :zwinker:

Neutral General 29. Okt 2007 14:00

Re: Image wieder blank machen
 
Hi,

Wenns statt weiß auch transparent sein darf dann empfehle ich:

Delphi-Quellcode:
Image1.Picture.Bitmap.Assign(nil);
:)

EDIT: Wobei wenn du direkt auf das Canvas des Images malst dürfte sogar ein Image1.Invalidate; reichen.

Gruß
Neutral General

Avicenna 29. Okt 2007 14:48

Re: Image wieder blank machen
 
Danke für eure Antworten, die von Neutral General genannten Codes scheinen die optimalsten zu sein, bloß stehe ich jetzt vor dem nächsten Problem:
Wie soll ich dem Programm vermitteln, dass es dann blank werden soll, wenn 60 Kreise gemalt wurden?

Apollonius 29. Okt 2007 14:50

Re: Image wieder blank machen
 
Einfach im onTimer schauen, wie viele Kreise schon gemalt worden sind.

NickelM 29. Okt 2007 15:04

Re: Image wieder blank machen
 
Um auf Apollonius Antwort zurückzukommen. Um jetzt diesen Schrittt zuwiederholen musst du ne eigene Prozedure schreiebn und ne If - then anweisung:

Delphi-Quellcode:
{eigene prozedure}
procedure Zeichnen;
begin
Image1.Canvas....
end;
{Timer}
procedure TForm1.Timer1Timer(Sender : TObject)
begin
Zeichnen;
If Sekunde = Gewünschte Zahl* then
begin
Image1.Invalidate;
Zeichnen;
end;

end;

leddl 29. Okt 2007 15:30

Re: Image wieder blank machen
 
Zitat:

Zitat von NickelM
Um auf Apollonius Antwort zurückzukommen. Um jetzt diesen Schrittt zuwiederholen musst du ne eigene Prozedure schreiebn und ne If - then anweisung:

:gruebel: Wieso muss sie (?) ne extra Prozedur schreiben? :gruebel:
Delphi-Quellcode:
var: sekunde : Integer;

[...]
  sekunde := 0;
[...]

procedure TForm1.Timer1Timer(Sender : TObject)
begin
  if sekunde = 59 then
  begin
    Image1.Invalidate;
    sekunde := 0;
  end
 
  image1.canvas.ellipse(10+6*sekunde,10,15+6*sekunde,15);
  inc(sekunde);
end;

DeddyH 29. Okt 2007 15:35

Re: Image wieder blank machen
 
Müsste Sekunde nicht 60 sein, bevor neu gezeichnet wird? Sonst würde IMHO der 60. Kreis nicht mehr gezeichnet.

Avicenna 29. Okt 2007 16:41

Re: Image wieder blank machen
 
Es will bei mir nicht funktionieren!
Es sieht bei mir so aus:
Delphi-Quellcode:
procedure TForm1.Timer1Timer(Sender: TObject);
begin
sekunde:=sekunde+1;
begin;
if sekunde > 59 then
begin;
sekunde:=0;
minute:=minute+1;
end;
if minute > 59 then
begin
minute:=0;
stunde:=stunde+1;
end;
if stunde > 59 then
stunde:=0;

label1.caption:='Zeit:'+ausgabestd+':'+ausgabemin+'.'+ausgabesek;

image1.canvas.ellipse(10+6*sekunde,10,15+6*sekunde,15);

if sekunde = 59 then
Image1.Invalidate;

end

end;

DeddyH 29. Okt 2007 16:51

Re: Image wieder blank machen
 
:shock: Was machst Du denn da mit den ganzen begins und ends?

Avicenna 29. Okt 2007 16:55

Re: Image wieder blank machen
 
Ist es falsch oder einfach nur unschön? (Delphi meckert nicht!) :-D

Neutral General 29. Okt 2007 16:57

Re: Image wieder blank machen
 
Sagen wir mal.. es ist nicht falsch.. aber dafür hässlich und unübersichtlich ;)

DeddyH 29. Okt 2007 16:58

Re: Image wieder blank machen
 
Semikolon hinter einem begin lässt Delphi durchgehen? Hab ich noch nie versucht.

[edit] Schreibrechtfehler [/edit]

Avicenna 29. Okt 2007 17:12

Re: Image wieder blank machen
 
Okay, dann bleibt ja nur noch die Frage, warum mein Programm nicht funktioniert.

DeddyH 29. Okt 2007 17:15

Re: Image wieder blank machen
 
Sag doch erstmal, was nicht funktioniert.
BTW: Bist Du sicher mit den 59 Stunden?

leddl 29. Okt 2007 17:32

Re: Image wieder blank machen
 
Zitat:

Zitat von DeddyH
Müsste Sekunde nicht 60 sein, bevor neu gezeichnet wird? Sonst würde IMHO der 60. Kreis nicht mehr gezeichnet.

Jepp, müsste es :oops: Hatte den Teil erst am Ende der Methode und beim Umkopieren dann vergessen, das zu ändern ;)

DeddyH 29. Okt 2007 17:33

Re: Image wieder blank machen
 
Shit happens ;)

rawsoul 29. Okt 2007 17:34

Re: Image wieder blank machen
 
Delphi-Quellcode:
[...]
var
  Form1: TForm1;
  sekunde:integer=0;
  minute:integer=0;
  stunde:integer=0;

[...]

procedure TForm1.Timer1Timer(Sender: TObject);
begin
  sekunde:=(sekunde+1) mod 60;
  if sekunde=59 then begin minute:=(minute+1) mod 60; image1.invalidate end;
  if minute=59 then stunde:=(stunde+1) mod 60;
  image1.canvas.ellipse(10+6*sekunde,10,15+6*sekunde,15);
end;

[...]
Bei mir funktioniert es so bestens.

Avicenna 29. Okt 2007 17:47

Re: Image wieder blank machen
 
Bei mir tut sich da einfach nichts.
Ich poste jetzt mal den kompletten Quelltext von procedure TForm1.Timer1Timer(Sender: TObject);:
Delphi-Quellcode:
procedure TForm1.Timer1Timer(Sender: TObject);
begin

 if stunde < 10 then
 ausgabestd:='0'+inttostr(stunde);
 if stunde >= 10 then
 ausgabestd:=inttostr(stunde);
 if minute < 10 then
 ausgabemin:='0'+inttostr(minute);
 if minute >= 10 then
 ausgabemin:=inttostr(minute);
 if sekunde < 10 then
 ausgabesek:='0'+inttostr(sekunde);
 if sekunde >= 10 then
 ausgabesek:= inttostr(sekunde);

sekunde:=sekunde+1;
begin;
if sekunde > 59 then
begin;
sekunde:=0;
minute:=minute+1;
image1.invalidate;
end;
if minute > 59 then
begin
minute:=0;
stunde:=stunde+1;
end;
if stunde > 59 then
stunde:=0;

label1.caption:='Zeit:'+ausgabestd+':'+ausgabemin+'.'+ausgabesek;

image1.canvas.ellipse(10+6*sekunde,10,15+6*sekunde,15);

if sekunde = 59 then
Image1.Invalidate;

end

end;
außerdem noch die Variablendeklaration:
Delphi-Quellcode:
var
  Form1: TForm1;
  stunde,minute,sekunde:integer;
  ausgabestd,ausgabemin,ausgabesek:string;
Ich hoffe, ihr könnt mir so weiterhelfen.

DeddyH 29. Okt 2007 17:49

Re: Image wieder blank machen
 
Ist der Timer auch enabled?

Progman 29. Okt 2007 17:52

Re: Image wieder blank machen
 
sollte es nicht anstelle von
Delphi-Quellcode:
if stunde > 59 then stunde:=0;
eher heißen:
Delphi-Quellcode:
if stunde > 23 then stunde:=0;
?
Und was geht denn nicht? Wird nichts gezeichnet?

DeddyH 29. Okt 2007 17:57

Re: Image wieder blank machen
 
Ich habe mal schnell eine Version mit weniger Variablen (dafür mit mehr Berechnungen) erstellt:
Delphi-Quellcode:
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ExtCtrls;

type
  TForm1 = class(TForm)
    Image1: TImage;
    Timer1: TTimer;
    Label1: TLabel;
    procedure FormCreate(Sender: TObject);
    procedure Timer1Timer(Sender: TObject);
  private
    { Private-Deklarationen }
    sekunde: Cardinal;
  public
    { Public-Deklarationen }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
begin
  sekunde := 0;
end;

procedure TForm1.Timer1Timer(Sender: TObject);
begin
  if (sekunde mod 60) = 0 then
    image1.Canvas.FillRect(Rect(0,0,Image1.Width,Image1.Height));
  image1.canvas.ellipse(10 + 6 * (sekunde mod 60),10,15 + 6 * (sekunde mod 60),15);
  Label1.Caption := Format('%.2d:%.2d:%.2d',[Succ(sekunde) div 3600,
                                             Succ(sekunde) div 60,
                                             Succ(sekunde) mod 60]);
  inc(sekunde);
end;

end.
[edit] Für lange Laufzeiten sekunde als Cardinal statt integer umdeklariert *gg* [/edit]

marabu 29. Okt 2007 18:02

Re: Image wieder blank machen
 
Hi,

hier noch was zum knobeln:

Delphi-Quellcode:
procedure TDemoForm.ClockTimer(Sender: TObject);
var
  r: TRect;
  dt: TDateTime;
begin
  with Sender as TTimer do
  begin
    Enabled := False;
    dt := Now;
    Panel.Caption := TimeToStr(dt);
    with Image do
    begin
      if SecondOf(dt) mod 5 = 0 then
        Canvas.FillRect(Canvas.ClipRect);
      r := Rect(Random(Width), Random(Height), Random(Width), Random(Height));
      Canvas.Ellipse(r);
    end;
    Interval := 1000 - MilliSecondOf(Now);
    Enabled := True;
  end;
end;
Grüße vom marabu

DeddyH 29. Okt 2007 18:03

Re: Image wieder blank machen
 
Jaja, DateUtils

Avicenna 29. Okt 2007 18:34

Re: Image wieder blank machen
 
Liste der Anhänge anzeigen (Anzahl: 1)
Danke für eure Antworten.
Der Timer ist enabled.
Danke für den Hinweis mit der Stunde (>23), ich habe es ausgebessert.
Aber gehen tut es immer noch nicht.

Problembeschreibung:
Pro Sekunde wird ein Kringel hinzugefügt. Nach 60 (oder 59, das spielt keine Rolle) Sekunden sind dann 60 (oder 59) Kringel da, und rien ne va plus. Nichts passiert mehr.

Erwünschte Problemlösung:
Es geht wieder von vorne los, d.h. alle 60 (oder 59) Kringel verschwinden. In der nächsten Sekunde kommt wieder ein Kringel usw. usf.

DeddyH 29. Okt 2007 18:36

Re: Image wieder blank machen
 
Hast Du meine Lösung mal versucht? Invalidate hat bei mir auch nicht genügt, weswegen ich das ganze Image einfach komplett übermale. Die "fehlenden" Variaben kannst Du ja dann wieder deklarieren.

Progman 29. Okt 2007 18:45

Re: Image wieder blank machen
 
Ich würde auch sagen, das Image mit FillRect neu zeichnen. Dann dürfte einem erneuten Zeichnen nichts mehr im Wege stehn...
Es sei denn, irgendwas anderes läuft noch schief, nur ich kann das jetzt nicht ausprobieren.

Avicenna 29. Okt 2007 19:37

Re: Image wieder blank machen
 
Bei dir kommt mod vor, das haben wir noch nicht gelernt. Was bedeutet das denn?

Progman 29. Okt 2007 19:40

Re: Image wieder blank machen
 
mod gibt bei einer Division den Rest zurück, während div den ganzzahligen Teil zurückliefert.
Beispiel: 13 mod 5 ergibt 3 (2 mal 5 ist 10, Rest 3), währen 13 div 5 2 ergibt (also nur den ganzzahligen Anteil)

Hador 29. Okt 2007 19:59

Re: Image wieder blank machen
 
Hallo Avicenna,

ich habe einfach deinen Quellcode genommen und ihn ein wenig korregiert.
Ich habe die Funktion zwar nicht getestet, aber hoffe, dass sie so funktioniert.
Was ich neu eingefügt oder verändert habe, habe ich kommentiert.

Delphi-Quellcode:
procedure TForm1.Timer1Timer(Sender: TObject);
begin
   if stunde < 10 then
      ausgabestd:='0'+inttostr(stunde)
   else // wenn's nicht kleiner 10 ist, ist es größer oder gleich 10
      ausgabestd:=inttostr(stunde);
      
   if minute < 10 then
      ausgabemin:='0'+inttostr(minute)
   else
      ausgabemin:=inttostr(minute);
      
   if sekunde < 10 then
      ausgabesek:='0'+inttostr(sekunde)
   else
      ausgabesek:= inttostr(sekunde);

   sekunde := sekunde + 1;
 
   if sekunde > 59 then
   begin // Schreibe _niemals_ ein ; hinter ein begin. Das gehört da einfach nicht hin!
      sekunde:=0;
      minute:=minute+1;
      image1.invalidate;
   end;
   if minute > 59 then
   begin
      minute:=0;
      stunde:=stunde+1;
   end;
   if stunde > 59 then
      stunde:=0;

   label1.caption := 'Zeit:'+ausgabestd+':'+ausgabemin+'.'+ausgabesek;

  image1.canvas.ellipse(10+6*sekunde,10,15+6*sekunde,15);

   if sekunde >= 59 then
      Image1.Canvas.FillRect(Rect(0, 0, Image1.Picture.Width, Image1.Picture.Height));
   // Hierzu folgende Erklärung:
   // Die Methode FillRect füllt ein angegebenes Rechteck mit der in clBrush angegebenen Farbe (Standard ist imho weiß)
   // Das zu füllende Rechteck Legen wir mit der Funktion Rect fest. Dieser Funktion müssen wir die Koordinaten
   // der Eckpunkte oben-links und unten-rechts angeben.
   // Oben-links ist ganz einfach. Da es der Ursprung ist, sind die Koordinaten 0 und 0.
   // Unten-rechts Sind die Koordinaten die Breite des Bildes und die Höhe des Bildes (Wir wollen ja die ganze Fläche füllen).
   // Die Breite bekommen wir mit Image1.Picture.Width heraus. Die Höhe äquivalent dazu mit Image1.Picture.Height

end

end;
EDIT:
Noch was vergessen:
Du solltest deinen Quellcode ein wenig formatieren. Vorallem die Einrückung macht das ganze wesentlich übersichtlicher. Sonst blickst du vorallem bei größeren Mengen an Quellcode schnell überhaupt nicht mehr durch.

Avicenna 29. Okt 2007 20:14

Re: Image wieder blank machen
 
Zitat:

Zitat von Avicenna hat vor Hadors Beitrag folgendes geschrieben

DeddyH'S Vorschlag funktioniert :)

Kann mir nun noch jemand ein Programm programmieren, das mir verrät, wie ich meiner Lehrerin sage, dass ich weiß, was mod ist? Von Succ, div und '%.2d:%.2d:%.2d' ganz abgesehen :P


Auf jeden Fall mal ein großes Dankeschön an alle, die versucht haben, mir zu helfen :thumb:

Hador, dich schickt der Himmel! Es funktioniert, enthält nur mir bekannte Dinge und ist einfach super erklärt! Vielen Dank für die Mühe!

Wobei allen anderen selbstverständlich auch mein Dank gilt.


Gruß,
Avicenna


Alle Zeitangaben in WEZ +1. Es ist jetzt 02:03 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz