我在这里有两个问题。
import sys
from PySide.QtGui import *
from PySide.QtCore import *
import random
class MyGraphicsView(QGraphicsView):
def __init__(self):
super(MyGraphicsView, self).__init__()
self.setDragMode(QGraphicsView.RubberBandDrag)
self._isPanning = False
self._mousePressed = False
# self.setBackgroundBrush(QImage("C:/Users/jmartini/Desktop/Temp/images/flag_0140.jpg"))
self.setCacheMode(QGraphicsView.CacheBackground)
self.setHorizontalScrollBarPolicy( Qt.ScrollBarAlwaysOff )
self.setVerticalScrollBarPolicy( Qt.ScrollBarAlwaysOff )
def mousePressEvent(self, event):
if event.button() == Qt.LeftButton:
self._mousePressed = True
if self._isPanning:
self.setCursor(Qt.ClosedHandCursor)
self._dragPos = event.pos()
event.accept()
else:
super(MyGraphicsView, self).mousePressEvent(event)
elif event.button() == Qt.MiddleButton:
self._mousePressed = True
self._isPanning = True
self.setCursor(Qt.ClosedHandCursor)
self._dragPos = event.pos()
event.accept()
def mouseMoveEvent(self, event):
if self._mousePressed and self._isPanning:
newPos = event.pos()
diff = newPos - self._dragPos
self._dragPos = newPos
self.horizontalScrollBar().setValue(self.horizontalScrollBar().value() - diff.x())
self.verticalScrollBar().setValue(self.verticalScrollBar().value() - diff.y())
event.accept()
else:
super(MyGraphicsView, self).mouseMoveEvent(event)
def mouseReleaseEvent(self, event):
if event.button() == Qt.LeftButton:
if self._isPanning:
self.setCursor(Qt.OpenHandCursor)
else:
self._isPanning = False
self.setCursor(Qt.ArrowCursor)
self._mousePressed = False
elif event.button() == Qt.MiddleButton:
self._isPanning = False
self.setCursor(Qt.ArrowCursor)
self._mousePressed = False
super(MyGraphicsView, self).mouseReleaseEvent(event)
def mouseDoubleClickEvent(self, event):
self.fitInView(self.sceneRect(), Qt.KeepAspectRatio)
pass
def keyPressEvent(self, event):
if event.key() == Qt.Key_Space and not self._mousePressed:
self._isPanning = True
self.setCursor(Qt.OpenHandCursor)
else:
super(MyGraphicsView, self).keyPressEvent(event)
def keyReleaseEvent(self, event):
if event.key() == Qt.Key_Space:
if not self._mousePressed:
self._isPanning = False
self.setCursor(Qt.ArrowCursor)
else:
super(MyGraphicsView, self).keyPressEvent(event)
def wheelEvent(self, event):
# zoom factor
factor = 1.25
# Set Anchors
self.setTransformationAnchor(QGraphicsView.NoAnchor)
self.setResizeAnchor(QGraphicsView.NoAnchor)
# Save the scene pos
oldPos = self.mapToScene(event.pos())
# Zoom
if event.delta() < 0:
factor = 1.0 / factor
self.scale(factor, factor)
# Get the new position
newPos = self.mapToScene(event.pos())
# Move scene to old position
delta = newPos - oldPos
self.translate(delta.x(), delta.y())
class MyGraphicsScene(QGraphicsScene):
def __init__(self, parent):
super(MyGraphicsScene, self).__init__()
self.setBackgroundBrush(QBrush(QColor(50,50,50)))
class EllipseItem(QGraphicsEllipseItem):
def __init__(self):
super(EllipseItem, self).__init__()
self.setAcceptHoverEvents(True)
self.hover = False
def paint(self, painter, option, widget):
painter.setRenderHints( QPainter.Antialiasing | QPainter.TextAntialiasing | QPainter.SmoothPixmapTransform | QPainter.HighQualityAntialiasing, True )
painter.setBrush(QBrush(QColor(170,170,170,255)))
if self.isSelected():
painter.setPen(QPen(QColor(255,255,255), 2, Qt.SolidLine, Qt.RoundCap, Qt.RoundJoin))
else:
painter.setPen(QPen(QColor(30,30,30), 2, Qt.SolidLine, Qt.RoundCap, Qt.RoundJoin))
self.setRect(-16, -16, 16, 16)
if self.hover:
painter.setPen(QPen(QColor(255,255,255), 2, Qt.SolidLine, Qt.RoundCap, Qt.RoundJoin))
self.setRect(-18, -18, 18, 18)
painter.drawEllipse(self.rect())
def hoverEnterEvent(self, event):
self.hover = True
self.update()
super(self.__class__, self).hoverEnterEvent(event)
def hoverLeaveEvent(self, event):
self.hover = False
self.update()
super(self.__class__, self).hoverEnterEvent(event)
class MyMainWindow(QMainWindow):
def __init__(self):
super(MyMainWindow, self).__init__()
self.setWindowTitle("Test")
self.resize(800,600)
self.gv = MyGraphicsView()
self.gv.setScene(MyGraphicsScene(self))
lay_main = QVBoxLayout()
lay_main.addWidget(self.gv)
widget_main = QWidget()
widget_main.setLayout(lay_main)
self.setCentralWidget(widget_main)
self.populate()
def populate(self):
scene = self.gv.scene()
item = EllipseItem()
item.setFlag( QGraphicsItem.ItemIsSelectable )
scene.addItem(item)
def main():
app = QApplication(sys.argv)
ex = MyMainWindow()
ex.show()
sys.exit(app.exec_())
if __name__ == '__main__':
main()
答案 0 :(得分:0)
我不太确定您到底想要什么(也许是我的英语)。通过运行您的代码,我看到悬停时边缘被框切掉了,并且两个圆不在同一点居中。
嗯,居中问题是由于在setRect
类的paint
重载上使用了EllipseItem
方法。对于悬停情况(我忽略了代码的所选项目逻辑),您正在设置实际上具有不同中心的矩形。要解决此问题,可以使用QPainter.drawEllipse(center, rx, ry)
,docs。
可以解决边缘问题,注意在{R {3}}发布的setRect设置的矩形上不考虑绘制的边缘。老实说,我不太确定为什么较小的椭圆适合矩形而较大的椭圆不适合矩形。
无论如何,您可以尝试执行以下操作:
def paint(self, painter, option, widget):
painter.setRenderHints( QPainter.Antialiasing | QPainter.TextAntialiasing | QPainter.SmoothPixmapTransform | QPainter.HighQualityAntialiasing, True )
painter.setBrush(QBrush(QColor(170,170,170,255)))
# if self.isSelected():
# painter.setPen(QPen(QColor(255,255,255), 2, Qt.SolidLine, Qt.RoundCap, Qt.RoundJoin))
# else:
# painter.setPen(QPen(QColor(30,30,30), 2, Qt.SolidLine, Qt.RoundCap, Qt.RoundJoin))
#self.setRect(-16, -16, 16, 16)
center = QPointF(0,0)
if self.hover:
painter.setPen(QPen(QColor(255,255,255), 2, Qt.SolidLine, Qt.RoundCap, Qt.RoundJoin))
# self.setRect(-10,-10, 20, 20) # this one wont fit the ellipse
self.setRect(-11, -11, 22, 22)
# plus 2
painter.drawEllipse(center, 10, 10)
else:
painter.setPen(QPen(QColor(30,30,30), 2, Qt.SolidLine, Qt.RoundCap, Qt.RoundJoin))
self.setRect(-8, -8, 16, 16) # but this one does
painter.drawEllipse(center, 8, 8)
很显然,您可以用多种方式将椭圆居中,上面的代码只是其中一种。
希望有帮助。