选择几个项目然后在它们之间取得距离

时间:2015-06-22 13:12:41

标签: python pyqt4 qgraphicsscene

我目前在查找QGraphicsScene中两个项目之间的距离时遇到问题。我的距离公式已经下降,但问题是当我在graphicsScene中选择两个点或项时,它表示它们处于同一点,因为它们处于同一点,所以距离总是为零。要选择多个项目,我使用ctrl +单击一次选择两个点,我知道这两个点位于场景的不同区域。这是代码:

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()

印刷声明只是为了找到问题所在。非常感谢!

1 个答案:

答案 0 :(得分:0)

看起来这是因为项目的创建方式。项目始终在(0,0)创建。在构造项目时指定(x,y,width,height)时,实际上创建的项目从(0,0)延伸到(x+width, y+height)。您可以通过查看项boundingRect()的大小来验证这一点。

相反,您应该在(0,0)构建对象并将其移动到正确的位置。使用当前代码,这意味着在创建项目时执行以下操作:

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)

注意,这里我将位置偏移宽度/高度的一半,以便项目以鼠标单击为中心。你可能想要也可能不想要这个。