Button.Enabled:= true|false;

Für Fragen von Einsteigern und Programmieranfängern...
oliver2104
Beiträge: 48
Registriert: Sa 26. Dez 2020, 13:22

Button.Enabled:= true|false;

Beitrag von oliver2104 »

Hallo,
hab ein Problem bei dem ich nicht mehr weiterkomme.
Vereinfacht gesagt geht's um ein Programm bestehend aus einem Formular (Form1) darin befinden sich ein Image und 3 Buttons.
Der erste Button (ButtonRender) setzt die Pixel im Image, das kann schon 2-3 sec dauern. In dieser Zeit sollen die beiden anderern Buttons nicht anklickbar sein.
Der zweite Button (ButtonExit) beendet das Programm
Der dritte Button (ButtonReset) würde einige Parameter zurücksetzen.
In der ButtonRender.OnClick - Procedure steht u.a. folgendes:

Code: Alles auswählen

  ButtonExit.Enabled:= false;        // Buttons zu Beginn disable
  ButtonReset.Enabled:= false;
  ..
  (Image zeichnen)
  ..
  ButtonExit.Enabled:= true;       // Buttons am Ende wieder enable
  ButtonReset.Enabled:= true;
Der ButtonExit reagiert darauf, der ButtonReset aber nicht.
Hab dann noch probehalber weitere Buttons in Form1 eingefügt, ohne Erfolg.
Alle nach dem ButtonExit eingefügte Buttons reagieren nicht mehr auf .Enabled:= true|false

Benutzeravatar
Zvoni
Beiträge: 363
Registriert: Fr 5. Jul 2024, 08:26
OS, Lazarus, FPC: Windoof 10 Pro (Laz 2.2.2 FPC 3.2.2)
CPU-Target: 32Bit
Wohnort: BW

Re: Button.Enabled:= true|false;

Beitrag von Zvoni »

hast du mal die Reihenfolge umgedreht?
Also erst den reset auf Enabled=False, dann den Exit?
Gleiches Phänomen?

Und was meinst du mit "eingefügt"?
Die Reihenfolge, in welcher du die Buttons auf der Form platzierst?

Oh, und welches Widget-Set? Welches OS?
Ein System sie alle zu knechten, ein Code sie alle zu finden,
Eine IDE sie ins Dunkel zu treiben, und an das Framework ewig zu binden,
Im Lande Redmond, wo die Windows drohn.

Benutzeravatar
m.fuchs
Lazarusforum e. V.
Beiträge: 2805
Registriert: Fr 22. Sep 2006, 19:32
OS, Lazarus, FPC: Winux (Lazarus 2.0.10, FPC 3.2.0)
CPU-Target: x86, x64, arm
Wohnort: Berlin
Kontaktdaten:

Re: Button.Enabled:= true|false;

Beitrag von m.fuchs »

oliver2104 hat geschrieben: Do 23. Jan 2025, 13:38 Der ButtonExit reagiert darauf, der ButtonReset aber nicht.
Meinst du damit, dass der ButtonExit disabled wird, aber ButtonReset nicht? Dann bitte folgenden Code nutzen:

Code: Alles auswählen

  ButtonExit.Enabled:= false;        // Buttons zu Beginn disable
  ButtonReset.Enabled:= false;
  Application.ProcessMessages;
  ..
  (Image zeichnen)
  ..
  ButtonExit.Enabled:= true;       // Buttons am Ende wieder enable
  ButtonReset.Enabled:= true;
Software, Bibliotheken, Vorträge und mehr: https://www.ypa-software.de

Benutzeravatar
af0815
Lazarusforum e. V.
Beiträge: 6765
Registriert: So 7. Jan 2007, 10:20
OS, Lazarus, FPC: FPC fixes Lazarus fixes per fpcupdeluxe (win,linux,raspi)
CPU-Target: 32Bit (64Bit)
Wohnort: Burgenland
Kontaktdaten:

Re: Button.Enabled:= true|false;

