![]() |
Здравствуйте, гость ( Вход | Регистрация )
![]() ![]() |
![]() |
Obey-Kun |
![]() ![]()
Сообщение
#1
|
![]() Студент ![]() Группа: Участник Сообщений: 96 Регистрация: 24.3.2010 Пользователь №: 1556 Спасибо сказали: 3 раз(а) Репутация: ![]() ![]() ![]() |
Сделал итем Cell, унаследованный от QGraphicsItem. Он рисует прямоугольник (я знаю про QGraphicsRectItem, но мой итем сложнее и он тут не катит). Располагаю их впритык (то есть, допустим, первый от 0 до 10, второй от 10 до 20 и т.д). Так как изначально у них всех границы рисуются одним и тем же цветом и нулевой толщиной, проблем нет. Но я хочу, чтобы при выделении граница становилась синей. Сказано — сделано. Чуть изменил строчку в void Cell::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget).
И всплыла проблема. Позднее созданные виджеты перекрывают ранее созданные, из-за чего граница их кое-где перекрывается более «молодыми» итемами. Вот как это выглядит: ![]() Обходится это очень просто. Надо поднимать выделенные ячейки путём смены z. По умолчанию z=0, так что можно поступить вполне элегантно — переопределить void setSelected ( bool selected ):
Хоть решение и элегантно, но так почему-то не работает. Картина остаётся такой же. Если же поступаю дурацким способом и запихиваю setZValue(isSelected()) прямо в paint, то всё ок: ![]() А через переопределении функции setSelected -- фиг. Почему так? Сообщение отредактировал Obey-Kun - 28.3.2010, 1:44 |
|
|
igor_bogomolov |
![]()
Сообщение
#2
|
Профессионал ![]() ![]() ![]() ![]() ![]() Группа: Сомодератор Сообщений: 1215 Регистрация: 22.3.2009 Из: Саратов Пользователь №: 630 Спасибо сказали: 235 раз(а) Репутация: ![]() ![]() ![]() |
Obey-Kun, приложи рабочий пример, есть подозрение что у тебя отрисовка не правильная. Нижнюю правую точку необходимо сместить на 1px.
|
|
|
Obey-Kun |
![]()
Сообщение
#3
|
![]() Студент ![]() Группа: Участник Сообщений: 96 Регистрация: 24.3.2010 Пользователь №: 1556 Спасибо сказали: 3 раз(а) Репутация: ![]() ![]() ![]() |
Копипастю код целиком:
Раскрывающийся текст
Раскрывающийся текст
Раскрывающийся текст
Раскрывающийся текст
Стоит отметить, что когда я создавал QGraphicsRectItem, он так же себя вёл (в смысле, перекрывался соседями, если они идут друг за другом). Так что вряд ли дело в одном пикселе. Логичное предположение — я так понимаю, вы подумали, что я использую QRect, но я его не использую. Сообщение отредактировал Obey-Kun - 28.3.2010, 0:41
Причина редактирования: Пользуйтесь тэтом [ expand ]
|
|
|
igor_bogomolov |
![]()
Сообщение
#4
|
Профессионал ![]() ![]() ![]() ![]() ![]() Группа: Сомодератор Сообщений: 1215 Регистрация: 22.3.2009 Из: Саратов Пользователь №: 630 Спасибо сказали: 235 раз(а) Репутация: ![]() ![]() ![]() |
|
|
|
Obey-Kun |
![]()
Сообщение
#5
|
![]() Студент ![]() Группа: Участник Сообщений: 96 Регистрация: 24.3.2010 Пользователь №: 1556 Спасибо сказали: 3 раз(а) Репутация: ![]() ![]() ![]() |
А через переопределении функции setSelected -- фиг. Почему так? void QGraphicsItem::setSelected ( bool selected ) - не виртуальная функция, ты не можешь её переопределить.Шутите что ли? (При публичном наследовании) переопределять можно любые public и protected функции родительских классов ![]() ![]() |
|
|
igor_bogomolov |
![]()
Сообщение
#6
|
Профессионал ![]() ![]() ![]() ![]() ![]() Группа: Сомодератор Сообщений: 1215 Регистрация: 22.3.2009 Из: Саратов Пользователь №: 630 Спасибо сказали: 235 раз(а) Репутация: ![]() ![]() ![]() |
Шутите что ли? (При публичном наследовании) переопределять можно любые public и protected функции родительских классов Срочно учить матчасть![]() ![]() |
|
|
Litkevich Yuriy |
![]()
Сообщение
#7
|
![]() разработчик РЭА ![]() ![]() ![]() ![]() ![]() ![]() ![]() Группа: Сомодератор Сообщений: 9669 Регистрация: 9.1.2008 Из: Тюмень Пользователь №: 64 Спасибо сказали: 807 раз(а) Репутация: ![]() ![]() ![]() |
переопределять можно любые public и protected функции родительских классов терминологически ты ошибся. Переопределяются только виртуальные функции. Не виртуальные перегружаются.Виртуальные хороши тем, что кто-то может вызвать по указателю на базовый класс функцию конкретного наследника. Скорее всего так и происходит. Т.е. функция не виртуальная, поэтому вызывается функция базового класса, а не наследника |
|
|
Obey-Kun |
![]()
Сообщение
#8
|
![]() Студент ![]() Группа: Участник Сообщений: 96 Регистрация: 24.3.2010 Пользователь №: 1556 Спасибо сказали: 3 раз(а) Репутация: ![]() ![]() ![]() |
переопределять можно любые public и protected функции родительских классов терминологически ты ошибся. Переопределяются только виртуальные функции. Не виртуальные перегружаются.Виртуальные хороши тем, что кто-то может вызвать по указателю на базовый класс функцию конкретного наследника. Скорее всего так и происходит. Т.е. функция не виртуальная, поэтому вызывается функция базового класса, а не наследника Ах вот оно как! Спасибо, хорошую такую дырку вы залатали в моих знаниях. Да, тогда действительно другого метода я не вижу. Нехорошо получается... |
|
|
Obey-Kun |
![]()
Сообщение
#9
|
![]() Студент ![]() Группа: Участник Сообщений: 96 Регистрация: 24.3.2010 Пользователь №: 1556 Спасибо сказали: 3 раз(а) Репутация: ![]() ![]() ![]() |
Вот мне кстати интересно, что быстрее:
или просто
Пока сделал первый способ. И между делом, был замечен ещё один подводный камень. Выделение сценой моего итема (Cell) в итоге приводит к такой последовательности: 1. итем помечается отмеченным 2. айтем перерисовывается, во время перерисовки меняется его z 3. сцена реагирует на изменение z и перерисовывает айтем ещё раз В итоге, если выделяется сразу много моих айтемов, то заметно, как сначала окрашивается "не перекрытая" часть границ, а потом вся остальная. Мне такое поведение не нравится. Да и операций приходится больше совершать. Думается мне, надо в сцене переопределить setSelectionArea и setSelectionRect, там определять, какие айтема попадают в выделение и вызывать для них setZ(1). Ну а в clearSelection вместе со снятием со всех выделения опускать их слоем ниже. При этом код setZValue(isSelected()) из paint у Cell нельзя убирать, так как ещё остаётся setSelected(bool), который может действовать минуя сцену. Как-то так. Но я, наверное, не буду это делать. Может, оно и станет чуть красивее, но ведь медленно всё это... Хотя чёрт знает, может и не медленно. Надо посмотреть. Сцена использует кеш? Ведь если я сделаю, как хочу, то поиск айтемов в одной и той же области будет проводиться дважды. Сообщение отредактировал Obey-Kun - 28.3.2010, 5:24 |
|
|
Litkevich Yuriy |
![]()
Сообщение
#10
|
![]() разработчик РЭА ![]() ![]() ![]() ![]() ![]() ![]() ![]() Группа: Сомодератор Сообщений: 9669 Регистрация: 9.1.2008 Из: Тюмень Пользователь №: 64 Спасибо сказали: 807 раз(а) Репутация: ![]() ![]() ![]() |
|
|
|
![]() ![]() ![]() |
![]() |
|
Текстовая версия | Сейчас: 19.2.2025, 2:19 |