Moving QGraphicsItem by mouse in a QGraphicsScene

谁都会走 提交于 2019-12-11 03:36:09

问题


I have a QGraphicsScene and its associated QGraphicsView. I let the user create some shapes in the form of derived QGraphicsItems into that scene. I also want them to be movable by mouse. Clicking one or more items select them, and moving them around while the mouse button is pressed works. I inherited QGraphicsView to do this, and overrided mousePressedEvent, mouseReleasedEvent & mouseMoveEvent to achieve this. When the user clicks, I am basically testing if an item (accessed through items() which returns the items of the associated scene) is under the mouse with contains(), and if it is then I am selecting it.

In the mouseMoveEvent, I am using setPos() on each item of the selection to move it relatively to the mouse move. It works and displays as expected.

This may not be the most efficient way, but that's what I achieved while discovering Qt. Now, the problem is : once I've moved my item or group of items with the mouse, if I want to deselect them (by clicking again on them), the contains() method supplied with the position of the input acts as if the item wasn't moved. Example : I draw a rectangle in the upper left corner, and move it around to, say, the center of the view. Clicking on it again doesn't work but clicking on where it was initially works. So I suspect it has something to do with local and global coordinates.

I've run through several problems today (most of them resolved) but I'm stuck on this one.

Here's my View class :

class CustomGraphicsView(QGraphicsView):


    def __init__(self, *args):
        super().__init__(*args)

        self.selection = []
        self.offsets = []
        self.select_point = None

    def mousePressEvent(self, event):
        pos = self.mapFromGlobal(event.globalPos())
        modifiers = event.modifiers()

        if event.button() == Qt.LeftButton:
            #do something else

        elif event.button() == Qt.RightButton:
            self.select_point = pos
            for s in self.selection:
                if s.contains(pos): # deselect or drag
                    for s in self.selection: # construct the offsets for dragging
                        self.offsets = [s.pos() - pos for s in self.selection]
                    break

    def mouseReleaseEvent(self, event):
        pos = self.mapFromGlobal(event.globalPos())
        modifiers = event.modifiers()

        if event.button() == Qt.LeftButton:
            #do something else

        elif event.button() == Qt.RightButton:
            if self.select_point == pos: # one click selection
                    self.update_selection(pos)
            if self.offsets:
                self.offsets.clear()

    def mouseMoveEvent(self, event):
        pos = self.mapFromGlobal(event.globalPos())
        modifiers = event.modifiers()

        if event.buttons() == Qt.RightButton:
            if not self.offsets:
                for s in self.selection:
                    self.offsets = [s.pos() - pos for s in self.selection]

            for s, off in zip(self.selection, self.offsets):
                s.set_pos(pos + off)

    def update_selection(self, pos):
        for item in self.items():
            if not item.contains(pos):
                continue
            if item.selected:
                self.selection.remove(item)
            else:
                self.selection.append(item)
            item.select()
            break

The scene rect is set at (0;0) so there's no concern about moving it or whatever.

来源:https://stackoverflow.com/questions/19668164/moving-qgraphicsitem-by-mouse-in-a-qgraphicsscene

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