我举一个小应用程序的例子。它显示您要在其上绘制形状的图像。如果你不放大图像,那么一切都很好。但是当图像被放大时,图形被放置在错误的位置。
在此示例中,单击图像会放置一个点。如果您不更改缩放比例,那么一切正常。如果放大,则该点不会放置在鼠标光标所在的位置,而是更远。无法弄清楚如何解决这个问题。我还附上了一张 512x512 的图片。比例随鼠标滚轮而变化。
UI_test.py
from PySide2 import QtCore, QtGui, QtWidgets
from PySide2.QtCore import Qt
from random import randint
class Ui_Form(object):
def setupUi(self, Form):
Form.resize(1300, 700)
self.layout = QtWidgets.QHBoxLayout()
self.layout.setContentsMargins(0, 0, 0, 0)
self.listWidget = QtWidgets.QListWidget()
self.layout.addWidget(self.listWidget)
self.stackedWidget = QtWidgets.QStackedWidget()
self.layout.addWidget(self.stackedWidget)
self.listWidget.currentRowChanged.connect(
self.stackedWidget.setCurrentIndex)
item1 = QtWidgets.QListWidgetItem(QtGui.QIcon('icons/settings.png'),'CamSettings', self.listWidget)
item2 = QtWidgets.QListWidgetItem(QtGui.QIcon('icons/explore.png'),'Explore', self.listWidget)
item1.setSizeHint(QtCore.QSize(10, 60))
item2.setSizeHint(QtCore.QSize(10, 60))
item1.setTextAlignment(QtCore.Qt.AlignCenter)
item2.setTextAlignment(QtCore.Qt.AlignCenter)
label1 = QtWidgets.QLabel('Это страница 1')
label2= QtWidgets.QLabel('Это страница 2')
label1.setAlignment(QtCore.Qt.AlignCenter)
label2.setAlignment(QtCore.Qt.AlignCenter)
label1.setStyleSheet('background: rgb(%d, %d, %d); margin: 50px;' % (
randint(0, 255), randint(0, 255), randint(0, 255)))
label2.setStyleSheet('background: rgb(%d, %d, %d); margin: 50px;' % (
randint(0, 255), randint(0, 255), randint(0, 255)))
self.img_rgb = QtWidgets.QGraphicsScene()
self.view_rgb = QtWidgets.QGraphicsView()
self.view_rgb.setScene(self.img_rgb )
pixmap_rgb = QtGui.QPixmap()
self.img_rgb.addPixmap('pic.png')
border_style_rgb = f'border-style: solid; border-width: 2px; background-color:#757575;'
self.view_rgb.setStyleSheet(border_style_rgb)
self.view_rgb.setFixedSize(520,520)
self.view_rgb.mousePressEvent = Form.press_event
#self.view_rgb.mouseMoveEvent = Form.move_event
#self.view_rgb.mouseReleaseEvent = Form.release_event
self.view_rgb.wheelEvent = Form.wheel_event
first_panel_left = QtWidgets.QVBoxLayout()
first_panel_left.setAlignment(Qt.AlignTop)
first_panel_frame_left = QtWidgets.QFrame()
first_panel_frame_left.setMinimumWidth(200)
first_panel_frame_left.setLayout(first_panel_left)
first_panel_right = QtWidgets.QVBoxLayout()
first_panel_right.addWidget(self.view_rgb)
first_panel_right.addStretch()
first_panel_frame_right = QtWidgets.QFrame()
first_panel_frame_right.setLayout(first_panel_right)
main_first_box = QtWidgets.QHBoxLayout()
main_first_box.addWidget(first_panel_frame_left)
main_first_box.addWidget(first_panel_frame_right)
first_container = QtWidgets.QWidget()
first_container.setLayout(main_first_box)
self.stackedWidget.addWidget(first_container)
self.stackedWidget.addWidget(label2)
Form.setLayout(self.layout)
应用程序.py
import sys
from PySide2 import QtWidgets
from UI_test import Ui_Form
from PySide2 import QtWidgets, QtGui, QtCore
from tools import DotPainter
class App(QtWidgets.QWidget):
def __init__(self, parent = None):
QtWidgets.QWidget.__init__(self, parent)
self.ui = Ui_Form()
self.ui.setupUi(self)
self._zoom = 0
def press_event(self, event):
self.clickPos = event.pos()
self.clickBtn= event.button()
print(self.clickPos)
if self.clickBtn & QtCore.Qt.LeftButton:
self.pointItem=DotPainter(self.ui.img_rgb,self.clickPos)
def fitInView(self):
rect = QtCore.QRectF(0.0, 0.0, 512.0, 512.0)
if not rect.isNull():
self.ui.view_rgb.setSceneRect(rect)
unity = self.ui.view_rgb.transform().mapRect(QtCore.QRectF(0, 0, 1, 1))
self.ui.view_rgb.scale(1 / unity.width(), 1 / unity.height())
viewrect = self.ui.view_rgb.viewport().rect()
scenerect = self.ui.view_rgb.transform().mapRect(rect)
factor = min(viewrect.width() / scenerect.width(),
viewrect.height() / scenerect.height())
self.ui.view_rgb.scale(factor, factor)
self._zoom = 0
def wheel_event(self,event):
if event.angleDelta().y() > 0:
factor = 1.25
self._zoom += 1
else:
factor = 0.8
self._zoom -= 1
if self._zoom > 0:
self.ui.view_rgb.scale(factor, factor)
elif self._zoom == 0:
self.fitInView()
else:
self._zoom = 0
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
window = App()
window.show()
sys.exit(app.exec_())
工具.py
from PySide2.QtCore import Qt,QRectF,QPointF,QSizeF
from PySide2.QtGui import QPen,QColor,QBrush,QPolygonF
from PySide2 import QtWidgets, QtGui, QtCore
class DotPainter(object):
#класс для рисования точки
def __init__(self, canvas, start):
self.start = start
self.canvas = canvas
self.point=QRectF()
self.width = self.point.width()
self.height = self.point.height()
self.PointF = QPointF(float(start.x()), float(start.y()))
self.point.setTopLeft(self.PointF)
self.point.setSize(QSizeF(8, 8))
self.linePen = QPen(QtGui.QColor(255,0,0), 2)
self.areaBrush = QBrush(QColor(255,0,0))
self.pointItem=self.canvas.addRect(self.point,
self.linePen,self.areaBrush)
def mouseReleaseEvent(self, event):
#функция события мыши для получения размеров точки
self.width = self.point.width()
self.height = self.point.height()

您需要将点击位置转换为场景位置
或将点击处理程序绑定到场景本身(不是视图)并通过方法检索位置
scenePos(此处理程序接收QGraphicsSceneMouseEvent类型的事件)