Beitrag von af0815 »

Vielleicht der Hintergrund, warum m.fuchs das Application.ProcessMessages hinzufügt.

Im Hinergrund, gut von Lazarus (und auch Delphi) werkelt ja trotzdem die Messagequece und arbeitet die Befehle ab. Wenn das System jetzt viele Befehle für zB. den Refresh von Komponenten empfängt, kann das System mehrere Befehle zuammenfassen. Deswegen kann es sein, das gewisse Zustandsänderungen gar nicht grafisch gezeichnet werden. Hier wird es die Bearbeitung der Imagebefehle sein, die ganz einfach verhindert, das die UI (UserInterface) mit allen Aktualisiert wird.

Fügtman jetzt ein PcocessMessages ein, so wird das System angewisen, einmal die Messagequece zu verarbeiten/bearbeiten zugleich wird natürlich auch ein Kontexwechsel (beabeitung von anderen Threads) ermöglicht. Manche sagen auch ProcessMessages ist Threading für Arme (sarkastisch gemeint).

Auch sollte man sich überlegen, Image Bearbeitung nicht direkt in einem Action Bereich zu visualisieren. Es gibt Betriebssystem die das verhindern. Sondern man macht die Bearbeitung in einem nicht visuellen Kontext und erst im Paint Ereignis wird der ganze Kontext in die GUI gebracht (meist kopiert). Beschleunigt meistens die ganze Bearbeitung, weil nicht jedesmal die langsamen Grafische Ausgabe aktiviert wird. Benefiz dabei, man kann die Bearbeitung auch im Hintergrund mit Threads machen, was ja sonst verboten ist. Di GUI ist nicht Threadsafe, ausser es ist explizit möglich (Eher nicht so oft gesehen).
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).

oliver2104
Beiträge: 48
Registriert: Sa 26. Dez 2020, 13:22

Re: Button.Enabled:= true|false;

Beitrag von oliver2104 »

Danke für die Antworten!

Mein Widget-Set ist nichts spezielles, was halt so standardmäßig mitinstalliert wird.
Primär verwende ich Win11, kopier aber gern die Sourcen ( *.lpi, *.lpr, *.lps, *.lfm, *.pas) nach Linux und kompilier das auch unter Linux.
Da gibts üblicherweise gar keine Probleme.

Hab jetzt wie von m.fuchs vorgeschlagen die Codezeile

Code: Alles auswählen

Application.ProcessMessages;
eingefügt.
Unter Windows hat das nichts gebracht, dann die Source nach Linux kopiert und dort neu kompliert und siehe da es funktioniert!
Damit meine ich, dass ButtonExit UND ButtonReset disabled werden.
Für Linux wäre das Problem durch diese Codezeile gelöst!
Unter Windows geht's aber nicht, hab da auch die Reihenfolge geändert, ButtonReset bleibt hartnäckig enabled.
Und was meinst du mit "eingefügt"?
Die Reihenfolge, in welcher du die Buttons auf der Form platzierst?
Mit "Einfügen" meinte ich, Button aus der Komponentenpalette auswählen und dann irgendwo ins Formular klicken.
Reihenfolge ist zeitlich gemeint, ButtonRender und ButtonExit waren die allerersten Komponenten im Formular.
Erst später dachte ich mir, ein ButtonReset wär auch hilfreich.
man macht die Bearbeitung in einem nicht visuellen Kontext und erst im Paint Ereignis wird der ganze Kontext in die GUI gebracht (meist kopiert).
Beschleunigt meistens die ganze Bearbeitung, weil nicht jedesmal die langsamen Grafische Ausgabe aktiviert wird.
Das trifft sicher zu! Ich möchte aber gern zusehen wie sich das Image langsam aufbaut. Verwende dafür Image.Update in regelmäßigen Abständen.

Benutzeravatar
fliegermichl
Lazarusforum e. V.
Beiträge: 1639
Registriert: Do 9. Jun 2011, 09:42
OS, Lazarus, FPC: Lazarus Fixes FPC Stable
CPU-Target: 32/64Bit
Wohnort: Echzell

