Autor |
Beitrag |
Efrel
Hält's aus hier
Beiträge: 11
|
Verfasst: So 10.10.10 22:28
Hi,
ich möchte gern eine Variable (die während eines Rechenprozesses nach oben zählt) "live" zur Laufzeit in einer Label.caption anzeigen lassen.
Habe jetzt schon ein bisschen was probiert, aber bekomme es nicht hin.
Am Code-Beispiel:
Es wird ein Zahlenbereich angegeben, von dem alle Primzahlen ermittelt und in einem Memofeld ausgegeben werden (soweit so gut).
Parallel dazu wird eine Variable (sinnigerweise "Laufvariable" benannt) mitzählen wie viele Primzahlen nacheinander entdeckt werden, also je neue Primzahl inc(Laufvariable).
Dieses Anwachsen soll "live" angezeigt werden.
Hier der Einfachheit halber der Gesamtcode (dort wo die Fragezeichen sind, hänge ich fest):
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54:
| unit primzahlunit;
interface
uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, ExtCtrls;
type TForm1 = class(TForm) Edit1: TEdit; Memo1: TMemo; Panel1: TPanel; Label1: TLabel; Label2: TLabel; Label3: TLabel; Button1: TButton; Edit2: TEdit; Label4: TLabel; procedure Button1Click(Sender: TObject); private public end;
var Form1: TForm1;
implementation
{$R *.DFM}
procedure TForm1.Button1Click(Sender: TObject); var pz:boolean;a,b,e1,e2,Laufvariable:integer; begin d:=0; e1:=strtoint(Edit1.Text); e2:=strtoint(Edit2.Text); if e2<=e1 then Application.MessageBox('Zweite Zahl ist zu klein','Fehler',MB_ICONERROR+MB_OK) else begin memo1.Lines.Clear; for a:=e1 to e2 do begin pz:=true; for b:=2to a div 2 do if a mod b=0 then pz:=false; if pz then begin inc(Laufvariable); memo1.lines.Add(inttostr(a)); end; end; end; end. |
Wäre super, wenn jemand einen Tipp hätte, wie man das Problem lösen kann.
Besten Dank im Voraus!
Efrel
PS: Kann man das Programm während des Rechenprozesses auch stoppen bzw. danach mit "Weiter" auch weiterrechnen lassen?
|
|
Tankard
      

