Updating labels in Windows

I have a Windows desktop app and I have a control called lblNotice. I am updating the control using lblNotice.text but it is not changing the label on the screen. It appears that labels dont get updated until the current event finishes. Is this correct? I have even tried creating a timer and storing the label values in a property and then the timer reads the property and updates the label but this also does not seem to update the label content.

Also where do you actually put your code in a Xojo desktop app that you want to run at startup. I am guessing in the Open event but this appears to run before the page is displayed and I cannot see an event that fires once the page has been displayed like Show or something similar.

Not having Xojo open in front of me but from memory:

Try lblNotice.Invalidate or lblNotice.Refresh

Try Window1.Activate event.

Have you tried the Resized event?

Something is wrong with your code somewhere. Changing the text changes instantly the display. Try this in the action of a timer :

Label1.Text = str(Microseconds)

You will see it updating at each timer tick.

Startup code in the main window Open event should work fine.

Actually, Nathan is correct. The text does not get updated until either the method terminates or the control gets a Refresh. To test this I created a label, and a button on a window. The initial text of the label I left as ‘Untitled’. The following code is in the Action event of the button.

Dim i As Integer label1.Text = "bbbbbbb" // Label1.Refresh for i = 0 to 1000000 // Really do nothing here next i Label1.Text = "Done"
I then set a breakpoint on the last line to see if the text had changed. When the debugger hit, the text on the label itself hadn’t changed but the Label1.text property had changed. Uncommenting the Refresh line had the text on the label changeing immediately.

Michael, the reason it works from the timer is probably due to the window getting refreshed each time the timer terminates and restarts its cycle.

Wow their is a first :wink: I have tried it both in the Open event and in the timer event and the text just doesnt update until after the open event finishes. The Open event by definition occurs before the window is shown so it is doing what I would expect in that it is only showing me the label updated when the Open event has finished. Which is why I was asking if a Show event exists as you had in VB. I cant really use Activate or Resize because if the window changes and then comes active again or resizes then the code will all get run again which would be a mess.

Then the conclusion is simple : if you want labels to update immediately, change their text from a timer. It is easy to put that into a method, and it saves the necessity to refresh the control…

Yes you can use activate for code that executes on launch only once :

Static dejarun as boolean
if dejarun = true then return
dejarun = true 
//Do whatever you need to do upon launch

Michel, this is nuts that you have to use a timer to update a label, whats more is that the implication is that Xojo does not update the UI until the current event has completed, that is really messy so you end up having to have lots of timers to update the UI if you have different things changing subject to difficult things happening in the event.

Just for the record I have found that if you create a method that updates the label then call that method with the text you want to be updated then the UI gets updated during the event.

Whatever works works. You looked for solutions. I was not the one with a label refresh issue. I never needed special methods for that. Do as you please, lad. Ideas are just that. Then you experiment and find what’s right for you.

Sorry Michel I did not mean any bad feeling, I just find Xojo a bit weird sometimes and updating a label seems such a simple thing to do to keep users aware of what the app is doing. I have never known a language where you have to call a method or create a timer or something else to update a label which is why I thought it was odd. Thanks as always for yours and everyone elses help it really is appreciated and keeps me from going mad :wink:

Nathan, I was not aware of the label lack of update while in an event before. I thought it was a problem with Windows but it occurs on Mac as well. I placed a series of loops to take time in a button event and indeed, there is no update while the event is not complete. I also noted that I cannot close the window or quit the application during that time. Pending more experiment, I suspect while an event execute, other processes are frozen… And that goes for a timer as well, as I tested it.

The best solution I found is to subclass a label and add to the class ‘Lab’ the following method :

Sub mytext(text as string) me.text = text me.refresh End Sub

Now instead of modifying the text directly, I go Lab1.mytext("new label text")

Truth is, I have not noticed the problem in all these years because I never had such a long process happening in any event. Now in VB that would probably call for doevents or an async. In Xojo, it calls for a refresh. Now we know.

Much neater solution that mine, all I did was create method called UpdateLabel with a string parameter, then call that method each time I want to update the label and that works as well. In VB6 (I have just tried it) your would have to do a label1.refresh after updating the label which I have tried in Xojo and it makes no difference. What I was thinking is adding a parameter to my UpdateLabel method to include the name of the label so I can just have one method that updates different labels on the screen but I havent got my head around that yet, I am still having trouble getting my head around classes and sub-classes, but it is starting to make sense :wink:

Here is a generic method to update a label with a given name in the first parameter:

Sub UpdateLabel(labelName as string, newText as string) dim c as Control for i as Integer = 0 to self.ControlCount c = control(i) if c isa Label and c.Name = labelName then Label(c).Text = newText Label(c).Refresh exit end if next End Sub

UpdateLabel("Label1","Some new text") //replace "Label1" with the label name, and "Some new text" with the new text 

Thanks Jason, this might be totally wrong but is it not possible in Xojo to set the labelName in the method to be of type label and then reference that from within the method so you would not have to loop round all the controls on the form? As I say I am new to this but I know it was possible to do something like this in VB but not sure in Xojo?

That would also work. Something like:

Sub UpdateLabel(labelName as label, newText as string) labelName.Text = newText labelName.Refresh End Sub
or in a module you could do something like Michel mentioned above but without a subclass:

Sub myText(extends labelName as label, assigns newText as string) labelName.Text = newText labelName.Refresh End Sub
which can be used like this:

Label1.myText = "some new text"

Thanks Jason, I have learned a lot from those examples as I am having a real mind bending issue trying to get my head around classes etc and the OOPs concept. I have not had a eureka moment yet but the pieces are starting to make sense and I can at lease now understand the examples people are giving me which is a big step forward :wink:

Two things I havent seen before are the "extends and the “assigns”. How does this method get linked with the label class and why do you need the assigns?

Sorry, I have just seen “extends labelName as label” which I now see is how it knows to extend the label class but still unsure about what the “assigns” bit does.

Assigns allows you to use the assignment operator (=), which makes this method more natural and like a property. If there was no assigns the syntax would be:

label1.mytext("some new text")

Does that make sense?

That is so cool, thanks for the explanation, that makes perfect sense, had no idea you could do that.

Thank you so much for your help and makes me realize I still have sooo much to learn :wink: