Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/logging/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何使用PySide2使我的选择框正确移动?_Python_Pyside2 - Fatal编程技术网

Python 如何使用PySide2使我的选择框正确移动?

Python 如何使用PySide2使我的选择框正确移动?,python,pyside2,Python,Pyside2,我正在使用maya GUI,并使用QRubberBand创建了一个拖动选择框。现在我试着在按住Alt键时移动它。 问题是当我移动QRubberBand时,它从原点开始移动 盒子的另一端,像现在这样 我想做的是让它从盒子的端点移动,就像预期的行为一样 代码如下: from PySide2 import QtCore, QtGui, QtWidgets class Ui_Form(QtWidgets.QWidget): def __init__(self): supe

我正在使用maya GUI,并使用QRubberBand创建了一个拖动选择框。现在我试着在按住Alt键时移动它。 问题是当我移动QRubberBand时,它从原点开始移动 盒子的另一端,像现在这样

我想做的是让它从盒子的端点移动,就像预期的行为一样

代码如下:

from PySide2 import QtCore, QtGui, QtWidgets


class Ui_Form(QtWidgets.QWidget):
    def __init__(self):
        super(Ui_Form, self).__init__()
        self.rubberBand = QtWidgets.QRubberBand(QtWidgets.QRubberBand.Rectangle, self)
        self.setupUi(self)

    def mousePressEvent(self, event):        
        if event.button() == QtCore.Qt.LeftButton:
            if event.modifiers() == QtCore.Qt.ShiftModifier:
                print 'shift is selected'
            elif event.modifiers() == QtCore.Qt.CTRL:
                print 'Ctrl is selected'
            else:
                print 'Reseting selection'

            self.origin = event.pos()           
            self.drag_selection = QtCore.QRect(self.origin, QtCore.QSize())
            self.rubberBand.setGeometry(self.drag_selection)
            self.rubberBand.show()

    def mouseMoveEvent(self, event):
        if event.modifiers() == QtCore.Qt.AltModifier:
            self.rubberBand.move(event.pos())
            self.origin = self.rubberBand.pos()
        else:
            self.drag_selection = QtCore.QRect(self.origin, event.pos()).normalized()
            self.rubberBand.setGeometry(self.drag_selection)

    def mouseReleaseEvent(self, event):
        if event.button() == QtCore.Qt.LeftButton:
            self.rubberBand.hide() 
            if event.modifiers() == QtCore.Qt.CTRL:
                print 'Removing from selection'                
            else:
                print 'Selecting'

为此,您需要创建一个偏移

以下是方法(为了实现您的期望):

我用鼠标x、鼠标y、橡皮筋w、橡皮筋h来分解这个过程,以简化理解,但你可以重构它

编辑:多亏了这个评论,我意识到我误解了这个问题。实际上,此解决方案仅适用于向右下角拖动(如第二张图片)。
我认为,为了实现这一点,您只需要比较鼠标位置和橡皮筋,以便在结果中创建偏移。

这比看起来更复杂,因为您不能简单地将橡皮筋的位置设置为光标,因为它会弹出,而不是像预期的那样平移

因此,我选择使用橡皮筋的几何结构,因为无论用户往哪个方向拖动,橡皮筋都更加一致。这个想法是当用户按下alt键时,我们保存鼠标的当前位置,以便在鼠标移动时计算出一个增量。有了这个三角形,我们可以移动几何体并设置它,而不需要任何弹出窗口。用户也可能反复按下并释放alt来调整橡皮筋的大小、移动橡皮筋、调整橡皮筋的大小、移动橡皮筋等等。。所以我们必须考虑到这一点,否则它会爆炸

这里有一个完整的例子,似乎是有效的。希望这些评论能让我们更容易遵循以下逻辑:

from PySide2 import QtCore, QtGui, QtWidgets


