选择几个项目,然后在它们之间拉开距离 [英] Selecting several items and then taking distance between them

查看:52
本文介绍了选择几个项目,然后在它们之间拉开距离的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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!

推荐答案

看起来发生这种情况的原因是项目的创建方式.项目总是在 (0,0) 处创建.当您在构造项目时指定 (x,y,width,height) 时,您实际上创建了一个从 (0,0) 扩展到 的项目(x+宽,y+高).您可以通过查看项目的大小来验证这一点 boundingRect().

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

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

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.

这篇关于选择几个项目,然后在它们之间拉开距离的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