我正在构建一个小型 GUI 界面,并且我有一个 QLabel,它通过将图像设置为像素图来将图像从目录中绘制到自身上。我希望用户能够以交互方式单击此像素图上的点,并在单击的位置出现一个小的绿色“x”。我尝试过重新实现paintEvent 方法,但这根本不是我想要的功能。每当有理由在 QLabel 上绘画时,paintEvent 都会被调用......而我想单独留下基本图形(图像),只需将点放在已经绘制的图像之上。最终,我希望用户能够使用第三方跟踪算法,通过一系列图像交互式地跟踪这些点。因此,我需要让用户移动点、删除点、添加点的能力,并修改它们而不需要重新绘制它们背后的图像。网上有几个关于简单画点的教程,但都涉及重新实现paintEvent方法,然后将mouseEvent连接到paintEvent。我正在努力避免这种情况。有什么建议么?
1 回答
您实际上确实想使用paintEvent()
覆盖。即使您确实只想在图像上绘制东西,如果您删除或移动在图像上绘制的东西并且这发生在paintEvent()
. 如果你想在渲染中添加东西,那你也必须这样做。
想想paintEvent()
as draw-the-entire-part-of-the-widget-that's-visible-Event()
。如果您使用的是 的子类QLabel
,那么您的覆盖应该调用QLabel::paintEvent(e)
,然后是您的东西。
听起来您将维护一个点列表,因此您的部分paintEvent()
应该以您需要的方式绘制所有点。
您的鼠标事件应该对您的点列表执行某些操作(例如添加一个点或移动一个点),然后调用update()
这将触发一个调用,paintEvent()
该调用将使用背景图像和更新的点重绘整个小部件。不应将鼠标事件连接到paintEvent()
或试图跟踪或处理内部的鼠标事件paintEvent()
。
要记住的主要事情是鼠标事件将修改您的“模型”,并且paintEvent()
无论何时更改都会绘制整个模型。即使有一个抽象/功能只需要您绘制新事物或改变的事物,在幕后,仍然需要擦除和重绘很多东西。
这可以通过使用传入的事件对象中的区域信息来优化,paintEvent()
但这通常不是必需的。
您可以在我提供的另一个问题的答案中查看一个有点相似的示例,尽管它可能与您已经看到的其他示例没有太大不同。不幸的是,它不在 Python 中。
您可以对内存中的图像进行所有渲染,然后只更新标签显示的图像,但paintEvent()
覆盖是更好的选择。