Themabewertung:
  • 0 Bewertung(en) - 0 im Durchschnitt
  • 1
  • 2
  • 3
  • 4
  • 5
gui refresh kommt zu spaet
#1
Hi, ich bin's wieder.
Ich hatte gerade eine Baustelle fertig und dachte ich bau schnell mit 'ntui_label' eine Statuszeile ein.
Das funktioniert auch soweit, nur wird im folgenden Code das Label erst NACH dem Aufruf in der letzten Zeile aktualisiert. Da scan{} 4-5 Sekunden braucht ist das schon ein wenig ärgerlich.
[ab3]Select ntui_GetNotifyID{*Notify}
Case "ev_ic_scan"
ntui_SetStringByID{*label,"icStatus","Scanning..."}
ntui_ClearListView{*InfoList}
scan{path.s}[/ab3]
Ein 'ntui_Refresh{*label,Null}' hilft da leider auch nicht.
EDIT:ntui_ClearListView wird auch erst danach ausgeführt, das war mir vorher nicht aufgefallen.
Zitieren
#2
Das ist logisch, da Ntui erst nach einem weiteren Durchlauf deiner Selectschleife refresht...

Das ntui_Refesh da nicht hilft ist auch logisch, da du das im selben Case aufrufst.

Wenn du vor deinem Aufruf zB. ein

Code:
Case "SetLabel"
ntui_SetStringByID{*label,"icStatus","Scanning..."}
ntui_PostNotify{*engine,"ev_ic_scan"}

machst, dann wird das Statuslabel zuerst gezeichnet und dann erst zum nächsten Case verzweigt...
Zitieren
#3
Hab ich das vielleicht falsch verstanden? Wenn die GUI das notify sended kann ich ja auch keine 2 case's auslösen.
Darf ich den 'SetLabel' case überhaupt in der getNotify schleife auslösen? Ich wüßte im Moment nicht von wo aus ich das sonst machen sollte. Denn jenachdem wie ich es mache gibt es einen Guru oder er zeichnet erst hinterher.

Kann ich das neuzeichnen des Labels nicht erzwingen?
Zitieren
#4
Ein Notify einlesen, dann ein Case abarbeiten.

Deshalb mein Vorschlag das mit einem PostEventxxx zu lösen...

Dann wird eben erst dein Label refrehst und dann deine lang andauernde Case bearbeitet...
Zitieren
#5
Mit postevent bekomme ich einen Guru, frag mich nicht warum. Ich denke aber der Fehler sitz vor dem Bildschirm. :oops:
Ich hab es jetzt erstmal so hinbekommen:
[ab3]Case "ev_ic_scan"
ntui_SetStringByID{*label,"icStatus","Scanning..."}
ttemp.l=1
End Select
Until *Notify = Null
If ttemp.l = 1
ttemp.l=0
scan{path.s}
End If
Wend[/ab3]
Ist allerdings nicht die eleganteste Lösung. Wenn ich das für mehrere dinge brauche würde ich eine zweite select/case schleife nutzen. Das scheint mir aber umständlich zu sein.

Nachtrag: Was macht postEvent? löst der den event aus, so das der entsprechende case abgearbeitet wird? Ich werd aus dem nicht so ganz schlau, hab auch keine Kommentare im sourcecode/docs gefunden. aber_die ntui_createEvent zeile klingt mir danach.
Zitieren
#6
Jedes moderne Toolkit wartet mit dem Neuzeichnen bis du im Event Loop fertig bist (wenn es überhaupt einen gibt, meistens sind die Callback basierend), weil das sehr viel effizienter ist und die Programmierung für dich erleichtert, da du dich nicht um den Refresh selbst kümmern musst. Grundsätzlich gilt daher: "Never block the main thread ™!".

Die richtige Vorgehensweise wäre, eine längere Aktion wie z.B. das Scannen eines Verzeichnisses als Background Thread zu starten, und bei Beendigung wieder ein Notify zu posten. So macht das AIDE z.B. für das scannen des AB3 sources. Sonst könnte man währendessen ja nicht editieren und die GUI wäre eingefrohren.