Beiträge: 217
Erhaltene Danke: 96
|
Verfasst: So 10.10.10 22:31
quick and dirty.
application.processmessages;
in der schleife aufrufen.
ist aber unsauber. besser in einen eigenen thread auslagern.
Zuletzt bearbeitet von Tankard am So 10.10.10 22:33, insgesamt 1-mal bearbeitet
Für diesen Beitrag haben gedankt: Efrel
|
|
Luckie
Ehemaliges Mitglied
Erhaltene Danke: 1
|
Verfasst: So 10.10.10 22:33
Formatiere deinen Quelltext bitte mal richtig, damit man auch was erkenne kann.
|
|
Efrel 
Hält's aus hier
Beiträge: 11
|
Verfasst: So 10.10.10 22:40
Luckie hat folgendes geschrieben : | Formatiere deinen Quelltext bitte mal richtig, damit man auch was erkenne kann. |
Sorry, hier noch einmal etwas übersichtlicher:
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55:
| unit primzahlunit;
interface
uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, ExtCtrls;
type TForm1 = class(TForm) Edit1: TEdit; Memo1: TMemo; Panel1: TPanel; Label1: TLabel; Label2: TLabel; Label3: TLabel; Button1: TButton; Edit2: TEdit; Label4: TLabel; procedure Button1Click(Sender: TObject); private public end;
var Form1: TForm1;
implementation
{$R *.DFM}
procedure TForm1.Button1Click(Sender: TObject); var pz:boolean;a,b,e1,e2,Laufvariable:integer; begin d:=0; e1:=strtoint(Edit1.Text); e2:=strtoint(Edit2.Text); if e2<=e1 then Application.MessageBox('Zweite Zahl ist zu klein','Fehler',MB_ICONERROR+MB_OK) else begin memo1.Lines.Clear; for a:=e1 to e2 do begin pz:=true; for b:=2to a div 2 do if a mod b=0 then pz:=false; if pz then begin inc(Laufvariable); memo1.lines.Add(inttostr(a)); end; end; end;
end. |
|
|
Luckie
Ehemaliges Mitglied
Erhaltene Danke: 1
|
Verfasst: So 10.10.10 22:57
Sorry, das sieht genauso grausam aus wie vorher. Zwei Dinge. Wenn es eine lokale Variable ist und die Routine immer wieder neu aufgerufen wird, behält sie ihren Wert nicht. Zweitens musst du der Oberfläche auch die Zeit und die Möglichkeit geben sich neu zu zeichen.
Für diesen Beitrag haben gedankt: Efrel
|
|
Efrel 
Hält's aus hier
Beiträge: 11
|
Verfasst: So 10.10.10 23:05
Luckie hat folgendes geschrieben : | Sorry, das sieht genauso grausam aus wie vorher. Zwei Dinge. Wenn es eine lokale Variable ist und die Routine immer wieder neu aufgerufen wird, behält sie ihren Wert nicht. |
Das leuchtet ein, denn der WErt ändert sich ja fortlaufend.
Luckie hat folgendes geschrieben : |
Zweitens musst du der Oberfläche auch die Zeit und die Möglichkeit geben sich neu zu zeichen. |
Hmm, hier hänge ich scheinbar. Klar, das Aufzählen erfolgt richtig schnell (halt PC-Geschwindigkeit).
Willst Du damit sagen, dass eine Anzeige über Label gar nicht sinnvoll ist, weil es das von der Leistungsfähigkeit der Anzeige nicht schaffen kann?
Welches Element könnte man alternativ verwenden? (Edit-Feld fiele mir auf Anhieb ein...)
Man findet im Net auch leider kein Programmbeispiel für solch eine ähnliche Funktion, wo man sich ein wenig Inspiration holen kann... 
|
|
delphi10
      
Beiträge: 447
Erhaltene Danke: 2
W2K, XP, Vista64, Win7 64
RAD-Studio 2010
|
Verfasst: So 10.10.10 23:07
Tankard hat folgendes geschrieben : | quick and dirty.
application.processmessages;
in der schleife aufrufen.
ist aber unsauber. besser in einen eigenen thread auslagern. |
Es ist auf jeden Fall pragmatisch. ABER es ist ein bösartiger Performance-killer wenn man es in einer Schleife verwendet. Edit: Natürlich kann die Anzeige das schaffen, es wird halt langsamer.
_________________ Salus populi suprema lex esto
Für diesen Beitrag haben gedankt: Efrel
|
|
Efrel 
Hält's aus hier
Beiträge: 11
|
Verfasst: Mo 11.10.10 17:57
Moderiert von Narses: Komplett-Zitat des letzten Beitrags entfernt.
Kann man das anhand irgendeiner Größe quantifizieren, um wieviel % die Leistung dadurch geschälert wird?
Ich weiß, das ist querfeldein geschätzt und hängt wahrscheinlich auch mit der zu errechnenden Routine + PC-Leistung + aktuelles Wetter usw. zusammen, aber vielleicht gibts ja ein Bauchgefühl aus Euren Erfahrungswerten. Ist ja ein Unterschied, ob es ca. 10-20% oder sogar 50%+ sind.
Danke für die Hilfe an alle. Mit application.processmessages; habe ich es auch hinbekommen.
Ich würde jedoch gern noch einmal meine im Eingangspost gestellte Frage in den Raum bringen:
Kann man alle Rechenprozesse (egal ob application.processmessages zur Anzeuge verwendet werden oder nicht) einer Routine auch stoppen (z. B. mittels Button) und dann an der gleichen Stelle die Berechnung fortsetzen (wieder mit Button). Alle Daten der Routine, die möglicherweise im RAM abgelegt wurden, sollen natürlich erhalten bleiben während des Stopps.
|
|
platzwart
      