Re: Button.Enabled:= true|false;

Beitrag von fliegermichl »

Kannst du das Projekt mal mit "Publish Project" in ein Zipfile packen und hier hochladen, damit man es nachvollziehen kann?

oliver2104
Beiträge: 48
Registriert: Sa 26. Dez 2020, 13:22

Re: Button.Enabled:= true|false;

Beitrag von oliver2104 »

Hätte das gern gemacht und wollte eine abgespeckte Version schicken.
D.h. mein Programm in ein anderes Verzeichnis klonen und diese Version wegen der Übersicht ein wenig reduzieren,
Bin aber schon daran gescheitert. Die Source Dateien sind ja schnell in ein anderes Verzeichnis kopiert.
Aber dann gibt's Probleme wie z.b. die geklonte Projektdatei (*.lpi ) verwendet nicht die Unit1.pas aus dem eigenen Verzeichnis,
sondern die Unit1.pas aus dem ursprünglichen Verzeichnis. usw..
Bei Projekt speichern unter.. , werden die Units nicht mit gespeichert.
Das hab ich noch nicht ganz durchschaut.
Vermute darin auch das Problem meiner Fragestellung.( Sourcecode in Unit1.pas ändern, aber Projektdatei *.lpi verweist auf eine Unit1.pas aus einem ganz andern Verzeichnis )
Also irgendwas stimmt da bei meiner Vorgehensweise nicht. Muss mir das noch genauer anschauen1
Von Windows nach Linux klonen funktioniert aber überraschend gut, Source Dateien kopieren, *.lpi öffnen und fertig.
Unter Windows ein Projekt von einem Verzeichnis in ein anders Verzeichnis zu kopieren und dann mit der Kopie weiter zu machen scheint nicht so einfach.

Benutzeravatar
Jorg3000
Lazarusforum e. V.
Beiträge: 359
Registriert: So 10. Okt 2021, 10:24
OS, Lazarus, FPC: Win64
Wohnort: NRW

Re: Button.Enabled:= true|false;

Beitrag von Jorg3000 »

Hi!
Weist das Kopierproblem auf irgendeine Verwurschtelung hin? :D

Gehört der störrische Button gar nicht auf das Form? Hast du was am .Parent rumgefummelt? Oder ist er Child eines anderen Control?
Sind es unterschiedliche Button-Typen?

Hast du den Button schon mal entfernt und nochmal neu angelegt?

Benutzeravatar
af0815
Lazarusforum e. V.
Beiträge: 6765
Registriert: So 7. Jan 2007, 10:20
OS, Lazarus, FPC: FPC fixes Lazarus fixes per fpcupdeluxe (win,linux,raspi)
CPU-Target: 32Bit (64Bit)
Wohnort: Burgenland
Kontaktdaten:

Re: Button.Enabled:= true|false;

Beitrag von af0815 »

oliver2104 hat geschrieben: So 26. Jan 2025, 15:26 Hätte das gern gemacht und wollte eine abgespeckte Version schicken.
D.h. mein Programm in ein anderes Verzeichnis klonen und diese Version wegen der Übersicht ein wenig reduzieren,
Bin aber schon daran gescheitert. Die Source Dateien sind ja schnell in ein anderes Verzeichnis kopiert.
Normalerweise sind die Pfade zu den Units relativ angelegt. Daher wenn man dort nichts herumpfuscht, kann man ein Projekt komplett relativ einfach kopieren. Nur die Struktur MUSS man einhalten.

Für so Tests, kann man auch die Funktion Publish aus "Project->Publish Project" verwenden, da wird auch alles was man so zum Projekt mit verwendet hat, mitkopiert. Das kann man auch sehr sicher verwenden. Und dann speckt man dieses Projekt ab. Hinweis - unter dem Sourcefenster sieht man, welch Datei man gerade bearbeitet, das sollte man kontrollieren, damit man sich nicht das falsche zerschiesst.
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).

