LINUX.ORG.RU

Qt, ну так не пойдет...

 


2

5

Короче есть QTimeEdit.

Когда его редактируешь с клавиатуры — если удерживать клавишу-стрелку и долго не отпускать — оно эмитит огромное кол-во сигналов timeChanged() эти сигналы скапливаются в очередь и сам таймэдит начинает тормозить и все медленнее обновляет значение у себя. У меня даже кулер подразгоняется от этого.

И это я уже отнаследовался, повесил на это говно в свой слот и не пущщаю ничего наружу, а эмичу свой сигнал, когда оно успокоится (типа debounce). Т.е. вся эта говнина эмитит свои сигналы локально внутри самого экземпляра и создает там FIFO очередь, которая начинает страшно тупить.

Ну и что делать? Как очистить очередь этих сигналов? Или как запретить эмитить их так часто?

Если ты не используешь QueuedConnection (явно или через коннект с объектом из другого потока), то никакой очереди сигналов нет, по крайней мере «снаружи» объекта. Если сигнал вызывается чаще, чем нужно, то просто делай выход в самом начале слота по какому-то простому условию, тогда обработка лишних сигналов займет минимум времени.

Очереди могут возникнуть внутри реализации объекта, но с ними ты уже никаким костылем вроде blockSignals не справишься. Правь виджет, выкладывай патч

annulen ★★★★★
()
Ответ на: комментарий от RazrFalcon

Не покатит, т.к. этот сигнал мне нужен. Я хочу ограничить его «интенсивность» или каким-то образом очищать накопившуюся очередь ненужных мне сигналов.

deep-purple ★★★★★
() автор топика
Ответ на: комментарий от annulen

Вот подписка в конструкторе:

    connect(
        this,
        SIGNAL(timeChanged(QTime)),
        this,
        SLOT(catchInternalTimeChanged(QTime))
    );
Вот содержимое слота:
void
myTimeEdit::catchInternalTimeChanged(const QTime &time)
{
    Q_UNUSED(time);

    mp_debouncer.stop();
    mp_debouncer.start(DEBOUNCE_TIME);
}
Куда уж меньше?

deep-purple ★★★★★
() автор топика
Ответ на: комментарий от annulen

Кстати, этот дебаунс (сейчас 500 мс) еще хоть как-то помогает — тупить начинает только сам таймэдит элемент. А без дебаунса сигналов — изза кучи накопившегося говна тупит все приложение ))

deep-purple ★★★★★
() автор топика
Ответ на: комментарий от deep-purple

Если mp_debouncer это QTimer, то заменить его на QElapsedTimer и выходить, если не натикало DEBOUNCE_TIME, в противном случае выполнять работу и рестартить таймер

annulen ★★★★★
()
Ответ на: комментарий от annulen

Так он и работает в режиме обратного отсчета. Когда внутренние сигналы не эмитит более N мс, то он эмитит текущее значение уже реально наружу. Или ты про то что элапсед таймер полегче будет?

deep-purple ★★★★★
() автор топика
Ответ на: комментарий от RazrFalcon

Во первых: проблема есть, я её вижу и кулер слышу.

Во вторых: треды снаружи таймэдита передают тебе пламенный привет!

deep-purple ★★★★★
() автор топика
Ответ на: комментарий от annulen

Йес!!! Стало намного лучше!

Однако — внутренняя очередь все так же скапливается и сам таймэдит тупит. Щас попробую еще поиграться с коннектом на timeChanged()

deep-purple ★★★★★
() автор топика
Ответ на: комментарий от deep-purple

Однако — внутренняя очередь все так же скапливается и сам таймэдит тупит

Скорее всего, он слишком часто пытается перерисовываться, возможно поможет в наследнике переопределить paintEvent и так же блокировать по таймеру

annulen ★★★★★
()
Ответ на: комментарий от annulen

Разве он от этого не начнёт мигать?

В целом от DE тоже может лагать. В KDE4 использовалась анимация полей ввода, что могло приводить к тормозам.

RazrFalcon ★★★★★
()
Ответ на: комментарий от annulen

Да, это точно внутри него самого (проверил только что на голом элементе). Ну зх, надо пробовать.

deep-purple ★★★★★
() автор топика
Ответ на: комментарий от RazrFalcon

Что да? Оказалось не да — проблема внутри таймэдита.

deep-purple ★★★★★
() автор топика
Ответ на: комментарий от annulen

Хотя что интересно — когда крутишь значение скроллом, то оно не тупит и все красиво и плавно делает.

deep-purple ★★★★★
() автор топика
Ответ на: комментарий от deep-purple

