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?

user2566616
  • 103
  • 1
  • 5
  • 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. – TLama Jul 10 '13 at 19:06
  • Have you tried setting Label or Form DoubleBuffered property to TRUE? – rsrx Jul 10 '13 at 19:07
  • @Mark TLabel won't have a `DoubleBuffered` property because it is not windowed. – David Heffernan Jul 10 '13 at 19:07
  • 2
    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). – Ken White Jul 10 '13 at 19:10
  • 2
    @David is right, label doesn't have `DoubleBuffered` property, but try setting TForm's `DoubleBuffered` property to true and check if flickering occurs again. – rsrx Jul 10 '13 at 19:15
  • 2
    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. – Remy Lebeau Jul 10 '13 at 19:42

1 Answers1

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.

Community
  • 1
  • 1
David Heffernan
  • 601,492
  • 42
  • 1,072
  • 1,490
  • +1 for suggesting the TStaticText trick, used that many times to solve same and similar issues with TLabel. – Peter Jul 10 '13 at 19:20
  • 2
    @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. – TLama Jul 10 '13 at 19:29
  • 1
    @TLama Well, it might flicker at even quite low refresh rates. – David Heffernan Jul 10 '13 at 19:42
  • 2
    @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. – Ken White Jul 11 '13 at 02:46
  • 1
    @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. – David Heffernan Jul 11 '13 at 06:18
  • @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. – Peter Jul 11 '13 at 06:32
  • @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. – TLama Jul 11 '13 at 06:45
  • 1
    @TLama 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. – David Heffernan Jul 11 '13 at 06:49
  • @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)... – TLama Jul 11 '13 at 07:07
  • @TLama I can repro flicker by setting label Caption in a busy loop so refresh rate could well be the issue. – David Heffernan Jul 11 '13 at 07:20
  • @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. – user2566616 Jul 15 '13 at 18:24
  • 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. – user2566616 Jul 15 '13 at 18:29
  • 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. – David Heffernan Jul 15 '13 at 18:48
  • 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 :) – ThN Oct 18 '13 at 17:42
  • @ThayananthanNarayanan You ought to ask a new question. Make sure you provide a good SSCCE when you do. – David Heffernan Oct 18 '13 at 21:37