class Ui_Form(QtWidgets.QWidget):

    def __init__(self):
        super(Ui_Form, self).__init__()
        self.rubberBand = QtWidgets.QRubberBand(QtWidgets.QRubberBand.Rectangle, self)

        # Create variables that will be handling the moving logic.
        self.sourceGeo = None
        self.altPoint = None
        self.delta = None

    def mousePressEvent(self, event):        
        if event.button() == QtCore.Qt.LeftButton:
            self.origin = event.pos()
            self.drag_selection = QtCore.QRect(self.origin, QtCore.QSize())
            self.rubberBand.setGeometry(self.drag_selection)
            self.rubberBand.show()

    # Must implement this event to detect when alt gets released
    def keyReleaseEvent(self, event):
        if event.key() == QtCore.Qt.Key_Alt:
            if self.delta is not None:
                # This is important: Add delta to origin so that it shifts it over.
                # This is needed if the user repeatedly pressed alt to move it, otherwise it would pop.
                self.origin += self.delta

                # Reset the rest of the variables.
                self.sourceGeo = None
                self.altPoint = None
                self.delta = None

    def mouseMoveEvent(self, event):
        if event.modifiers() == QtCore.Qt.AltModifier:
            # Get the point where alt is pressed and the selection's current geometry.
            if self.altPoint is None:
                self.sourceGeo = self.rubberBand.geometry()
                self.altPoint = event.pos()

            self.delta = event.pos() - self.altPoint  # Calculate difference from the point alt was pressed to where the cursor is now.
            newGeo = QtCore.QRect(self.sourceGeo)  # Create a copy
            newGeo.moveTopLeft(self.sourceGeo.topLeft() + self.delta)  # Apply the delta onto the geometry to move it.
            self.rubberBand.setGeometry(newGeo)  # Move the selection!
        else:
            self.drag_selection = QtCore.QRect(self.origin, event.pos()).normalized()
            self.rubberBand.setGeometry(self.drag_selection)

    def mouseReleaseEvent(self, event):
        if event.button() == QtCore.Qt.LeftButton:
            self.rubberBand.hide() 


inst = Ui_Form()
inst.show()

恐怕此解决方案仅在向右下角拖动时有效。尝试在不同方向创建一个选择,注意当使用alt.@GreenCell移动时,它会弹出。你可以带上你的LIGHTS来帮助我们,或者提出另一个解决方案?“@GreenCell,而不是提供课程”-希望你没有真的生气我只是说这个解决方案有一些疏忽。我发布了一个有效的答案,尽管我觉得会有更好的方法来优化它。谢谢!这正是我需要的!:P
from PySide2 import QtCore, QtGui, QtWidgets


class Ui_Form(QtWidgets.QWidget):

    def __init__(self):
        super(Ui_Form, self).__init__()
        self.rubberBand = QtWidgets.QRubberBand(QtWidgets.QRubberBand.Rectangle, self)

        # Create variables that will be handling the moving logic.
        self.sourceGeo = None
        self.altPoint = None
        self.delta = None

    def mousePressEvent(self, event):        
        if event.button() == QtCore.Qt.LeftButton:
            self.origin = event.pos()
            self.drag_selection = QtCore.QRect(self.origin, QtCore.QSize())
            self.rubberBand.setGeometry(self.drag_selection)
            self.rubberBand.show()

    # Must implement this event to detect when alt gets released
    def keyReleaseEvent(self, event):
        if event.key() == QtCore.Qt.Key_Alt:
            if self.delta is not None:
                # This is important: Add delta to origin so that it shifts it over.
                # This is needed if the user repeatedly pressed alt to move it, otherwise it would pop.
                self.origin += self.delta

                # Reset the rest of the variables.
                self.sourceGeo = None
                self.altPoint = None
                self.delta = None

    def mouseMoveEvent(self, event):
        if event.modifiers() == QtCore.Qt.AltModifier:
            # Get the point where alt is pressed and the selection's current geometry.
            if self.altPoint is None:
                self.sourceGeo = self.rubberBand.geometry()
                self.altPoint = event.pos()

            self.delta = event.pos() - self.altPoint  # Calculate difference from the point alt was pressed to where the cursor is now.
            newGeo = QtCore.QRect(self.sourceGeo)  # Create a copy
            newGeo.moveTopLeft(self.sourceGeo.topLeft() + self.delta)  # Apply the delta onto the geometry to move it.
            self.rubberBand.setGeometry(newGeo)  # Move the selection!
        else:
            self.drag_selection = QtCore.QRect(self.origin, event.pos()).normalized()
            self.rubberBand.setGeometry(self.drag_selection)

    def mouseReleaseEvent(self, event):
        if event.button() == QtCore.Qt.LeftButton:
            self.rubberBand.hide() 


inst = Ui_Form()
inst.show()