In my program to greate a database, i have write a lot of methodes with a boolse return.
Under teh eventhandler “Action” of a button, is the folowing code.
If MakeDataBase Then LogList.AddRow "DataBase OK"
If MakeNameList Then LogList.AddRow "Namelist OK"
If MakeCompagnylist Then LogList.AddRow "Compagnylist OK"
And so on…
After every methode ther should be a mesage into the Loglist, but the loglist is empty until the process, after all the methodes are fixed, the loglist is filled.
What shall i do to have a step by step loglist?
Refresh the Listbox one line at a time ?
http://documentation.xojo.com/index.php/RectControl.RefreshRect
An this will slowdown the running stuff.
Edit: or put the code in a thread.
A thread will make a ThreadAccessingUIException. You will need to do the usual timer method - timer or no timer. Do you know what I mean?
Hello,
in addition to what Beatrix wrote: In an app that uses a thread I do the following: The log-messages are appended to an array (let’s call it MessageArray). A timer checks once every second if MessageArray.Ubund > -1
. If the MessageArray is not empty, then every message from the array is appended to the listbox and the MessageArray is emptied again (Redim MessegeArray(-1)
)
Better pull the 0 item and then remove it from the array. With a ReDim in such a timer you could destroy objects which have been added between the EndIf and the ReDim.
Hello Beatrix W, i don’t no what you mean.
Do you have a Example?
Add a Property to where it fit’s in scope. A Property like “strLogEntry” as string.
In a Thread you can add new Log Entries like If MakeDataBase Then strLogEntry.Append “DataBase OK”.
In your Timer you check if the upper bound of your strLogEntry Array is > -1.
If the upper bound is > -1 then pull the 1st object of the strLogEntry and add it to the ListBox. Right afterwards, you remove the 1st entrie from strLogEntry (strLogEntry.Remove(0)).
BTW: I can’t offer Code. Not at my Desk…
Check out the examples included with Xojo:
…/Example Projects/Desktop/UpdatingUIFromThread
Thanks, that is a very good suggestion! Now I did it this way:
[code]dim theUbound as Integer
dim i as Integer
theUbound = MessageArray.Ubound
// check if there are new entries in the array
if theUbound = -1 then
// nothing to do, exit the method
Return
end if
// add the new entries from the array to the listbox
for i = 0 to theUbound
Listbox_LogList.Addrow(MessageArray(i))
next
// remove the already listed entries from the array
for i = theUbound DownTo 0
MessageArray.Remove(i)
next[/code]
[quote=368677:@Hans Riemers]Hello Beatrix W, i don’t no what you mean.
Do you have a Example?[/quote]
You can create an array MessageArray(-1)
of type String. Now you can for example write:
MessageArray.Append("DataBase OK")
or MessageArray.Append("Namelist OK")
.
You also need to add Timer to your LogList-Window. In the Action-event of the Timer you can enter the code I posted above to display the messages in a listbox.
Just be aware that, if there are too many items in the array, pulling them all within 1 timer cycle can lead to a freezing ui.
I recommend to pull just 1 for each timer cycle until the jobs which fill the array are done.
Remember: Timers run in the Main Thread
Hello Sascha, thanks for the suggestion. Currently my log list displays 5 to 30 entries every couple of minutes (most of the time the messages come from a thread), so the UI will never freeze in that app because of the logging I currently set the timer to fire only once per second because I also update some UI elements with that timer in my log-window (and I do not want to update the UI too often), so I think I will leave it that way.
But I see that the method you describe (see below) is far better suited for more demanding log-systems (wich have to deal with way more entries than my example) when used with a timer with a short period.
[code]// check if there are entries in the array
if MessageArray.Ubound = -1 then
// nothing to do, exit the method
Return
end if
// add the first entry from the array to the listbox
Listbox_LogList.Addrow(MessageArray(0))
// remove the already listed first array object from the array
MessageArray.Remove(0)[/code]
Why not start the Timer only when things change? You can start a Timer from a Thread without raising a ThreadAccessingUIException. That would reduce the CPU fingerprint even more.