Остановить мерцание заголовка метки

У меня есть метка, указывающая размер файла с помощью

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

и все это работало нормально, когда все файлы были меньше 2 МБ. Теперь я иногда использую файлы размером 2 ГБ и выше.

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

Заголовок обновляется примерно каждые 1 КБ, и мерцание сильное.

Есть ли способ остановить это или свести к минимуму?


person user2566616    schedule 10.07.2013    source источник
comment
То, что метка обновляется каждый КБ, здесь не имеет значения. Более важным является то, как часто обновляется эта метка. Судя по тому, что вы описываете, это очень часто, чаще, чем пользователь может заметить.   -  person TLama    schedule 10.07.2013
comment
Вы пытались установить для свойства Label или Form DoubleBuffered значение TRUE?   -  person Marko Paunovic    schedule 10.07.2013
comment
@Mark TLabel не будет иметь свойство DoubleBuffered, потому что оно не оконное.   -  person David Heffernan    schedule 10.07.2013
comment
Лично я бы изменил частоту обновления файлов такого размера. Он срабатывает слишком часто, чтобы пользователь мог его заметить (и, вероятно, основная причина мерцания). каждый 1 КБ для одного файла MB, вероятно, слишком быстрый, а каждый КБ для файла GB — довольно расточительное использование ЦП (и обновления пользовательского интерфейса).   -  person Ken White    schedule 10.07.2013
comment
@David прав, метка не имеет свойства DoubleBuffered, но попробуйте установить для свойства DoubleBuffered TForm значение true и проверьте, не возникает ли мерцание снова.   -  person Marko Paunovic    schedule 10.07.2013
comment
Да просто не обновляйте TLabel так часто во-первых. Обновляйте его каждые несколько секунд, а не при каждом изменении значения КБ, например, сохраните последнее значение где-нибудь в памяти, а затем используйте TTimer для периодического обновления TLabel текущим значением.   -  person Remy Lebeau    schedule 10.07.2013


Ответы (1)


Delphi TLabel действительно может быть непоседливым зверем. Многие рекомендуют двойную буферизацию, но мне это не нравится. Это приносит другие проблемы. В частности, если вы используете темы, двойная буферизация может помешать тематическому рендерингу.

Мой трюк для борьбы с мерцанием метки заключается в использовании TStaticText вместо TLabel. Это оконный элемент управления, оболочка для элемента управления Windows STATIC, и, по моему опыту, он неизменно не будет мерцать в сценарии, где TLabel мерцает.

Как упоминают другие, дросселирование частоты обновления — это разумная идея, и она разумна независимо от мерцания. Нет необходимости тратить ресурсы на обновление пользовательского интерфейса быстрее, чем может воспринять человеческий глаз. На мой взгляд, для чего-то вроде прогресса загрузки вам не нужно больше 5 Гц. Это вполне может быть основной причиной вашей проблемы, и если регулирование скорости обновления решит проблему, вы можете придерживаться TLabel.

Мой ответ здесь содержит несколько более общих советов по борьбе с мерцанием: Изменить размер.

