Progress wheel stays invisible

I have a progress wheel that I like to be shown und turning while some file access is beeing performed. Unfortunately, it never pops up. This is the code I try to test it in a simple manner, but even with that no success. The code in italic has been added - although it should not be neccessary - to try all possible ‘enhancements’, but did not help either. Anyone has a hint?

dim i as integer '$$$
beep
WindowMain.Wheel.Visible = true
WindowMain.Wheel.RefreshRect(0,0,16,16)
EnableMenuItems
DoEvents

for i = 1 to 10000000
i = i*2/2
next
WindowMain.Wheel.Visible = false
beep

Your for-next loop is monopolizing the thread, so the progress wheel cannot update. You need to get rid of the loop and instead use a timer to wake up periodically and check if you’re done. In the meantime, the main event loop will have time to update the wheel. Example projects showing how to do this accompany Xojo I think, and it’s probably also described in the documentation.

Thanks. I’ll check again the documentation.
But shouldn’t it at least become visible before the for-next loop (whitout rotating, though)?

“If the control is to be animated during a tight loop, this can be achieved by putting the loop in a Thread, or via the RectControl.Refresh method.”
So, I put Rectcontrol.Refresh into the loop, but no appearance of the wheel, and the application is just beach-balling…

Don’t do something like this. Put your file activitities in a thread. The thread calls a timer which does the refresh.

Have a look at the examples. UI Update or something similar.

If you put in ‘for’ cycle:

if i mod 100000 = 0 then WindowMain.Wheel.Refresh

You will see. :slight_smile:
Yes, it little bit slows down your computing but at least gives feedback. If this is not acceptable, use thread.

Ok, firstly, the documentation is then not correct, if it states that next to a thread RectControl.Refresh should do it.

Secondly, I tried to setup a timer (thats like another thread, right?). During its 50milisecond multiple run, it just sets Wheel.Visible = true and Wheel.Refresh. But no progress wheel is shown over the 3 second period while the lengthy file is beeing read…

At this case documentation is correct. You refresh once and it refreshses and shows you wheel state at refresh moment.
You must refresh often or use thread for your computing for giving wheel little bit steam for rotation… :slight_smile:

[quote=384378:@Peter Kronenberg]Ok, firstly, the documentation is then not correct, if it states that next to a thread RectControl.Refresh should do it.

Secondly, I tried to setup a timer (thats like another thread, right?). During its 50milisecond multiple run, it just sets Wheel.Visible = true and Wheel.Refresh. But no progress wheel is shown over the 3 second period while the lengthy file is beeing read…[/quote]

You don’t understand. Timer <> Thread.

But neither a timer nor a thread may be necessary.

In your code above, the wheel does not show because you need to do the visible in another event. Otherwise the visible true and false will happen both at the end of the current event.

You must put

WindowMain.Wheel.Visible = true

in another event. For instance if your code is in a button, use MouseDown for that code.

Then it should show the progressWheel just fine, and hide it after the loop is over.

Note : DoEvents is not necessary. It does nothing where is is.

And not recommended in Desktop Applications.

Because it’s mainly for Console Applications which have no Main Thread, tho you create your own Main Event Loop to yield time to Classes which rely on the Main Event Loop.

Maybe for Mac it’s true, but for Windows it shows only wheel but did not rotate it, as accomplishing For cycle takes all power from processor.
For rotating just for trying make Window, put there Button and ProgressWheel named ‘Wheel’ with visiblity turned off and for Button Action event paste:

beep Wheel.Visible = true Wheel.Refresh for i as integer = 1 to 10000000 if i mod 100000 = 0 then Wheel.Refresh i = i*2/2 next Wheel.Visible = false beep
No need for over thinking. And if in future you are more familiar with threads, just use them…

There’s lots of mixed advice here.

Xojo only updates its interface at the end of an event loop, not just event. The event loop is literally just a loop that checks for things like user input and triggers events accordingly, then updates the UI and starts the next iteration.

Using Refresh can sometimes work, but don’t count on it. You might as well pretend it doesn’t exist.

If your app has work to do that is expected to take more than 2 seconds, you absolutely must use a thread. Using a thread is easy; communicating the status of the thread to the user is the tricky part.

Look in the Xojo examples included with the download. There are projects that demonstrate this. The idea is a thread does its work, almost like a mini-program, and a timer watches a property or two to determine what the thread is doing. The timer is allowed to update the UI because the thread is not.

Anything less is a workaround.

[h]Amazing! In a bad way. :([/h]

That code I put above, will take 0.98 seconds to compute with Xojo 2014r3.2 and 3.18 !!! seconds with Xojo 2018r1!
Its’ huge slowdown for graphics in Windows environment. :frowning:

Okay - little cooldown. :slight_smile:
Compiled them both to 32-bit executables and now are scores: Xojo 2014r3.2 0.40 and Xojo 2018r1 0.45.
But still pity that compiling time and processing time in Xojo 2018r1 is noticeably slower. It means raise of development time…

OK, guys, I opted to omit a timer and a thread, both seemed to be an overkill.
So I just put a

window.wheel.visible = true
DoEvents
for…
next
window.wheel.visible = false
DoEvents

at the beginn and end of that extensive loop - and it did what I wanted it to do!

NO!!! Do not do that! DoEvents shouldn’t even exist in the desktop framework. It can cause recursion. It’s basically saying “do the thing you’re already doing.”

@Thom McGrath you are a legendary figure and I would never question your guidance (and certainly DoEvents in desktop apps has been universally discouraged forever) but I’m curious about the “can” part of “can cause recursion”. Under what circumstances will it and will it not? I know that disaster is almost sure to occur in a multi-threaded app, but if one has no threads but the main thread, is it still as much of a danger? Asking for a friend :slight_smile:

It works fine. The DoEvent is not within the loop, it just triggers the progress wheel to be shown and hidden…

Yep, still a danger. It DoEvents is basically “detect user input events, trigger timers, give time to threads, and update ui” all in one method. DoEvents in MouseDown or Timer.Action, for example, can be especially dangerous. But the effect could happen anywhere really. Its only valid use is when there is no other event loop running.

Since you’re still learning the language, I’m trying to teach you the right way. I worked for Xojo for years and even gave an XDC talk on this stuff. You should heed my advice. DoEvents is one of the worst parts of Xojo Desktop, because it does exactly this - it looks like it works, and it kind of does, but it can cause subtle and hard-to-diagnose problems. Do not use it a desktop app.