【问题标题】:Python PyQt: How can I move my widgets on the window with mouse?Python PyQt:如何用鼠标在窗口上移动我的小部件?
【发布时间】:2017-02-17 05:23:52
【问题描述】:

我是 Python 新手。我用固定坐标绘制了多边形和圆。现在我想使用鼠标将这个多边形和圆圈移动到窗口上的其他位置。请指导我该怎么做?

import sys
from PyQt4.QtGui import *
from PyQt4.QtCore import *

class MyFrame(QWidget):
    def __init__(self, parent=None):
            QWidget.__init__(self)

    def paintEvent(self, event=None):
            paint=QPainter(self)
            paint.setPen(QPen(QColor(Qt.green).dark(150),1,Qt.SolidLine))
            segColor=QColor(Qt.green).dark(150)
            paint.setBrush(segColor)
            paint.setBrushOrigin(QPoint(225,225))
            polygon=QPolygon([QPoint(250,175), QPoint(265,175), QPoint(250,190), QPoint(265,190),QPoint(250,175)])
            paint.drawPolygon(polygon)
            paint.setPen(QPen(QColor(Qt.red),1,Qt.SolidLine))
            paint.setBrush(QBrush(Qt.NoBrush))
            polygon1=QPolygon([QPoint(250,300), QPoint(250,500), QPoint(350,500), QPoint(350,300)])
            paint.drawPolyline(polygon1)
            paint.drawEllipse(50,50,50,50)


app=QApplication(sys.argv)
f=MyFrame()
f.show()
app.exec_()

【问题讨论】:

    标签: python pyqt4


    【解决方案1】:

    你应该查看 QGraphicsView 而不是你在做什么,它已经内置了这一切。

    http://doc.qt.nokia.com/4.7-snapshot/qgraphicsview.html

    http://doc.qt.nokia.com/4.7-snapshot/qgraphicsscene.html

    from PyQt4 import QtGui, QtCore
    
    class MyFrame(QtGui.QGraphicsView):
        def __init__( self, parent = None ):
            super(MyFrame, self).__init__(parent)
    
            self.setScene(QtGui.QGraphicsScene())
    
            # add some items
            x = 0
            y = 0
            w = 45
            h = 45
            pen = QtGui.QPen(QtGui.QColor(QtCore.Qt.green))
            brush = QtGui.QBrush(pen.color().darker(150))
    
            item = self.scene().addEllipse(x, y, w, h, pen, brush)
            item.setFlag(QtGui.QGraphicsItem.ItemIsMovable)
    
    if ( __name__ == '__main__' ):
        app = QtGui.QApplication([])
        f = MyFrame()
        f.show()
        app.exec_()
    

    编辑:展示如何创建 QPainterPath

    from PyQt4 import QtGui, QtCore
    
    class MyFrame(QtGui.QGraphicsView):
        def __init__( self, parent = None ):
            super(MyFrame, self).__init__(parent)
    
            scene = QtGui.QGraphicsScene()
            self.setScene(scene)
    
            # add some items
            x = 0
            y = 0
            w = 45
            h = 45
            pen   = QtGui.QPen(QtGui.QColor(QtCore.Qt.green))
            brush = QtGui.QBrush(pen.color().darker(150))
    
            item = scene.addEllipse(x, y, w, h, pen, brush)
            item.setFlag(QtGui.QGraphicsItem.ItemIsMovable)
    
            # create an open path
            path = QtGui.QPainterPath()
            path.moveTo(-w, -h)
            path.lineTo(-w, h)
            path.lineTo(w, h)
            path.lineTo(w, -h)
    
            clr   = QtGui.QColor('blue')
            clr.setAlpha(120)
            brush = QtGui.QBrush(clr)
            pen   = QtGui.QPen(QtCore.Qt.NoPen)
            fill_item = scene.addRect(-w, y, w*2, h, pen, brush)
            path_item = scene.addPath(path)
    
    if ( __name__ == '__main__' ):
        app = QtGui.QApplication([])
        f = MyFrame()
        f.show()
        app.exec_()
    

    【讨论】:

    • 感谢 Eric 的宝贵回复,但这解决了我的部分问题。实际上我想画一个水箱,我觉得会用折线画,因为我需要三个边而不是顶部。并且“QGraphicsScene”对象没有“addPolyline”属性。其次,我想根据我的价值来装满油箱。我怎样才能给水箱加水(让我们看看蓝色)?
    • 您可以控制场景中的对象——它们不必是简单的形状对象。我将从查看 QGraphicsPathItem 开始,它允许您定义要绘制的任何 QPainterPath,并支持填充。对于比这更复杂的项目,您可以将任何让您关闭的 QGraphicsItem 子类化并实现您自己的 paintEvent 方法
    • 顺便说一句,添加路径的快捷方式是 QGraphicsScene.addPath
    • Eric 我已尝试遵循您的建议,但无法在 QGraphicsScene 中添加使用 PainterPath 编写的折线代码。请您发送一些小代码来添加它。其次,如何保存小部件的位置,因为当我关闭窗口时,所有小部件都会回到它们的初始位置(我想保存小部件的新位置)?
    • 我用一个示例更新了代码,说明如何像您一样创建 QPainterPath。至于保存位置,您需要将它们记录到某处的设置中-您可以通过执行 scene.items() 循环遍历对象并通过执行 item.pos() 获取每个项目的位置
    【解决方案2】:

    受 Eric 的回答启发,这里有一些代码通过更新点的 x 和 y 坐标来为点设置动画。

    
    from PyQt5.QtGui  import QPen, QBrush, QColor
    from PyQt5.QtCore import Qt, QTimer
    from PyQt5.QtWidgets import QGraphicsView, QGraphicsScene, QGraphicsItem, QApplication
    
    class GameWindow(QGraphicsView):
        def __init__( self, parent = None ):
            super().__init__(parent)
    
            self.sx = 635
            self.sy = 475
    
            scene = QGraphicsScene(0,0,self.sx,self.sy)
            self.setScene(scene)
    
            self.x = 0
            self.y = 0
            self.w = 30
            self.h = 30
            pen   = QPen(QColor('dodgerblue'))
            #pen   = QPen(QColor(Qt.green))
            brush = QBrush(pen.color())
            #brush = QBrush(pen.color().darker(150))
    
            # As opposed to using QPen and QBrush, this colors the periphery only
            #dot = scene.addEllipse(self.x, self.y, self.w, self.h, QColor('dodgerblue')) 
    
            self.dot = scene.addEllipse(self.x, self.y, self.w, self.h, pen, brush)
            self.dot.setFlag(QGraphicsItem.ItemIsMovable)
    
    
    if  __name__ == '__main__':
        import sys
    
        fps = 50
        refresh_period = 1000/fps # ms
    
        app = QApplication(sys.argv)
    
        gw = GameWindow()
        gw.resize(640,480)
        gw.show()
    
    
        # if the steps match the gw aspect ratio, the dot will move along the main diagonal,
        # otherwise the dot will drift
        xstep = 4
        ystep = 3
        #ystep = xstep * gw.sy / gw.sx
    
        def moveDot():
           # In place of the next four lines, one can have a function 
           # or a feed from an external source to update gw.x and gw.y
           gw.x += xstep
           gw.x %= gw.sx
    
           gw.y += ystep
           gw.y %= gw.sy
    
           gw.dot.setRect(gw.x,gw.y,gw.w,gw.h)
    
        timer = QTimer()
        timer.timeout.connect(moveDot)
    
        # Comment this line out to be able to click and drag the dot
        timer.start(refresh_period)
    
        sys.exit(app.exec_())
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-01-13
      • 2011-11-17
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多