Zum Inhalt springen

Schleifenkonstrukte und Ausgaben...


DanielH

Empfohlene Beiträge

Hallo zusammen.

Sitze im Moment an einem Programm in PHP-GTK (programmiersprache ist aber eigentlich egal), welches aus einer textdatei ausgelesene SQL-Anweisungen unbestimmter Anzahl abarbeitet. Nach jeder abgearbeiteten Anweisung soll ein Progressbar erhöht werden.

Sinnvollerweise war meine Lösung, die anzahl der Anweisungen zu ermitteln und in einer for bzw. while-schleife abzuarbeiten.

Nun zum Problem, die Berechnung der Position des Progressbars, läuft vollkommen korrekt die ganze Zeit mit, aber ausgegeben wird immer erst dann etwas, wenn die Schleife komplett durchgelaufen ist. Egal ob in der Standardausgabe oder eben im Fenster.

Was könnte man da anders machen, das Ausgaben nach jedem Schleifendurchlauf gemacht werden ?

Hab das auch in C probiert, mit einer Schleife durch ein Array zu rennen und die Werte auszugeben, auch hier wird tatsächlich erst ausgegeben, wenn die Schleife abgearbeitet ist, vorher ist die Anwendung wie "gesperrt".

Danke schonmal im vorraus.

MfG

Link zu diesem Kommentar
Auf anderen Seiten teilen

Objektorientiert würde das wahrscheinlich kein Problem sein. Wenn der Progress-bar ein wie auch immer geartetes Objekt ist, kannst du es innerhalb der verschiedenen for-Schliefen-Durchläufen immer wieder auf den aktuellen Stand setzen. Vielleicht die richtige Richtung?

PHP-GTK hört sich gut an, muss ich mich mal drüber einlesen - kenn ich nicht.

[Edit:] Nach ein paar Seiten Doku, vielleicht kann dir das helfen: http://gtk.php.net/manual/de/gtk.gtkprogressbar.php ? Ist aber kein Algorithmus, sorry wg. OT. :)

Link zu diesem Kommentar
Auf anderen Seiten teilen

Ich dachte mir das so:

Vorstufe - Zählen der SQL-Anweisungen in der Textdatei. Im einfachsten Fall ein SQL-Statement pro Textzeile, dann muss man nur die Zeilen zählen. Dann hat man die Gesamtzahl der Schritte.

Initialisierung des Progress-Bar: Maximale Schrittweite auf die Gesamtzahl der Schritte einstellen.

Die Schleife: Bei jedem Durchlauf der Schleife setzt man den Progress-Bar-Zähler einen höher, damit der fortläuft. Also meinetwegen etwas wie

$progressbar->set_percentage($schleifenNr/$gesamtzahl);

Link zu diesem Kommentar
Auf anderen Seiten teilen

Genauso hab ich den Algorhythmus. GTK progge ich schon ne ganze Weile... ;)

Aber hier mal der Auszug: (ohne SQL)



$step = 1.0 / count($SQL->queries);


foreach($SQL->queries as $var) {


  if($value <= 1.0) {

    $value += $step;

  }


  $progressbar->set_percentage($value);



}


Das $SQL->queries ist ein array als rückgabewert aus einer SQL-Parserklasse, die Textdateien eben auseinander nimmt, kommentare raushaut usw. und die einzelnen Abfragen abarbeitet. Baut man nun z.B. dort nach dem der letzen Anweisung ein sleep(1) (eine Sekunde Pause), und es sind z.B. 4 Anweisungen im Array passiert 4 Sekunden lang garnichts, die Änderung des Progressbars wird erst übernommen wenn die Schleife abgearbeitet ist, das heisst er bleibt bei null stehen, die SQl-Befehle laufen durch, und er zeigt 100 % an. Die zwischenergebnisse der Anzeige stimmen aber, weil die korrekt (auch erst im Anschluss) ausgegeben werden, und ohne die Schleife läuft er auch korrekt.

MfG

Link zu diesem Kommentar
Auf anderen Seiten teilen

Vielleicht liegt es daran, dass GTK eventgesteuert ist. Wenn dein Code in einem Event-Handler steht, dann kann solange kein weiteres Event verarbeitet werden, solange die Schleife läuft. Deine Aufrufe von set_percentage lösen wahrscheinlich Events zum Neuzeichnen der Progress Bar aus, aber die können erst abgearbeitet werden, wenn "dein" Event behandelt wurde.

