Как интерактивно рисовать точки на Pixmap, который находится на QLabel в PyQT - PullRequest
2 голосов
/ 03 июня 2011

Я строю небольшой графический интерфейс, и у меня есть QLabel, который рисует изображения из каталога на себя, устанавливая их как растровое изображение.Я хочу, чтобы пользователь мог интерактивно нажимать на точки на этом растровом изображении, и чтобы в выбранных местах отображался маленький зеленый крестик.Я попытался повторно реализовать метод paintEvent, но это не та функциональность, которая мне нужна.paintEvent - это то, что вызывается каждый раз, когда есть причина рисовать на QLabel ... тогда как я хочу оставить базовый чертеж (изображение) в покое и просто поместить точки поверх уже нарисованного изображения.В конце концов, я хочу, чтобы пользователь мог интерактивно отслеживать эти точки с помощью последовательности изображений, используя сторонние алгоритмы отслеживания.Таким образом, мне нужна возможность, чтобы пользователь перемещал точки вокруг, удалял точки, добавлял точки и изменял их без необходимости перерисовывать изображение позади них.В Интернете есть несколько учебных пособий по простому рисованию точек, но все они включают повторную реализацию метода paintEvent и затем подключение mouseEvent к paintEvent.Я пытаюсь специально избегать этого.Есть предложения?

1 Ответ

3 голосов
/ 03 июня 2011

Вы действительно хотите использовать paintEvent() переопределение.Даже если вы хотите рисовать объекты только над изображением, виджет все же должен иметь возможность перерисовывать части изображения, если вы удаляете или перемещаете объекты, которые нарисованы поверх него, и это происходит в paintEvent().Если вы хотите добавить что-то в рендеринг, вам нужно это сделать тоже.

Думайте о paintEvent() как draw-the-entire-part-of-the-widget-that's-visible-Event().Если вы используете подкласс QLabel, то ваше переопределение должно вызвать QLabel::paintEvent(e), а затем ваши вещи.

Похоже, вы будете вести список точек, поэтому ваша часть paintEvent() должнаНарисуйте все свои точки так, как вам нужно.

Ваши события мыши должны что-то сделать с вашим списком точек (например, добавить точку или переместить точку), а затем вызвать update(), что вызовет вызовpaintEvent(), который перерисовает весь виджет с фоновым изображением и вашими обновленными точками.Не должно быть никакого подключения событий мыши к paintEvent() или возни с попытками отследить или обработать события мыши внутри paintEvent().

Главное, что нужно помнить, это то, что события мыши изменят вашу «модель» иpaintEvent() будет рисовать всю модель всякий раз, когда она изменяется.Даже если существовала абстракция / функция, которая требовала от вас только рисования новых вещей или вещей, которые изменились, под обложками все еще нужно стереть и перерисовать.

Это можно оптимизировать, используяинформация о регионе в объекте события передается в paintEvent(), но обычно это не требуется.

Вы можете посмотреть на несколько похожий пример в ответе на другой вопрос , который я предоставил, хотяэто может не сильно отличаться от других примеров, которые вы уже видели.К сожалению, это не в Python.

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

...