Leider unterstützt AB3 aber kein Multithreading, sodass man das etwas aufwendig hacken muss. Wenn du einen Refresh erzwingen willst, dann kannst du das so tun:

[ab3]ntui_SendEvent{*obj, #TUIEV_REFRESH}[/ab3]

... ist aber kein guter Stil. Du solltest dann auf jeden Fall den MousePointer busy setzen, um dem User zu signalisieren dass der Main Thread geblockt ist und du keine weiteren Events erhältst.

ntui_SendEvent dispatched ein Event blockierend.
ntui_PostEvent schickt ein Event ab ohne zu blockieren, das Event wird dann erst gedispatched wenn der Focus wieder an NTUI zurückgegeben wird per ntui_GetEvent() oder nuti_WaitEvent().
Doku und Beispiele werden langsam notwendig, wenn ihr das ernsthalf benutzen wollt.
Zitieren
#7
@tero

Ja das ist schlecht wenn du in einen Selectblock noch einen weiteren einfügst, da hat der Wanderer Recht...

Nochmal der Ablauf:

1 waitevent
2 Notify
3 select
4 case "Irgendwas"
5 case "ev_ic_scan"
6 end select
zurück zu waitevent

Wenn du nun dein Labelsetzen in Punkt 4 machst (mußt du dann halt neu benennen und nicht ev_ic_scan),
und dort anschließend ein ntui_PostNotifyWithEvent_dep{*engine,"ev_ic_scan",-1,""} (PostEvent crasht bei mir auch manchmal oder auch PostNotify deswegen nehme ich das)
dann wird nach diesem Case zurückgesprungen auf waitevent und dann der nächste Notify geholt (was dann dein eingegebenes ev_ic_scan bedeutet)
Zwischenzeitlich ist dann auch dein Label refresht worden und dann wird nun dein länger dauernder Scan ausgeführt...

Set_Event würde ich nicht nutzen.

ich hoffe ich konnte das einigermassen verständlich rüberbringen.......
Zitieren
#8
Ich Danke euch beiden.
Ich probiere mal in einem testsource mit ntui_send/postEvent herum, in meinem Programm läuft es ja erstmal. Da bin ich Gestern auch schon an andere Sachen dran gegangen.

Blackbird schrieb:1 waitevent
2 Notify
3 select
4 case "Irgendwas"
5 case "ev_ic_scan"
6 end select
zurück zu waitevent
So war mein erster Versuch mit ntui_PostEvent, nur eben mit dem Guru. Dann hatte ich das ja doch nicht falsch verstanden. Aber nachdem es nicht funktionierte war ich mir nicht mehr sicher.
EDIT: mit ntui_PostNotifyWithEvent funktioniert es einwandfrei.

@Wanderer
Der Kommentarblock, der bei den Funktionen im Source steht, würde meistens reichen. Die kurze Beschreibung und die Syntax haben mich, in der Regel, bisher weitergebracht. Den gibt es nur leider nicht überall, und man muß bereits wissen was man sucht. Wenn Du vorhast etwas Doku zu schreiben: bei NTUI wäre es Hilfreich wenn es eine Doku gäbe wo zumindest die vorhanden Gadgets/befehle kurz erklärt werden. Das braucht kein komplettes Tutorial sein, nur das man weiß was es gibt und was es macht.
Zitieren
#9
Immer im Hinterkopf behalten, Ntui ist noch nicht fertig....

Unter welchem OS programmierst du denn überhaupt ?
Zitieren
#10
Zitat:So war mein erster Versuch mit ntui_PostEvent, nur eben mit dem Guru.

Unter MorphOS habe ich da nachgeforscht, das kracht weil der Befehl scheinbar das select end selekt konstrukt knackt...

will heisen das es nach dem Case in dem es aufgerufen wurde einfach zum nächsten springt und dann die meldung (im Debugger) kommt das kein Sellect End Select war
Zitieren


Gehe zu:


Benutzer, die gerade dieses Thema anschauen: 3 Gast/Gäste