Wie die Abhilfe aussieht, hängt von der Sprache ab. Ein sleep wird nicht helfen, weil die anderen Events nicht in einem anderen Thread behandelt werden. Der Thread wartet sozusagen auf sich selbst. Aber es gibt in mehreren Sprachen Möglichkeiten, zwischenzeitlich aufgelaufene Events abzuarbeiten, so z.B. PeekMessage/DispatchMessage oder DoEvents. Vielleicht gibt es so etwas auch in GTK.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Danke für den Hinweis, werde gleich mal danach suchen.

Das sleep war nur zum "debuggen" was überhaupt passiert, und in Verbindung mit erfolgreichen auslösen des Events hätte ja eigentlich 1 Sekunde lang der Status des Progressbars anhgezeigt werden müssen. :confused:

MfG

Link zu diesem Kommentar
Auf anderen Seiten teilen

Originally posted by DanielH

Genauso hab ich den Algorhythmus. GTK progge ich schon ne ganze Weile... ;)

Aber hier mal der Auszug: (ohne SQL)




$step = 1.0 / count($SQL->queries);


foreach($SQL->queries as $var) {


  if($value <= 1.0) {

    $value += $step;

  }


  $progressbar->set_percentage($value);



}


Hmm ich kenne jetzt nicht genau die Funktion einer GTK-Progressbar, wann zeigt die denn 100% an , bei $value = 100 oder bei $value = 1.0 ??

step = (100 / Zeilenzahl), gibt ja die Erhoehung von Value pro Durchlauf an,

kann es sein das du der Progressbar ein Redraw - Event schicken musst damit sie weiss das sie sich mit dem neuen Wert neu Zeichnen soll ?

Frank

Link zu diesem Kommentar
Auf anderen Seiten teilen

Originally posted by SgtBadAzz

Hmm ich kenne jetzt nicht genau die Funktion einer GTK-Progressbar, wann zeigt die denn 100% an , bei $value = 100 oder bei $value = 1.0 ??

step = (100 / Zeilenzahl), gibt ja die Erhoehung von Value pro Durchlauf an,

kann es sein das du der Progressbar ein Redraw - Event schicken musst damit sie weiss das sie sich mit dem neuen Wert neu Zeichnen soll ?

Frank

Also 1.0 / Zeilenzahl ergibt ergibt den Prozentwert, der durch

set_percentage(Prozent) gesetzt wird. Dabei wird einfach der neue Wert an den Bar geschickt und GTK kümmert sich dann um die Berechnung der neuen Position, und je nach Geschmack um die Anzeige der Zahl 1.0 / Zeilenzahl * 100.

Das funktioniert eigentlich auch ganz super, solange eben keine for, foreach und while schleifen verwendet werden.

@mods

falls das jetzt hier zu programmiersprachenspezifisch wird, in welches Forum können denn in Zukunft GTK-Fragen gepostet werden ?

MfG :)

Link zu diesem Kommentar
Auf anderen Seiten teilen

Originally posted by DanielH

Also 1.0 / Zeilenzahl ergibt ergibt den Prozentwert, der durch

set_percentage(Prozent) gesetzt wird. Dabei wird einfach der neue Wert an den Bar geschickt und GTK kümmert sich dann um die Berechnung der neuen Position, und je nach Geschmack um die Anzeige der Zahl 1.0 / Zeilenzahl * 100.

Das funktioniert eigentlich auch ganz super, solange eben keine for, foreach und while schleifen verwendet werden.

MfG :)

Hallo,

1.0 / Zeilenzahl ergibt die Differenz um die der aktuelle Wert der Progressbar pro durchlauf erhoeht wird, dieser wird (laut deinem Quelltext) pro Durchlauf zu $value auf addiert und dann wird der neue Wert der Progressbar mit set_percentage($value) gesetzt. Wenn du mittels einer Konsolenausgabe verifizieren kannst, das sich der Wert von $value pro Durchlauf der Schleife kontiuierlich um den Wert von 1.0/Zeilenzahl erhoeht und sich die Progressbar-Anzeige trotzdem nicht aendert dann liegt es (so denke ich) bestimmt daran das du vergisst sowas wie ein Redraw nach dem Setzen jeden neuen Wertes zu erzwingen.

Frank

Link zu diesem Kommentar
Auf anderen Seiten teilen

Originally posted by DanielH

@mods

falls das jetzt hier zu programmiersprachenspezifisch wird, in welches Forum können denn in Zukunft GTK-Fragen gepostet werden ?

Da es sich ja im Grunde um PHP handelt, könntest du die Fragen im Forum Skript- und Webserverprogrammierung stellen. Wenn du es allerdings nicht im Webserver-Umfeld einsetzt (das lässt die ProgressBar vermuten), könnte Delphi/VB/VBS/AS 400/C#/.net/Sonstige besser passen.
Link zu diesem Kommentar
Auf anderen Seiten teilen