Потому что на колёсико stepBy меняется не на единичку. См. методы stepBy, wheelEvent и keyPressEvent у абстрактного спинбокса.

fluorite ★★★★★
()
Ответ на: комментарий от fluorite

Хм... Тогда может правильнее будет переопределить keyPressEvent вместо paintEvent как предполагали выше?

deep-purple ★★★★★
() автор топика
Ответ на: комментарий от fluorite

Очень интенсивно — значения скачут как угорелые и без тормозов. Но тут еще надо оговориться, что это не колесико, а тач полоска. И она не такую дельту в маус-ивенте дает — дельта гораздо «плавнее».

deep-purple ★★★★★
() автор топика
Ответ на: комментарий от RazrFalcon

Разве он от этого не начнёт мигать?

Если поверх него ничего не рисуется, то не начнет

annulen ★★★★★
()

[2018-01-02 20:50:23.175] starting of log [2018-01-02 20:50:23.175] Compilation date: Jan 2 2018 20:49:32 [2018-01-02 20:50:25.388] «00:01:00» [2018-01-02 20:50:25.886] «00:02:00» [2018-01-02 20:50:25.886] «00:03:00» [2018-01-02 20:50:25.919] «00:04:00» [2018-01-02 20:50:25.952] «00:05:00» [2018-01-02 20:50:25.985] «00:06:00» [2018-01-02 20:50:26.018] «00:07:00» [2018-01-02 20:50:26.051] «00:08:00» [2018-01-02 20:50:26.084] «00:09:00» [2018-01-02 20:50:26.117] «00:10:00» [2018-01-02 20:50:26.150] «00:11:00» [2018-01-02 20:50:26.183] «00:12:00» [2018-01-02 20:50:26.216] «00:13:00» [2018-01-02 20:50:26.249] «00:14:00» [2018-01-02 20:50:26.283] «00:15:00» [2018-01-02 20:50:26.316] «00:16:00» [2018-01-02 20:50:26.349] «00:17:00» [2018-01-02 20:50:26.382] «00:18:00» [2018-01-02 20:50:26.387] «00:19:00» [2018-01-02 20:50:26.432] «00:20:00» [2018-01-02 20:50:26.479] «00:21:00» [2018-01-02 20:50:26.526] «00:22:00» [2018-01-02 20:50:26.572] «00:23:00» [2018-01-02 20:50:26.619] «00:24:00» [2018-01-02 20:50:26.666] «00:25:00» [2018-01-02 20:50:26.699] «00:26:00» [2018-01-02 20:50:26.744] «00:27:00» [2018-01-02 20:50:26.791] «00:28:00» [2018-01-02 20:50:26.822] «00:29:00» [2018-01-02 20:50:26.869] «00:30:00» [2018-01-02 20:50:26.916] «00:31:00» [2018-01-02 20:50:26.949] «00:32:00» [2018-01-02 20:50:26.994] «00:33:00» [2018-01-02 20:50:27.041] «00:34:00» [2018-01-02 20:50:27.073] «00:35:00» [2018-01-02 20:50:27.120] «00:36:00» [2018-01-02 20:50:27.166] «00:37:00» [2018-01-02 20:50:27.198] «00:38:00» [2018-01-02 20:50:27.244] «00:39:00» [2018-01-02 20:50:27.292] «00:40:00» [2018-01-02 20:50:27.324] «00:41:00» [2018-01-02 20:50:27.370] «00:42:00» [2018-01-02 20:50:27.416] «00:43:00» [2018-01-02 20:50:27.448] «00:44:00» [2018-01-02 20:50:27.494] «00:45:00» [2018-01-02 20:50:27.541] «00:46:00» [2018-01-02 20:50:27.574] «00:47:00» [2018-01-02 20:50:27.619] «00:48:00» [2018-01-02 20:50:27.666] «00:49:00» [2018-01-02 20:50:27.699] «00:50:00» [2018-01-02 20:50:27.744] «00:51:00» [2018-01-02 20:50:27.791] «00:52:00» [2018-01-02 20:50:27.823] «00:53:00» [2018-01-02 20:50:27.869] «00:54:00» [2018-01-02 20:50:27.916] «00:55:00» [2018-01-02 20:50:27.948] «00:56:00» [2018-01-02 20:50:27.995] «00:57:00» [2018-01-02 20:50:28.041] «00:58:00» [2018-01-02 20:50:28.073] «00:59:00» [2018-01-02 20:50:31.200] ending of log

Ничего там не тупит. С такими вбросами нужно приносить минимально не работающий говнокод

anonymous
()
Ответ на: комментарий от deep-purple

