Russian Qt Forum
Ноябрь 24, 2024, 06:50 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1]   Вниз
  Печать  
Автор Тема: Таблицы стилей: непонятные и страшные тормоза  (Прочитано 5998 раз)
Visor
Гость
« : Ноябрь 09, 2007, 14:55 »

Здравствуйте! Задавал вопрос на других форумах - перенаправили к вам.

Сразу скажу - сейчас пишу на PyQt 2.5 (Qt 4.3.1), но т.к. это только привязка к qt dll, думаю вопрос останется актуальным.

Есть виджет, обычный, производный от QWidget.
В обычной ситуации он как-то подкрашен или выделен цветной рамкой, неважно. При наведении на него указателя мыши нужно его закрасить по другому. Я попробовал решить эту проблему с помощью динамических свойств:

"
*[selected="false"] {
border: none;
}

*[selected="true"] {
border-width: 2px;
border-style: solid;
border-color: darkkhaki;
border-radius: 5px;
}
"

Как написано в доке, после изменения дин. свойства стиль нужно переустановить. Вот здесь начинаются проблемы... если у него есть дочерние виджеты. Структура - дерево. Чем больше дерево, тем дольше работает функция setStyleSheet. Профилирование показало, что отсылается тьма событий всем дочерним на изменения стиля.

Пробовал так...
"
.MyWidget {
border: none;
}

.MyWidget {
border-width: 2px;
border-style: solid;
border-color: darkkhaki;
border-radius: 5px;
}
"
...и по всякому.

Не помогло! Какой стиль не пиши, setStyleSheet затрагивает дочерние элементы. Функция может работать 1 сек, может и 3 сек...

Да, ещё... Я переопределяю mouseMoveEvent (вернее, enter и leave) и в обработчике ставлю стиль... или меняю динамическое свойство (setProperty) и обновляю стиль...

Вариант с палитрой не подойдёт - в перспективе виджет нужно будет красиво оформить, с изменением padding, подкраской рамки, изменение цвета фона или фонового рисунка. Причём, виджеты будут разных типов (графически) и оформляться будут по разному, поэтому я и обратил внимание на динамич. свойста и таблицы стилей.

Буду рад любому пинку в правильном направлении... спасибо.
Записан
Visor
Гость
« Ответ #1 : Ноябрь 09, 2007, 15:00 »

Я искал по форуму, нашёл несколько похожих тем, в частности "Можноли менять свойства объектов через css - файл?".
Там вскользь обсуждается скорость css, у меня вопрос немного глубже.
Записан
k06a
Гость
« Ответ #2 : Ноябрь 11, 2007, 13:00 »

А ты файл ксс, при наведении курсора на объект с диска считываешь?
(Может он каждый раз считывает его с диска для каждого эл-та дерева?)
Ты не пробовал засекать, в каком именно месте все тормозится?
Записан
Visor
Гость
« Ответ #3 : Ноябрь 12, 2007, 11:19 »

Цитировать
А ты файл ксс, при наведении курсора на объект с диска считываешь?
(Может он каждый раз считывает его с диска для каждого эл-та дерева?)

Нет...
Я ставлю стиль 1 раз, с файла не считываю, передаю готовую строку.
Ставлю его на родительском виджете, как уже сказал, 1 раз.

Цитировать
Ты не пробовал засекать, в каком именно месте все тормозится?

Да, я выяснил, где всё тормозится. Я профилировал функцию QWidget::setStyleSheet.
Профилирование показало наличие громадного количества сообщений всем детям на смену стиля (QEvent::StyleChange).
К примеру, если у родительского виджета 20 детей (разного уровня вложенности), то функция работает до 1 сек. С ростом детей время резко увеличивается. Я прикинул сложность - где-то O(n2), т.е. лавинный рост, это пугает...

Похоже, я понял, почему же изменение синтаксиса стиля ни к чему не приводит. В доке сказано, что, например, .QPushButton применяет стиль только к QPushButton, а не к производным. Здесь имеется в виду именно факт класса-наследника, а не виджета-ребёнка.

Поясню, зачем может потребоватся такая вложенность виджетов...
Есть виджет-контейнер необычно оформленный, он может содержать другие виджеты (с помощью QVBoxLayout например), в т.ч. другие контейнеры. Вот откуда дерево взялось... И если к самому верхнему контейнеру применить стиль, то и начинаются тормоза.
Записан
Visor
Гость
« Ответ #4 : Ноябрь 12, 2007, 12:12 »

Может быть я как-то нестандартно использую стили?
Ещё раз о задаче: нужно в зависимости от какого-то состояния менять внешний вид виджета.
Состояние: например, при клике мышкой на виджете состояние "выделено", при клике на другом виджете или клике с ctrl по этому же состояние "невыделено".
В зависимости от этих 2-х состояний нужно раскрасить виджет.
Динамические свойства и переустановка стиля после их изменения - пока единственное, к чему я пришёл. Можно и без них обойтись, но всё равно придётся постоянно ставить новый стиль.
Пока я не вижу решения с установкой 1 раз стиля при запуске приложения, меняя затем какие-то параметры у виджетов с автоматической перерисовкой.
Может быть я что-то пропустил?
Записан
Tonal
Гость
« Ответ #5 : Ноябрь 13, 2007, 07:58 »

А Pseudo-States не пробывал пользоваться?
Т.е. для твоего описания, на вскидку, описываешь 2 стиля - нормальный и :selected
Ну а Qt само разбирается каким стилем что оформлять.
Записан
Visor
Гость
« Ответ #6 : Ноябрь 13, 2007, 14:17 »

Псевдо-состояния - это было бы идеальное решение, но... судя по документации и моим экспериментам нельзя добавлять собственные состояния.

Цитировать
Т.е. для твоего описания, на вскидку, описываешь 2 стиля - нормальный и :selected

Стили я могу написать, вопрос в том, как менять состояние "selected". Повторюсь, у меня не QTabBar, например, где "selected" внутренне поддерживается, у меня обычный виджет. Нет времени, чтобы копать исходники Qt. По крайней мере, через дин. св-во или через переменную-член изменить не получится.
Записан
Visor
Гость
« Ответ #7 : Ноябрь 13, 2007, 14:35 »

Для "обычного" виджета мне удалось прекрасно обработать пару состояний - focus (фокус ввода) и hover (наведения мышки). Всё остальное игнорируется, т.к. это специфика производных виджетов, типа кнопки и т.п.
Записан
Tonal
Гость
« Ответ #8 : Ноябрь 14, 2007, 08:15 »

Если лень копать исходники, спроси на http://www.qtcentre.org/forum/ мож там знают.

P.S. Тема всяко интересная, но сейчас просто нет времени. Отпиши, если что получиться.
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.058 секунд. Запросов: 21.