person David Heffernan    schedule 10.07.2013
comment
+1 за предложение трюка с TStaticText, который много раз использовался для решения одних и тех же и подобных проблем с TLabel. - person Peter; 10.07.2013
comment
@ Питер, это не решение. Это обходной путь к проблеме позади. Если бы метка обновлялась реже, она бы не мерцала. OP теперь должен обновлять эту метку так часто, что пользователь даже не сможет прочитать новое значение. - person TLama; 10.07.2013
comment
@TLama Ну, он может мерцать даже при довольно низкой частоте обновления. - person David Heffernan; 10.07.2013
comment
@ Дэвид: Но, вероятно, нет. :-) Использование TStaticText для решения этой проблемы не является решением. Если метка обновляется каждый КБ для чего-то ›= 2 ГБ при сегодняшней пропускной способности, следует ожидать мерцания. Недостаток использования TStaticText, когда в нем нет необходимости, заключается в том, что он использует дескриптор окна (HWND), а TLabel — нет. (Конечно, сейчас это не так важно, как раньше, но все же... Не тратьте зря, не хотеть.). Не минусую - просто комментирую. - person Ken White; 11.07.2013
comment
@ Кен, я не уверен. Я не вижу, чтобы мерцание обязательно было связано с частотой обновления. Вы можете увидеть мерцание при одном обновлении. - person David Heffernan; 11.07.2013
comment
@TLama, я согласен, что это обходной путь, но каков реальный недостаток использования TStaticText вместо Tlabel, чтобы избежать мерцания? Кен заявил, что недостатком является то, что TStaticText использует дескриптор, но я не понимаю, почему это представляет проблему. - person Peter; 11.07.2013
comment
@Peter, на мой взгляд, недостатков нет. Создание элемента управления окном (TStaticText) не является расточительным, чтобы даже упоминать об этом. Хотя я не проголосовал за этот ответ, поскольку в нем не упоминался возможный корень проблемы. Только обходной путь. Если OP говорит, что мерцание сильное, то я почти уверен (даже если это расплывчатый термин), что метка обновляется слишком часто. Хорошо, что вы заменяете компонент и перестаете мерцать, но вы не перестанете тратить впустую все запрошенные к нему перерисовки без реальной возможности пользователя когда-либо читать такое часто изменяемое значение. - person TLama; 11.07.2013
comment
@TLama Я просто не согласен с тем, что вы точно изолировали корень проблемы. Мерцание в приложениях Delphi обычно не связано с частотой обновления. Например, изменение размера мерцания. Целые фоны перекрашиваются без уважительной причины. Я могу поставить метку на форму и обновить ее по таймеру 50 мс без мерцания. - person David Heffernan; 11.07.2013
comment
@ Дэвид, я просто не могу воспроизвести мерцание, которое я бы назвал сильным. Таймер 50 мс вообще не проблема (простой ванильный проект Delphi 7, без двойного буфера и, конечно, без улучшений антимерцания)... - person TLama; 11.07.2013
comment
@TLama Я могу воспроизвести мерцание, установив метку Caption в цикле занятости, поэтому проблема может быть в частоте обновления. - person David Heffernan; 11.07.2013
comment
@DavidHeffernan Спасибо за статический текст, никогда не знал, что он существует. К сожалению, это мало что изменило, поэтому я вернулся к метке и сделал основную Panel.DoubleBuffered:=True, и это сильно успокоило ситуацию. Я также изменил способ форматирования результатов, и это тоже помогло. Проблема, по-видимому, является результатом очистки Label.Caption перед каждым обновлением. Если бы это было просто перезаписано, не должно быть никакого мерцания. - person user2566616; 15.07.2013
comment
Что касается остальных респондентов, кроме Дэвида, иногда нецелесообразно или невозможно изменить способ отображения поступающих материалов. В этом случае числовые данные поступали от стороннего компонента, для которого у клиента не было источника. Читая здесь много материала, слишком часто кажется, что люди отвечают лучше, не утруждая себя ответом на фактический вопрос. Это только добавляет разочарования и никоим образом не помогает ребятам. - person user2566616; 15.07.2013
comment
Люди предлагают разные способы сделать что-то, потому что они пытаются помочь. Люди не без комментариев задают один вопрос, но в глубине души им нужен ответ на другой вопрос. Если это не так для вас, то вы можете просто проигнорировать совет. Однако независимо от того, откуда поступают данные, вы, безусловно, можете реализовать некоторое регулирование частоты обновления. Таким образом, данные могут поступать очень быстро, но вы можете выбрать менее быстрое обновление пользовательского интерфейса. Это вполне может помочь. - person David Heffernan; 15.07.2013
comment
Я знаю, что этому вопросу пару месяцев, но я все еще хочу оставить комментарий. Я с той же проблемой. У меня на форме 2 таблички, одна не мерцает, а другая мерцает. Итак, я изменил их обоих, как вы предложили в ответе на TStaticText. Тоже так же мерцает. Я показываю дату и время на TLabel раз в секунду. Теперь вы не можете сказать мне, что это слишком быстро для компьютера. РЖУ НЕ МОГУ :) - person ThN; 18.10.2013
comment
@ThayananthanNarayanan Вы должны задать новый вопрос. При этом убедитесь, что вы предоставили хороший SSCCE. - person David Heffernan; 19.10.2013