Как интерактивно рисовать точки на Pixmap, который находится на QLabel в PyQT

1

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

Теги:
qt
pyqt
qpixmap

1 ответ

3
Лучший ответ

Фактически вы хотите использовать переопределение 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.

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

  • 0
    Несколько вопросов, так как я новичок в этом: (1) Когда вы говорите «вызов обновления», это то, что mouseEvent, как внутри mousePressEvent (self, event), я могу вызвать event.update (или это self.update)? (2) Я сейчас излучаю свой собственный сигнал, СИГНАЛ («левый клик»), с (x, y) положением мыши в качестве переданных аргументов. Как получить paintEvent для ответа на этот пользовательский сигнал, или это не обязательно.
  • 0
    В вашем слоте для сигнала щелчка, который, как я предполагаю, будет слотом в вашем подклассе QLable, вы внесете какое-то изменение в свой список точек (который должен быть сохранен в переменной-члене) на основе x, y информация, а затем просто позвоните update (); Просто так. Затем внутри переопределения paintEvent () вы будете использовать переменную member для точек, чтобы решить, где рисовать объекты. Вызов update () инициирует перерисовку виджета, который включает в себя вызов paintEvent ().
Показать ещё 3 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню