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