Stop Label Caption Flickering
Asked Answered
Z

1

7

I have a Label that is indicating a file size with

FormatFloat('##.## KB',BytesIn/OneKB);

and it all worked fine when the files were all under about 2MB. Now I am sometimes using files 2GB and up.

FormatFloat('##.##### MB',BytesIn/OneMB);

The Caption is being updated about every 1-KB and the flickering is fierce.

Any way to stop that or minimize it some?

Zing answered 10/7, 2013 at 19:2 Comment(6)
That the label is being updated every KB is not relevant here. More relevant is how frequently is that label being updated. From what you're describing it's very often, more often than user can ever notice.Lewse
Have you tried setting Label or Form DoubleBuffered property to TRUE?Faggoting
@Mark TLabel won't have a DoubleBuffered property because it is not windowed.Moro
I'd change the update frequency on files that large, personally. It's firing way too often for the user to notice (and probably a major cause of the flickering). "every 1-KB" for a one MB file is probably too fast, and every KB on a GB file is a pretty wasteful use of CPU (and UI updating).Inconsonant
@David is right, label doesn't have DoubleBuffered property, but try setting TForm's DoubleBuffered property to true and check if flickering occurs again.Faggoting
Yes, simply do not update the TLabel so often in the first place. Update it once every few seconds instead of on every KB value change, for instance store the latest value in memory somewhere and then use a TTimer to update the TLabel with the current value periodically.Elohim
M
14

The Delphi TLabel can indeed be a flickery beast. Many people will recommend double buffering, but I don't like that. It brings other problems. In particular, if you are using themes then double buffering can interfere with the themed rendering.

My trick for dealing with label flicker is to use a TStaticText instead of a TLabel. This is a windowed control, a wrapper around the Windows STATIC control, and in my experience it invariably will not flicker in the scenario where TLabel would.

As others mention, throttling update rate is a sound idea, and is wise irrespective of flickering. There's no need to spend resources updating the UI any faster than the human eye can absorb. For something like download progress you should not really need any more than 5Hz in my view. This may very well be the root cause of your problem, and if throttling update rate solves the problem then you can stick with TLabel.

My answer here has some more general anti-flicker tips: TLabel and TGroupbox Captions Flicker on Resize.

Moro answered 10/7, 2013 at 19:6 Comment(15)
+1 for suggesting the TStaticText trick, used that many times to solve same and similar issues with TLabel.Alfrediaalfredo
@Peter, it's not a solution. It's a workaround to the problem behind. If the label were updated less frequently, it wouldn't flicker. OP must now update that label so frequently, that user can't even be able to read the new value.Lewse
@Lewse Well, it might flicker at even quite low refresh rates.Moro
@David: But probably not. :-) Using TStaticText to address this problem is not a solution. If the label is being updated every KB for something >= 2GB at today's bandwidth speeds, flicker should be expected. The drawback to using TStaticText when not necessary is that it uses a window handle (HWND), where TLabel does not. (Granted, that's not as important now as it used to be, but still... "Waste not, want not."). Not downvoting - just commenting.Inconsonant
@Ken I'm not so sure. I don't see that flicker is necessarily related to update rate. You can see flicker on a single update.Moro
@TLama, I agree it's a workaround but what is the actual downside of using a TStaticText instead of a Tlabel to avoid flickering? Ken stated that the drawback is that TStaticText uses a handle but I don't see why that presents an issue.Alfrediaalfredo
@Peter, there is no downside in my view. Creating a window control (TStaticText) is not wasteful to even mention. Although, I didn't voted up this answer since it didn't mentioned the possible root of the problem. Only a workaround. If OP says that the flickering is fierce, then I'm almost sure (even if it's a vague term) that the label is updated too frequently. It's nice that you replace the component and stop flickering, but you won't stop wasting of all the repaints requested to it without the real ability of the user to ever read such frequently changed value.Lewse
@Lewse I simply don't agree that you have isolated the root of the problem for sure. Flickering in Delphi apps is usually nothing to do with refresh rate. Resize flicker is an example. Entire backgrounds get repainted for no good reason. I can put a label on a form and refresh it on a 50ms timer with no flicker.Moro
@David, I just can't reproduce flickering which I would call fierce. 50ms timer is not a problem at all (plain vanilla Delphi 7 project, no double buffer and no anti-flicker improvements of course)...Lewse
@Lewse I can repro flicker by setting label Caption in a busy loop so refresh rate could well be the issue.Moro
@DavidHeffernan Thanks for the Static Text, never knew it existed. Sadly, it changed little so I went back to the Label and made the underlying Panel.DoubleBuffered:=True and it has calmed it down a lot. I also changed the way the results were Formatted and that too has helped. The problem appears to be a result of the Label.Caption being cleared before being updated every time. If it was simply over-written, there should be no apparent flickering.Zing
As for the rest of the responders other than David, sometimes it is not practical or possible to change the way stuff is arriving to be displayed. In this case the numeric data was coming from a 3rd party component for which the client did not have the source. Reading a lot of stuff here, all too often it seems people respond with a "better way," without bothering to answer the actual question. That just adds to frustration and does not help in anyway at all guys.Zing
People suggest different ways to do things because they are trying to help. It's not uncomment for people to ask one question but really deep down they need the answer to a different question. If that's not the case for you then you can just ignore the advice. However, not matter where the data is coming from you could certainly implement some update rate throttling. So the data may arrive very rapidly, but you could choose to update the UI less rapidly. That may very well help.Moro
I know this question is couple of months old, but I still want to leave a comment. I am having the same problem. I have a 2 Tlabel on the form and One is not flickering and the other one is. So, I changed both of them as you suggested in the answer to TStaticText. It is also flickering the same way. I am displaying Date and Time on the TLabel once a second. Now you can't tell me that is too fast for a computer. LOL :)Norther
@ThayananthanNarayanan You ought to ask a new question. Make sure you provide a good SSCCE when you do.Moro

© 2022 - 2024 — McMap. All rights reserved.