pythonpyqt:如何用鼠标移动窗口上的小部件?
我是Python新手。我用固定坐标画了多边形和圆。现在我想用鼠标将这个多边形和圆移动到窗口上的其他位置。请指导我怎么做pythonpyqt:如何用鼠标移动窗口上的小部件?,python,pyqt4,Python,Pyqt4,我是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, eve
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_()
您应该查看QGraphicsView,而不是您正在做的事情,它已经内置了这一切 编辑:显示如何创建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答案的启发,这里有一些代码通过更新点的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_())
谢谢Eric的宝贵回复,但这解决了我的部分问题。实际上,我想画一个水箱,我觉得应该用多段线来画,因为我需要三条边,而不是顶部。“QGraphicscene”对象没有属性“addPolyline”。第二,我想根据我的价值给油箱加满油。我怎样才能装满水箱(让我们看看蓝色)?您可以控制场景中的对象-它们不必是简单的形状对象。首先,我将介绍QGraphicsPathItem,它允许您定义要绘制的任何QPainterPath,并支持填充。对于比这更复杂的项目,您可以将任何QGraphicsItem子类化,以使您接近并实现您自己的paintEvent方法。添加路径的快捷方式是QGraphicscene.addPathEric我已尝试按照您的建议进行操作,但我无法为使用QGraphicscene中的PainterPath编写的多段线添加代码。请你发送一些小代码来添加这个。其次,如何保存小部件的位置,因为当我关闭窗口时,所有小部件都会返回到它们的初始位置(我想保存小部件的新位置)?我用一个示例更新了代码,说明了如何创建QPainterPath,就像您所看到的那样。至于保存位置,您需要将它们记录到某个位置的设置中-您可以通过执行scene.items()循环对象,并通过执行item.pos()获得每个项目的位置
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_())