Beiträge: 1054
Erhaltene Danke: 78
Win 7, Ubuntu 9.10
Delphi 2007 Pro, C++, Qt
|
Verfasst: Mo 11.10.10 18:02
Wenn du das ganze in einen Thread auslagerst, dann ja. Denn kannst du starten (execute), anhalten (suspend), weiterlaufen lassen und killen...
_________________ Wissenschaft schafft Wissenschaft, denn Wissenschaft ist Wissenschaft, die mit Wissen und Schaffen Wissen schafft. (myself)
|
|
Efrel 
Hält's aus hier
Beiträge: 11
|
Verfasst: Mo 11.10.10 18:04
platzwart hat folgendes geschrieben : | Wenn du das ganze in einen Thread auslagerst, dann ja. Denn kannst du starten (execute), anhalten (suspend), weiterlaufen lassen und killen... |
Puhhh... Noch nie was davon gehört.
Kannst Du mir aus dem Stehgreif einen Hinweis geben wie sowas geht oder wo man sowas gut nachschlagen kann.
Edit: OK - grad was dazu gefunden: www.delphi-treff.de/.../threads/einleitung/
Sieht nicht ganz einfach aus... 
|
|
bummi
      
Beiträge: 1248
Erhaltene Danke: 187
XP - Server 2008R2
D2 - Delphi XE
|
Verfasst: Mo 11.10.10 18:34
Ein kleines (sinnloses) Demo
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58:
| unit Unit1;
interface
uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls;
type TForm1 = class(TForm) Button1: TButton; Label1: TLabel; Button2: TButton; Button3: TButton; procedure Button1Click(Sender: TObject); procedure Button2Click(Sender: TObject); procedure Button3Click(Sender: TObject);
private public end;
var Form1: TForm1;
implementation uses Threadtest; {$R *.dfm}
var L_Mythread:TMythread;
Procedure CallBack(i:Integer); begin Form1.Label1.Caption := IntToStr(i); end;
procedure TForm1.Button1Click(Sender: TObject); begin L_Mythread:=TMythread.create(@CallBack); end;
procedure TForm1.Button2Click(Sender: TObject); begin L_Mythread.Suspend; end;
procedure TForm1.Button3Click(Sender: TObject); begin L_Mythread.Resume; end;
end. |
und der Thread dazu
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48:
| unit Threadtest;
interface uses windows,classes; type TCallBackProc=Procedure(Zahl:Integer);
TMythread=Class(TThread)
Procedure Execute;override; Constructor Create(CallBack: TCallBackProc); overload; Private FDummy : Integer; FCallBackProc:TCallBackProc; procedure DoCallBack;
End; implementation
Constructor TMythread.Create(CallBack: TCallBackProc); begin inherited Create(false); FDummy := 0; FCallBackProc := CallBack; FreeOnTerminate := true; end;
procedure TMythread.DoCallBack; begin FCallBackProc(FDummy); end;
procedure TMythread.Execute; begin while not Terminated do begin sleep(100); inc(FDummy); if Assigned(FCallBackProc) then Synchronize(DoCallBack);
end; end;
end. |
Für diesen Beitrag haben gedankt: Efrel
|
|
platzwart
      
Beiträge: 1054
Erhaltene Danke: 78
Win 7, Ubuntu 9.10
Delphi 2007 Pro, C++, Qt
|
Verfasst: Mo 11.10.10 18:38
Ja, ist in der Tat nicht ganz trivial. Aber wenn man es einmal verstanden hat, kann man damit wunderbare Dinge programmieren...
_________________ Wissenschaft schafft Wissenschaft, denn Wissenschaft ist Wissenschaft, die mit Wissen und Schaffen Wissen schafft. (myself)
|
|
Efrel 
Hält's aus hier
Beiträge: 11
|
Verfasst: Mo 11.10.10 18:39
Vielen Dank, Bummi (wie die alte Kinderzeitschrift  )
Werde ich ausführlich anschauen. Das benötigt eine kleine Einarbeitung.
Herzlichen Dank nochmal an alle Helfer!
Efrel
|
|
|