Originally posted by SgtBadAzz

Hallo,

1.0 / Zeilenzahl ergibt die Differenz um die der aktuelle Wert der Progressbar pro durchlauf erhoeht wird, dieser wird (laut deinem Quelltext) pro Durchlauf zu $value auf addiert und dann wird der neue Wert der Progressbar mit set_percentage($value) gesetzt. Wenn du mittels einer Konsolenausgabe verifizieren kannst, das sich der Wert von $value pro Durchlauf der Schleife kontiuierlich um den Wert von 1.0/Zeilenzahl erhoeht und sich die Progressbar-Anzeige trotzdem nicht aendert dann liegt es (so denke ich) bestimmt daran das du vergisst sowas wie ein Redraw nach dem Setzen jeden neuen Wertes zu erzwingen.

Frank

Die Werte werden alle vollkommen korrekt berechnet, und das set_percentage löst auch das update des Fensters aus.

Hab das jetzt von hinten mit der Faust aufs Auge über interne GTK-Callbacks mit Hilfe eines Timeouts in den Griff bekommen, schön ist das aber auch nicht.

@Klotzkopp

Leider gibt es keine Anweisungen, die das ausführen der ausgelösten Events erzwingen. Wenn ich das selber schreiben würde, wie müsste das aussehen ?

Würde ggf. die C-Quellen vom GTK-Interpreter erweitern... :(

MfG

Link zu diesem Kommentar
Auf anderen Seiten teilen

Originally posted by DanielH

Die Werte werden alle vollkommen korrekt berechnet, und das set_percentage löst auch das update des Fensters aus.

Hab das jetzt von hinten mit der Faust aufs Auge über interne GTK-Callbacks mit Hilfe eines Timeouts in den Griff bekommen, schön ist das aber auch nicht.

@Klotzkopp

Leider gibt es keine Anweisungen, die das ausführen der ausgelösten Events erzwingen. Wenn ich das selber schreiben würde, wie müsste das aussehen ?

Würde ggf. die C-Quellen vom GTK-Interpreter erweitern... :(

MfG

Das kann ja sein, dass set_Percentage ein Update ausloest, die Frage ist ob es auch

korrekt abgearbeitet wird ?? Oder ueberhaupt zur Abarbeitung kommt.

Ich meine da was Klotzkopp geschrieben hat , mit deinem Code in einem Event-Handler usw...

Mit dem Timeout finde ich das nicht gut, das ding wird ja immer langsamer je mehr

Zeilen du verarbeitest.

Frank

Link zu diesem Kommentar
Auf anderen Seiten teilen

Das Timeout ist auf Null gestellt, von daher wird es nicht langsamer, aber der Event wird wenigstens ausgelöst.

hab in der GTK-Doku leider nix gefunden, das diesen Effekt beschreibt:

1. Das Fenster wird erzeugt

2. Alle Texte, Buttons usw. werden reingepackt

3. Das Fenster wird bei Aufruf LEER angezeigt

4. Der Nachstehende Code wird abgearbeitet

5. Der Inhalt des Fensters wird angezeigt

So passiert es, wenn ich den oben beschriebenen Code nutze. Keine Ahnung wie das anderweitig zu umgehen wäre.

MfG

Link zu diesem Kommentar
Auf anderen Seiten teilen

Dein Kommentar

Du kannst jetzt schreiben und Dich später registrieren. Wenn Du ein Konto hast, melde Dich jetzt an, um unter Deinem Benutzernamen zu schreiben.

Gast
Auf dieses Thema antworten...

×   Du hast formatierten Text eingefügt.   Formatierung wiederherstellen

  Nur 75 Emojis sind erlaubt.

×   Dein Link wurde automatisch eingebettet.   Einbetten rückgängig machen und als Link darstellen

×   Dein vorheriger Inhalt wurde wiederhergestellt.   Editor leeren

×   Du kannst Bilder nicht direkt einfügen. Lade Bilder hoch oder lade sie von einer URL.

Fachinformatiker.de, 2024 by SE Internet Services

fidelogo_small.png

Schicke uns eine Nachricht!

Fachinformatiker.de ist die größte IT-Community
rund um Ausbildung, Job, Weiterbildung für IT-Fachkräfte.

Fachinformatiker.de App

Download on the App Store
Get it on Google Play

Kontakt

Hier werben?
Oder sende eine E-Mail an

Social media u. feeds

Jobboard für Fachinformatiker und IT-Fachkräfte

×
×
  • Neu erstellen...