python - 如何使用 PyQt5 获取像素位置并在该位置上绘制一个点?
问题描述
from PyQt5 import QtCore, QtGui, QtWidgets
class Window(QtWidgets.QWidget):
def __init__(self):
QtWidgets.QWidget.__init__(self)
layout = QtWidgets.QGridLayout(self)
self.getImageButton = QtWidgets.QPushButton('Select')
layout.addWidget(self.getImageButton)
self.getImageButton.clicked.connect(self.resimac)
self.resim1 = QtWidgets.QLabel()
layout.addWidget(self.resim1)
self.resim1.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignVCenter)
# I'm assuming the following...
self.resim1.setScaledContents(True)
self.resim1.setFixedSize(701,451)
# install an event filter to "capture" mouse events (amongst others)
self.resim1.installEventFilter(self)
def resimac(self):
filename, filter = QtWidgets.QFileDialog.getOpenFileName(None, 'Resim Yükle', '.', 'Image Files (*.png *.jpg *.jpeg *.bmp *.tif)')
if not filename:
return
self.resim1.setPixmap(QtGui.QPixmap(filename))
def eventFilter(self, source, event):
# if the source is our QLabel, it has a valid pixmap, and the event is
# a left click, proceed in trying to get the event position
if (source == self.resim1 and source.pixmap() and not source.pixmap().isNull() and
event.type() == QtCore.QEvent.MouseButtonPress and
event.button() == QtCore.Qt.LeftButton):
self.getClickedPosition(event.pos())
return super().eventFilter(source, event)
def getClickedPosition(self, pos):
# consider the widget contents margins
contentsRect = QtCore.QRectF(self.resim1.contentsRect())
if pos not in contentsRect:
# outside widget margins, ignore!
return
# adjust the position to the contents margins
pos -= contentsRect.topLeft()
pixmapRect = self.resim1.pixmap().rect()
if self.resim1.hasScaledContents():
x = pos.x() * pixmapRect.width() / contentsRect.width()
y = pos.y() * pixmapRect.height() / contentsRect.height()
pos = QtCore.QPoint(x, y)
else:
align = self.resim1.alignment()
# for historical reasons, QRect (which is based on integer values),
# returns right() as (left+width-1) and bottom as (top+height-1),
# and so their opposite functions set/moveRight and set/moveBottom
# take that into consideration; using a QRectF can prevent that; see:
# https://doc.qt.io/qt-5/qrect.html#right
# https://doc.qt.io/qt-5/qrect.html#bottom
pixmapRect = QtCore.QRectF(pixmapRect)
# the pixmap is not left aligned, align it correctly
if align & QtCore.Qt.AlignRight:
pixmapRect.moveRight(contentsRect.x() + contentsRect.width())
elif align & QtCore.Qt.AlignHCenter:
pixmapRect.moveLeft(contentsRect.center().x() - pixmapRect.width() / 2)
# the pixmap is not top aligned (note that the default for QLabel is
# Qt.AlignVCenter, the vertical center)
if align & QtCore.Qt.AlignBottom:
pixmapRect.moveBottom(contentsRect.y() + contentsRect.height())
elif align & QtCore.Qt.AlignVCenter:
pixmapRect.moveTop(contentsRect.center().y() - pixmapRect.height() / 2)
if not pos in pixmapRect:
# outside image margins, ignore!
return
# translate coordinates to the image position and convert it back to
# a QPoint, which is integer based
pos = (pos - pixmapRect.topLeft()).toPoint()
print('X={}, Y={}'.format(pos.x(), pos.y()))
if __name__ == '__main__':
import sys
app = QtWidgets.QApplication(sys.argv)
w = Window()
w.show()
sys.exit(app.exec_())
这是别人的示例代码。我设法使用上面的代码获取像素位置,但是如何在每次点击时在图像的点击位置上放置一个点?此外,当我单击图像的另一部分时,我希望点出现在新的单击位置并从最后单击的位置删除。
解决方案
逻辑是存储原始的QPixmap,复制它,用QPainter画点并设置在QLabel中:
class Window(QtWidgets.QWidget):
def __init__(self):
QtWidgets.QWidget.__init__(self)
self.pixmap = QtGui.QPixmap()
# ...
def resimac(self):
filename, filter = QtWidgets.QFileDialog.getOpenFileName(
None, "Resim Yükle", ".", "Image Files (*.png *.jpg *.jpeg *.bmp *.tif)"
)
if not filename:
return
self.pixmap = QtGui.QPixmap(filename)
self.resim1.setPixmap(self.pixmap.copy())
# ...
def getClickedPosition(self, pos):
# ...
pos = (pos - pixmapRect.topLeft()).toPoint()
pixmap = self.pixmap.copy()
painter = QtGui.QPainter(pixmap)
painter.drawPoint(pos)
painter.end()
self.resim1.setPixmap(pixmap)
print("X={}, Y={}".format(pos.x(), pos.y()))
pixmap = self.pixmap.copy()
painter = QtGui.QPainter(pixmap)
painter.setRenderHint(QtGui.QPainter.Antialiasing)
painter.setBrush(QtGui.QColor("black"))
length = 10
rect = QtCore.QRect(0, 0, length, length)
rect.moveCenter(pos)
painter.drawEllipse(rect)
painter.end()
self.resim1.setPixmap(pixmap)
推荐阅读
- python - TypeError:使用字典替换数据框时,字符串索引必须是整数熊猫
- emoji - 这些图像/表情符号是什么意思?
- javascript - 如何在聚合/查找查询中填充深层?
- r - R中的TukeyHSD函数不完全错误并且不确定如何修复它
- c# - 如何在 xamarin 表单的集合视图中的最后一项旁边添加图像/按钮?
- reactjs - 在滑块中添加指向按钮的链接
- visual-studio - CMake 是否可以选择控制生成的可执行文件
- python - RTL2832U:在 Windows 上使用 GNC 构建 FM 接收器
- vba - 通过数组将日期格式化为年份
- javascript - 我如何修复 onBindViewHolder 在 nativescript 中失败