Selecting several items and then taking distance between them

只愿长相守 提交于 2019-12-08 10:37:49

问题


I am currently having an issue with finding the distance between two items in a QGraphicsScene. I have the distance formula already down but the issue is that when I select two points or items in the graphicsScene it says they are at the same point and since they are at the same point the distance always comes out zero. To select multiple items I use ctrl + click to get two points selected at once and I know the two points are at different areas in the scene. Here is the code:

import sys
from PyQt4 import QtGui, QtCore
import math
#this sets the scene for drawing and the microscope image
class MyView(QtGui.QGraphicsView):
    def __init__(self,window):
        QtGui.QGraphicsView.__init__(self)
        self.window = window
        self.scene = QtGui.QGraphicsScene(self)
        self.item = QtGui.QGraphicsRectItem(400, 400, 400, 400)
        self.scene.addItem(self.item)
        self.setScene(self.scene)
    def paintMarkers(self,event):
        ##self.cursor = QtGui.QCursor()
        #self.cursor.setShape(2)
        p = self.mapToScene(event.x(),event.y())
        if (p.x() > 400 and p.x() < 800) and (p.y() > 400 and p.y() < 800):
            self.circleItem = QtGui.QGraphicsEllipseItem(p.x(),p.y(),5,5)
                   self.circleItem.setFlag(QtGui.QGraphicsItem.ItemIsSelectable,True)
            self.scene.addItem(self.circleItem)
            self.circleItem.setPen(QtGui.QPen(QtCore.Qt.red, 1.5))
        #self.setScene(self.scene)
    def deleteMarkers(self,event):
        p = self.mapToScene(event.x(),event.y())
        if self.scene.itemAt(p.x(),p.y()) != self.item:
            self.scene.removeItem(self.scene.itemAt(p.x(),p.y()))
        #print "Hello world"
    #def mousePressEvent(self,QMouseEvent):
        #self.paintMarkers()
    def mousePressEvent(self,event):
        if self.window.btnPaintDot.isChecked():
            self.paintMarkers(event)
        if self.window.btnDeleteMarks.isChecked():
            self.deleteMarkers(event)
        if self.window.btnPaintLength.isChecked():
            self.distanceFormula(self.scene.selectedItems())
        return QtGui.QGraphicsView.mousePressEvent(self,event)
    def distanceFormula(self,list):
        if len(list) == 2:
            """for i in list:
                p = self.mapToScene(i.x(),i.y())
                print p.x()
                print p.y()"""
            p = self.mapToScene(list[0].x(),list[0].y())
            q = self.mapToScene(list[1].x(),list[1].y())
            print p.x()
            print p.y()
            print q.x()
            print q.y()
            print list[0]
            print list[1]
            print len(list)
            length = math.sqrt((p.x() - q.x())**2 + (p.y() - q.y())**2)
            print length

class Window(QtGui.QMainWindow):
    def __init__(self):
        #This initializes the main window or form
        super(Window,self).__init__()
        self.setGeometry(50,50,1000,1000)
        self.setWindowTitle("Pre-Alignment system")

        self.view = MyView(self)
        self.setCentralWidget(self.view)

self.btnPaintLength = QtGui.QPushButton("Len",self)
        self.btnPaintLength.clicked.connect(self.paintLengthOnImage)
        self.btnPaintLength.setCheckable(True)
        self.btnPaintLength.resize(30,30)
        self.btnPaintLength.move(330,50)
#this creates the paint button allowing user to draw lines or anything on the image from the microscope
        self.btnPaintDot = QtGui.QPushButton("*",self)
        self.btnPaintDot.setCheckable(True)
        self.btnPaintDot.clicked.connect(self.paintDotOnImage)
        self.btnPaintDot.resize(30,30)
        self.btnPaintDot.move(300,50)

#creates the delete marker button
        self.btnDeleteMarks = QtGui.QPushButton("del",self)
        self.btnDeleteMarks.clicked.connect(self.paintDeleteMarks)
        self.btnDeleteMarks.setCheckable(True)
        self.btnDeleteMarks.resize(30,30)
        self.btnDeleteMarks.move(390,50)

    def paintLengthOnImage(self):
            """create length on image"""
            if self.btnPaintLength.isChecked():
                self.btnPaintDot.setChecked(False)
                self.btnPaintPolygon.setChecked(False)
                self.btnDeleteMarks.setChecked(False)
                self.view.distanceFormula(self.view.scene.selectedItems())
            else:
                self.btnPaintLength.setChecked(False)

    def paintDotOnImage(self):
            """create a dot paint button"""
            if self.btnPaintDot.isChecked():
                self.btnPaintDot.setChecked(True)
                self.btnPaintPolygon.setChecked(False)
                self.btnPaintLength.setChecked(False)
                self.btnDeleteMarks.setChecked(False)
            else:
                self.btnPaintDot.setChecked(False)
    def paintDeleteMarks(self):
            if self.btnDeleteMarks.isChecked():
                self.btnPaintDot.setChecked(False)
                self.btnPaintPolygon.setChecked(False)
                self.btnPaintPolygon.setChecked(False)
                self.btnDeleteMarks.setChecked(True)
            else:
                self.btnDeleteMarks.setChecked(False)
def run():
    app = QtGui.QApplication(sys.argv)
    GUI = Window()
    GUI.show()
    sys.exit(app.exec_())

run()

The print statements were just there for my purpose of finding where the issue was. Much thanks!


回答1:


It looks like this happens because of the way the items were created. Items are always created at (0,0). When you specify the (x,y,width,height) when you construct the item, you actually create an items which extends from (0,0) to (x+width, y+height). You can verify this by looking at the size of the items boundingRect().

Instead, you should construct the object at (0,0) and move it to the correct location. With you current code, this means doing the following when you create the item:

self.circleItem = QtGui.QGraphicsEllipseItem(0,0,5,5)
self.circleItem.setPos(p.x()-self.circleItem.boundingRect().width()/2.0,p.y()-self.circleItem.boundingRect().height()/2.0)

Note, here I offset the position by half of the width/height so that the items is centred on the mouse click. You may or may not want this.



来源:https://stackoverflow.com/questions/30980895/selecting-several-items-and-then-taking-distance-between-them

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!