Autor Beitrag
Efrel
Hält's aus hier
Beiträge: 11



BeitragVerfasst: 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):
ausblenden volle Höhe Delphi-Quelltext
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
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  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));
  // label4.caption.add(inttostr(d));  // wie kann man im Label die Laufvariable "live" mit hochzählen lassen ????
   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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Administrator
Beiträge: 217
Erhaltene Danke: 96



BeitragVerfasst: 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



BeitragVerfasst: So 10.10.10 22:33 
Formatiere deinen Quelltext bitte mal richtig, damit man auch was erkenne kann.
Efrel Threadstarter
Hält's aus hier
Beiträge: 11



BeitragVerfasst: So 10.10.10 22:40 
user profile iconLuckie hat folgendes geschrieben Zum zitierten Posting springen:
Formatiere deinen Quelltext bitte mal richtig, damit man auch was erkenne kann.


Sorry, hier noch einmal etwas übersichtlicher:

ausblenden volle Höhe Delphi-Quelltext
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
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  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));
          // label4.caption.add(inttostr(d));  // wie kann man im Label die Laufvariable "live" mit hochzählen lassen
        end;
   end;
end;

end.
Luckie
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: 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 Threadstarter
Hält's aus hier
Beiträge: 11



BeitragVerfasst: So 10.10.10 23:05 
user profile iconLuckie hat folgendes geschrieben Zum zitierten Posting springen:
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.

user profile iconLuckie hat folgendes geschrieben Zum zitierten Posting springen:

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
ontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic starofftopic star
Beiträge: 447
Erhaltene Danke: 2

W2K, XP, Vista64, Win7 64
RAD-Studio 2010
BeitragVerfasst: So 10.10.10 23:07 
user profile iconTankard hat folgendes geschrieben Zum zitierten Posting springen:
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 Threadstarter
Hält's aus hier
Beiträge: 11



BeitragVerfasst: Mo 11.10.10 17:57 
Moderiert von user profile iconNarses: 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
ontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic starofftopic star
Beiträge: 1054
Erhaltene Danke: 78

Win 7, Ubuntu 9.10
Delphi 2007 Pro, C++, Qt
BeitragVerfasst: 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 Threadstarter
Hält's aus hier
Beiträge: 11



BeitragVerfasst: Mo 11.10.10 18:04 
user profile iconplatzwart hat folgendes geschrieben Zum zitierten Posting springen:
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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 1248
Erhaltene Danke: 187

XP - Server 2008R2
D2 - Delphi XE
BeitragVerfasst: Mo 11.10.10 18:34 
Ein kleines (sinnloses) Demo

ausblenden volle Höhe Delphi-Quelltext
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
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  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


ausblenden volle Höhe Delphi-Quelltext
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

{ Mythread }

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
ontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic starofftopic star
Beiträge: 1054
Erhaltene Danke: 78

Win 7, Ubuntu 9.10
Delphi 2007 Pro, C++, Qt
BeitragVerfasst: 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 Threadstarter
Hält's aus hier
Beiträge: 11



BeitragVerfasst: 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