wp_xyz
Beiträge: 5130
Registriert: Fr 8. Apr 2011, 09:01

Re: Button.Enabled:= true|false;

Beitrag von wp_xyz »

Zum Kopieren eines Projekts, wenn man nicht "Publish Project" verwendet, immer die IDE verlassen und die Dateien im Betriebssystem kopieren, nie in der IDE unter häppchenweisem Speichern im anderen Ordner. Denn wenn die IDE eine Datei anderswohin speichert, werden die Pfade neu gesetzt, und das endet im heillosen Chaos.

oliver2104
Beiträge: 48
Registriert: Sa 26. Dez 2020, 13:22

Re: Button.Enabled:= true|false;

Beitrag von oliver2104 »

Hallo,
habs jetzt geschafft und lade test.zip hoch. (für Windows )
Das tut nicht viel, färbt nur ein Image Pixel für Pixel, nach Klick auf Render rot ein.
Wieso wird der Reset Button nicht, so wie der Exit Button während des Renderns, disabled.

Würd mich aber auch nicht wundern wenn's bei euch schon geht.
Hab wie gesagt alles auf ein anderes System ( meine Linux Partition) kopiert und da gibt es kein Problem!
test.zip
(3.45 KiB) 34-mal heruntergeladen

Benutzeravatar
Zvoni
Beiträge: 363
Registriert: Fr 5. Jul 2024, 08:26
OS, Lazarus, FPC: Windoof 10 Pro (Laz 2.2.2 FPC 3.2.2)
CPU-Target: 32Bit
Wohnort: BW

Re: Button.Enabled:= true|false;

Beitrag von Zvoni »

Also, ich hab mal das problem von OP in einem test nachgestellt.
Eine Form, 3 Buttons, ein Label

Folgender code in Button1Click:

Code: Alles auswählen

procedure TForm1.Button1Click(Sender: TObject);
Var i:Integer;
begin
  Button2.enabled:=False;
  Button3.Enabled:=False;
  For i:=0 To 10000000 Do  //Um den Rechner mal wirklich zur Arbeit zu zwingen
    Begin
      Label1.Caption:='Iteration '+i.ToString;      
    end;
  Button2.Enabled:=True;
  Button3.Enabled:=True;
end;
Das Phänomen ist erkennbar, dass die Form als auch die Buttons nicht neu gezeichnet werden (Erkennbar, dass das Label nicht auf die Zuweisung reagiert)
Button2 und Button3 sind dennoch auf Enabled=False --> Null Reaktion.
Das heisst: Das Enabled wird ausgeführt, der User sieht es aber nicht.
Das oben erwähnte "Application.ProcessMessages" gehört in die Schleife, dann wird das "Enabled:=False" auch sichtbar, aber das ist teuer!

Ich dachte, nach den zwei "Enabled:=False" ein Form1.Refresh oder Form1.Repaint würde helfen.
Das einzige was geholfen hat, war Application.ProcessMessages in die Schleife zu packen, aber das ist ja mal desaströs.

EDIT: Auf Windows bei mir....
Zuletzt geändert von Zvoni am Mo 27. Jan 2025, 15:28, insgesamt 1-mal geändert.
Ein System sie alle zu knechten, ein Code sie alle zu finden,
Eine IDE sie ins Dunkel zu treiben, und an das Framework ewig zu binden,
Im Lande Redmond, wo die Windows drohn.

Benutzeravatar
Niesi
Lazarusforum e. V.
Beiträge: 581
Registriert: So 26. Jun 2016, 19:44
OS, Lazarus, FPC: Linux Mint Cinnamon, Laz 3.9 Fpc 3.2.3 und allerlei mit FpcUpDeLuxe
Kontaktdaten:

Re: Button.Enabled:= true|false;

Beitrag von Niesi »

oliver2104 hat geschrieben: Mo 27. Jan 2025, 14:11
...