i5 2500k, дело не в характеристиках. При зажимании клавиши вверх QTimerEdit генерирует сигнал раз в ~33мс.

anonymous
()
Ответ на: комментарий от deep-purple

Может за это как-то отвечает Flood Rate клавиши? Быть может он у тебя дохера повышен и нестандартный.

EXL ★★★★★
()
Ответ на: комментарий от deep-purple

Неправильный дебаунс. Вот правильный (предполагая что mp_debouncer - QTimer):

void
myTimeEdit::catchInternalTimeChanged(const QTime &time)
{
    Q_UNUSED(time);

    if (!mp_debouncer.isActive())
        mp_debouncer.start(DEBOUNCE_TIME);
}

former_anonymous ★★★
()
Ответ на: комментарий от former_anonymous

Уже переписано с использованием элапсед тайм.

deep-purple ★★★★★
() автор топика
Ответ на: комментарий от anonymous

Intel Atom 1.2GHz 32bit, 768MB RAM.

Гыы — накидал отдельной прилагой в коротой только эдит и лейбл — не тормозит.

Набросил только тайм эдит (родной, не наследный и без коннектов) внутрь «большой» прилаги — тормозит. Все, приехали? Куда копать дальше?

deep-purple ★★★★★
() автор топика

Короче. По факту, ребята, проблема есть. Но она не проявляется на хорошем железе.

Было бы хорошо всетаки каким-то способом ограничить интенсивность этих сигналов.

deep-purple ★★★★★
() автор топика

Просто используй Electron и нормальный язык - JavaScript :-) Цепепе уже давно obsolete :-)

anonymous
()
Ответ на: комментарий от deep-purple

Прочитал я твои страдания. Ну что ж, значит ты нашел баг, проблему. Такое бывает, что кто-то является первооткрывателем, а авторы виджета не подозревали о таком сценарии.

Пиши скорее баг-репорт. Попробуй выяснить, есть ли такая проблема в виджете Qt 4.x, а может ее нет в ранних версиях Qt 5.x. И жди когда исправят, но можешь и сам патч приготовить.

Видимо тебе придется лезть в код Qt, а может и сделать свой виджет для решения проблемы.

I-Love-Microsoft ★★★★★
()
Ответ на: комментарий от deep-purple

Ну а если ввести переменную в которую сохранять время последнего вызова слота, и также в этом слоте проверять разницу текущего времени и времени из этой переменной, если разница слишком мала, то выходить из слота и не выполнять действий.

rumgot ★★★★★
()
Последнее исправление: rumgot (всего исправлений: 1)
Ответ на: комментарий от rumgot

Не катит. Проблема в интенсивности испускания сигналов. Толку что я в слоте что-то делаю нет. Там уже поздно пить боржоми.

deep-purple ★★★★★
() автор топика
Ответ на: комментарий от deep-purple

Вот кстати да, попробуй накидать пример на Qt 4.

Qt 5 сильно разжирел и

Intel Atom 1.2GHz 32bit, 768MB RAM.

Для него видимо уже мало.

EXL ★★★★★
()
Ответ на: комментарий от deep-purple

На вменяемых лаптопах это фн-вверх, например.

anonymous
()
Ответ на: комментарий от EXL

Могу и на 4 проверить, но особого смысла не вижу — мне нужны фичи из 5. Ну ради интереса только.

deep-purple ★★★★★
() автор топика
Ответ на: комментарий от EXL

Так, стоп. Как я на четверке тогда проверю? На 5 оно и когда один виджет — не тормозит. А «большое» приложение использует фичи из 5 и будет сложно запустить это на 4.

deep-purple ★★★★★
() автор топика
Ответ на: комментарий от deep-purple

Проблема в интенсивности испускания сигналов

Само по себе испускание сигналов не создает практически никакой нагрузки. Проблема в алгоритме, который посылает эти сигналы в результате своей деятельности

annulen ★★★★★
()

IMHO, QTimeEdit все делает правильно. У тебя может быть, например, еще один Widget в виде аналоговых часов, у которых стрелки должны крутиться, при изменении циферок в QTimeEdit. При этом QTimeEdit может, конечно, эмитить сигналы не так часто, но он должен эмитить последний сигнал об изменении циферок, при этом как-то должен распознать, которое изменение было последним (сразу после этого изменения)... Думаю, что попытки изменить существующее поведение приведут к неожиданным косякам в произвольным местах приложения...

anonymous
()

Проблема явно в каком-то другом месте. Не может быть так, что ты на каждое получение сигнала создаёшь ещё один connect к нему же, к примеру? Посмотри свой код внимательно.

unC0Rr ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.