Würd mich aber auch nicht wundern wenn's bei euch schon geht.
Hab wie gesagt alles auf ein anderes System ( meine Linux Partition) kopiert und da gibt es kein Problem!test.zip
Macht was es soll: Alle Knöpfe sind während des in Rot Färbens disabled ...
Auswahl_043.png
(48.66 KiB) Noch nie heruntergeladen
Auswahl_044.png
(56.95 KiB) Noch nie heruntergeladen
Auswahl_045.png
(53.67 KiB) Noch nie heruntergeladen
Wissen ist das einzige Gut, das sich vermehrt, wenn es geteilt wird ...

Benutzeravatar
Zvoni
Beiträge: 363
Registriert: Fr 5. Jul 2024, 08:26
OS, Lazarus, FPC: Windoof 10 Pro (Laz 2.2.2 FPC 3.2.2)
CPU-Target: 32Bit
Wohnort: BW

Re: Button.Enabled:= true|false;

Beitrag von Zvoni »

Niesi hat geschrieben: Mo 27. Jan 2025, 14:53
oliver2104 hat geschrieben: Mo 27. Jan 2025, 14:11
...

Würd mich aber auch nicht wundern wenn's bei euch schon geht.
Hab wie gesagt alles auf ein anderes System ( meine Linux Partition) kopiert und da gibt es kein Problem!test.zip
Macht was es soll: Alle Knöpfe sind während des in Rot Färbens disabled ...

Auswahl_043.png


Auswahl_044.png


Auswahl_045.png
Errr.... er hat das Problem auf Windows, nicht auf linux?
Ein System sie alle zu knechten, ein Code sie alle zu finden,
Eine IDE sie ins Dunkel zu treiben, und an das Framework ewig zu binden,
Im Lande Redmond, wo die Windows drohn.

Benutzeravatar
af0815
Lazarusforum e. V.
Beiträge: 6765
Registriert: So 7. Jan 2007, 10:20
OS, Lazarus, FPC: FPC fixes Lazarus fixes per fpcupdeluxe (win,linux,raspi)
CPU-Target: 32Bit (64Bit)
Wohnort: Burgenland
Kontaktdaten:

Re: Button.Enabled:= true|false;

Beitrag von af0815 »

Nochmals, es ist wie Messagequeuce abgearbeitet wird. Das kann sogar bei Windows Versionen unterschiedlich sein.

https://learn.microsoft.com/de-de/windo ... age-queues dort im Kapitel Nachrichten in der Warteschlange
Zitat: Die WM_PAINT Nachricht, die WM_TIMER Nachricht und die WM_QUIT Nachricht werden jedoch in der Warteschlange beibehalten und nur dann an die Fensterprozedur weitergeleitet, wenn die Warteschlange keine anderen Nachrichten enthält. Darüber hinaus werden mehrere WM_PAINT Nachrichten für dasselbe Fenster in einer einzelnen WM_PAINT Nachricht kombiniert, wodurch alle ungültigen Teile des Clientbereichs in einem einzelnen Bereich konsolidiert werden. Durch das Kombinieren WM_PAINT Nachrichten wird die Anzahl der Wiederholungen reduziert, mit denen ein Fenster den Inhalt des Clientbereichs neu zeichnen muss.
Daher kann das Windows System mehre Anforderungen zum Zeichnen des Fensters zusammenfassen. Daher wird hier das System die Routine abgearbeitet haben, bevor die nächste Nachricht zum Neuzeichnen aktiv wird. Mit dem Application ProzessMessages wird ein Kontextwechsel (Thread/Programm ) erzwungen und auch die Messageqeuce des Programm erzwungener Massen abgearbeitet. Deswgen greift dann wieder ein Neuzeichnen und der Status des Buttons wird sichtbar. Klar kostet das Performance. Aber hier setzt man es ja bewusst ein.

Ach ja, andere Fenstermanager (zB. unter Linux) können das Verhalten anders haben.
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).

Antworten