如何将 qgraphicsitem 的位置保存和加载到 qgraphicsscene 或(正确绘制项目)
How to save and load position of qraphicsitems to qraphicscene or (correctly drow item)
原则上来说,这不是一件难事,但事实证明,一切都不像看起来那么容易。很难理解坐标。因为它们一共有三对:模型、项目、视图。我保留了 x 和 y 位置以及 class 属性的其余部分。然后我尝试使用当前位置将它们添加回来。这就是魔法开始的地方。元素占据了以前明显不存在的位置。这也显然与移动物品功能的实现有关。但是,这不是我的,我不明白如何在开始和结束时正确设置坐标。还有放大缩小场景的功能,是可以的,也会影响后面的加载,不过我已经没有想法了。
加载前
加载后
我的 MRE 工具
import sys
from PySide2.QtCore import *
from PySide2.QtGui import *
from PySide2.QtWidgets import *
from math import pi
import os
from pickle import load,dump
class MyQGraphicsView(QGraphicsView):
def __init__ (self, parent=None):
super(MyQGraphicsView, self).__init__ (parent)
def wheelEvent(self, event):
if QApplication.keyboardModifiers() == Qt.ControlModifier:
print('Control+Click')
# Zoom Factor
zoomInFactor = 1.25
zoomOutFactor = 1 / zoomInFactor
# Set Anchors
self.setTransformationAnchor(QGraphicsView.NoAnchor)
self.setResizeAnchor(QGraphicsView.NoAnchor)
# Save the scene pos
oldPos = self.mapToScene(event.pos())
# Zoom
if event.delta() > 0:
zoomFactor = zoomInFactor
else:
zoomFactor = zoomOutFactor
self.scale(zoomFactor, zoomFactor)
# Get the new position
newPos = self.mapToScene(event.pos())
# Move scene to old position
delta = newPos - oldPos
self.translate(delta.x(), delta.y())
class Communicate(QObject):
closeApp = Signal()
add_delete_row = Signal(QModelIndex, str)
class Drow_equipent(QGraphicsItem):
def __init__(self, x, y, w, h,name,brush=Qt.blue,type='эллипс'):
super().__init__()
self.setPos(x, y)
self.penWidth = 1
self.name=name
self.x,self.y,self.h,self.w=x,y,h,w
self.setAcceptHoverEvents(True)
self.signal=Communicate()
self.setFlags(QGraphicsItem.ItemSendsGeometryChanges|QGraphicsItem.ItemIsSelectable)
self.rotation_=False
self._brush=QBrush(brush)
self.pen_color=Qt.black
self.type_obj=type
self.types = {'эллипс': lambda x: x.drawEllipse(self.x, self.y, self.w, self.h),'прямоугольник':lambda x: x.drawRect(self.x, self.y, self.w, self.h)}
# x.drawLine(QPoint(self.x+self.x*2,self.y+self.y*2),QPoint(self.w_eq-self.w_eq/8,self.h_eq-self.h_eq/8)),
# x.drawLine(QPoint(self.x+self.x*8,self.y+self.y*8),QPoint(self.x+self.x*4,self.y+self.y*4+self.h_eq/8)),
# x.drawLine(QPoint(self.x, self.y), QPoint(5, self.y)),
# x.drawLine(QPoint(self.w_eq,self.h_eq), QPoint(self.w_eq, self.h_eq-5)),
# x.drawLine(QPoint(self.w_eq, self.h_eq), QPoint(self.w_eq-5, self.h_eq)),
def get_file_settings(self):
c=self.scenePos()
return {'x':c.x(),'y':c.y(),'h':self.h,'w':self.w,'name':self.name,'rotation':self.rotation(),
'brush_color':self._brush.color().toTuple(),'type_obj':self.type_obj}
def createDefaultContextMenu(self):
menu = QMenu()
menu.addAction('Повернуть').triggered.connect(lambda: self.setMode('scale'))
return menu
def hoverEnterEvent(self, event):
QApplication.instance().setOverrideCursor(Qt.OpenHandCursor)
def hoverLeaveEvent(self, event):
QApplication.instance().restoreOverrideCursor()
def mouseMoveEvent(self, event):
if self.rotation_:
self.my_rotation(self.rotation()+1)
return True
orig_cursor_position = event.lastScenePos()
updated_cursor_position = event.scenePos()
orig_position = self.scenePos()
updated_cursor_x = updated_cursor_position.x() - orig_cursor_position.x() + orig_position.x()
updated_cursor_y = updated_cursor_position.y() - orig_cursor_position.y() + orig_position.y()
self.setPos(QPointF(updated_cursor_x, updated_cursor_y))
def createDefaultContextMenu(self):
menu = QMenu()
menu.addAction('Повернуть').triggered.connect(lambda: self.setMode(True))
return menu
def contextMenuEvent(self, event):
menu = self.createDefaultContextMenu()
menu.exec_(event.screenPos())
def setMode(self, mode):
self.rotation_ = mode
def mouseReleaseEvent(self, event):
print('x: {0}, y: {1}'.format(self.pos().x(), self.pos().y()))
if self.rotation_:
self.rotation_=False
def my_rotation(self,angle):
# self.prepareGeometryChange()
c=self.mapToScene(self.boundingRect().center())
self.setRotation(angle)
cNew = self.mapToScene(self.boundingRect().center())
offset = c - cNew
self.moveBy(offset.x(), offset.y())
def mousePressEvent(self, event):
print(event.pos())
def boundingRect(self):
# return QRectF(-10 - penWidth / 2, -10 - penWidth / 2,
# 20 + penWidth, 20 + penWidth)
return QRectF(self.x,self.y,self.w,self.h)
# return QRectF(self.x,self.y,self.w_eq,self.h_eq)
def paint(self, painter, option, widget, PySide2_QtWidgets_QWidget=None, *args, **kwargs):
# painter.drawRoundedRect(-10, -10, 20, 20, 5, 5)
# painter.setBrush()
painter.setRenderHints(QPainter.Antialiasing|QPainter.TextAntialiasing,True)
painter.setPen(self.pen_color)
painter.setBrush(self._brush)
self.types[self.type_obj](painter)
self._brush = painter.brush()
def setBrush(self,brush):
self._brush.setColor(brush)
def get_square(self):
type={'эллипс': round ((((pi*self.w*self.h)/4)/10000),4),
'прямоугольник':(self.h*self.w)/10000}
return type[self.type_obj]
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
self.centralwidget = QWidget(self)
self.centralwidget.setGeometry(0, 0, 600, 700)
self.centralwidget.setObjectName(u"centralwidget")
self.gridLayout = QGridLayout(self.centralwidget)
self.gridLayout.setObjectName(u"gridLayout")
self.verticalLayout = QVBoxLayout()
self.verticalLayout.setObjectName(u"verticalLayout")
self.graphicsView = MyQGraphicsView(self.centralwidget)
self.graphicsView.setObjectName(u"graphicsView")
self.scene = QGraphicsScene(self.graphicsView)
self.scene.setObjectName('scene')
self.scene.setSceneRect(0, 0, 500, 500)
self.graphicsView.setScene(self.scene)
self.graphicsView.setMouseTracking(True)
self.verticalLayout.addWidget(self.graphicsView)
self.horizontalLayout = QHBoxLayout()
self.horizontalLayout.setObjectName(u"horizontalLayout")
self.add_item = QPushButton(self.centralwidget)
self.add_item.setObjectName(u"add_item")
self.horizontalLayout.addWidget(self.add_item)
self.save_items = QPushButton(self.centralwidget)
self.save_items.setObjectName(u"save_items")
self.horizontalLayout.addWidget(self.save_items)
self.load_items = QPushButton(self.centralwidget)
self.load_items.setObjectName(u"load_items")
self.horizontalLayout.addWidget(self.load_items)
self.verticalLayout.addLayout(self.horizontalLayout)
self.gridLayout.addLayout(self.verticalLayout, 0, 0, 1, 1)
self.setGeometry(0, 0, 600, 700)
self.add_item.pressed.connect(self.add_equipment)
self.save_items.pressed.connect(self.save_items_)
self.load_items.pressed.connect(self.load_items_)
self.retranslateUi()
# setupUi
def retranslateUi(self):
self.add_item.setText(QCoreApplication.translate("MainWindow", u"add item", None))
self.save_items.setText(QCoreApplication.translate("MainWindow", u"save items", None))
self.load_items.setText(QCoreApplication.translate("MainWindow", u"load items", None))
# retranslateUi
def add_equipment(self):
self.eq_obj = Drow_equipent(30, 40, 20,
20, 'block', Qt.blue,'прямоугольник')
self.scene.addItem(self.eq_obj)
self.last_selected_item = self.eq_obj
def load_items_(self):
with open(os.path.join(os.getcwd(), 'config.ini'), 'rb') as f:
settings = load(f)
print(settings)
items_keys = [key for key in settings.keys() if key != 'grid']
print(items_keys)
for item in items_keys:
self.eq_obj = Drow_equipent(settings[item]['x'], settings[item]['y'],
settings[item]['w'], settings[item]['h'],
settings[item]['name'],
QBrush(QColor().fromRgb(*settings[item]['brush_color'])),
settings[item]['type_obj'])
self.scene.addItem(self.eq_obj)
def save_items_(self):
settings = {}
number_item = 0
for item in self.scene.items():
settings[f'item_№:{number_item}'] = item.get_file_settings()
number_item += 1
with open(os.path.join(os.getcwd(), 'config.ini'), 'wb') as f:
dump(settings, f)
if __name__ == '__main__':
app = QApplication(sys.argv)
translator = QTranslator()
if len(sys.argv) > 1:
locale = sys.argv[1]
else:
locale = QLocale.system().name()
translator.load('qt_%s' % locale,
QLibraryInfo.location(QLibraryInfo.TranslationsPath))
app.installTranslator(translator)
window = MainWindow()
window.show()
app.exec_()
要始终考虑的非常重要的事情是 QGraphicsItem 的 position 不必与其内容匹配。
考虑两个矩形项目:
rect1 = self.scene.addRect(5, 10, 20, 10)
rect2 = self.scene.addRect(0, 0, 20, 10)
rect2.setPos(5, 10)
虽然它们都显示在相同的位置,但它们不同。这些参数实际上将成为这些项目的 boundingRect
,但第一个的 pos
仍在 (0, 0),第二个已被移动,这是因为图形项目 always 的起始位置为坐标 (0, 0),边界矩形在项目坐标中为 always。
创建新项目时,通常最好将其边界矩形设置为 (0, 0),除非需要特殊要求(例如,始终显示为 centered[=57 的项目) =] 在其位置上)。
在展示如何更正您的代码之前,还有其他重要的问题需要解决。
- 如果你需要允许移动项目,通常不需要自己实现移动,因为 QGraphicsItem 标志
ItemIsMovable
就足够了;如果您需要对鼠标事件进行特殊控制,只需确保在需要移动时调用默认实现即可;
- 这也意味着
super().mousePressEvent()
必须 被调用,因为 mouseMoveEvents 仅在按下鼠标按钮后接收;
x()
e y()
是所有 QGraphicsItems 的现有功能,虽然您仍然可以通过 self.pos().x()
和 self.pos().y()
访问它们,但覆盖这些属性确实没有任何好处;
- 鼠标事件不应该return一个
bool
;
class Drow_equipent(QGraphicsItem):
def __init__(self, x, y, w, h, name, brush=Qt.blue, type='эллипс'):
super().__init__()
self.setPos(x, y)
self.penWidth = 1
self.name = name
<b>self.h, self.w = h, w</b>
self.setAcceptHoverEvents(True)
self.signal = Communicate()
<b>self.setFlags(
QGraphicsItem.ItemSendsGeometryChanges|
QGraphicsItem.ItemIsSelectable|
QGraphicsItem.ItemIsMovable)</b>
# ...
self.types = {
'эллипс': lambda x: x.drawEllipse(<b>0, 0</b>, self.w, self.h),
'прямоугольник':lambda x: x.drawRect(<b>0, 0</b>, self.w, self.h)
}
# ...
def mouseMoveEvent(self, event):
if self.rotation_:
self.my_rotation(self.rotation() + 1)
else:
super().mouseMoveEvent(event)
def mouseReleaseEvent(self, event):
if self.rotation_:
self.rotation_ = False
super().mouseReleaseEvent(event)
def mousePressEvent(self, event):
print(event.pos())
super().mousePressEvent(event)
def boundingRect(self):
return QRectF(0, 0, self.w, self.h)
最后,将小部件创建为 QMainWindow 的子项是不够的,而且不受支持。您必须将其设置为中央小部件:
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
self.centralwidget = QWidget(self)
self.setCentralWidget(self.centralwidget)
另请注意,虽然对于 运行 不是必需的,但始终建议使用良好的代码风格;应该 总是 逗号后有 space 和等号周围的 space ,否则阅读会更不舒服,因为能够立即区分对象是非常重要:看到self.x,self.y=x,y
(坏)与self.x, self.y = x, y
([=39]不相同=]很好)。阅读官方Style Guide for Python Code.
原则上来说,这不是一件难事,但事实证明,一切都不像看起来那么容易。很难理解坐标。因为它们一共有三对:模型、项目、视图。我保留了 x 和 y 位置以及 class 属性的其余部分。然后我尝试使用当前位置将它们添加回来。这就是魔法开始的地方。元素占据了以前明显不存在的位置。这也显然与移动物品功能的实现有关。但是,这不是我的,我不明白如何在开始和结束时正确设置坐标。还有放大缩小场景的功能,是可以的,也会影响后面的加载,不过我已经没有想法了。
加载前
加载后
我的 MRE 工具
import sys
from PySide2.QtCore import *
from PySide2.QtGui import *
from PySide2.QtWidgets import *
from math import pi
import os
from pickle import load,dump
class MyQGraphicsView(QGraphicsView):
def __init__ (self, parent=None):
super(MyQGraphicsView, self).__init__ (parent)
def wheelEvent(self, event):
if QApplication.keyboardModifiers() == Qt.ControlModifier:
print('Control+Click')
# Zoom Factor
zoomInFactor = 1.25
zoomOutFactor = 1 / zoomInFactor
# Set Anchors
self.setTransformationAnchor(QGraphicsView.NoAnchor)
self.setResizeAnchor(QGraphicsView.NoAnchor)
# Save the scene pos
oldPos = self.mapToScene(event.pos())
# Zoom
if event.delta() > 0:
zoomFactor = zoomInFactor
else:
zoomFactor = zoomOutFactor
self.scale(zoomFactor, zoomFactor)
# Get the new position
newPos = self.mapToScene(event.pos())
# Move scene to old position
delta = newPos - oldPos
self.translate(delta.x(), delta.y())
class Communicate(QObject):
closeApp = Signal()
add_delete_row = Signal(QModelIndex, str)
class Drow_equipent(QGraphicsItem):
def __init__(self, x, y, w, h,name,brush=Qt.blue,type='эллипс'):
super().__init__()
self.setPos(x, y)
self.penWidth = 1
self.name=name
self.x,self.y,self.h,self.w=x,y,h,w
self.setAcceptHoverEvents(True)
self.signal=Communicate()
self.setFlags(QGraphicsItem.ItemSendsGeometryChanges|QGraphicsItem.ItemIsSelectable)
self.rotation_=False
self._brush=QBrush(brush)
self.pen_color=Qt.black
self.type_obj=type
self.types = {'эллипс': lambda x: x.drawEllipse(self.x, self.y, self.w, self.h),'прямоугольник':lambda x: x.drawRect(self.x, self.y, self.w, self.h)}
# x.drawLine(QPoint(self.x+self.x*2,self.y+self.y*2),QPoint(self.w_eq-self.w_eq/8,self.h_eq-self.h_eq/8)),
# x.drawLine(QPoint(self.x+self.x*8,self.y+self.y*8),QPoint(self.x+self.x*4,self.y+self.y*4+self.h_eq/8)),
# x.drawLine(QPoint(self.x, self.y), QPoint(5, self.y)),
# x.drawLine(QPoint(self.w_eq,self.h_eq), QPoint(self.w_eq, self.h_eq-5)),
# x.drawLine(QPoint(self.w_eq, self.h_eq), QPoint(self.w_eq-5, self.h_eq)),
def get_file_settings(self):
c=self.scenePos()
return {'x':c.x(),'y':c.y(),'h':self.h,'w':self.w,'name':self.name,'rotation':self.rotation(),
'brush_color':self._brush.color().toTuple(),'type_obj':self.type_obj}
def createDefaultContextMenu(self):
menu = QMenu()
menu.addAction('Повернуть').triggered.connect(lambda: self.setMode('scale'))
return menu
def hoverEnterEvent(self, event):
QApplication.instance().setOverrideCursor(Qt.OpenHandCursor)
def hoverLeaveEvent(self, event):
QApplication.instance().restoreOverrideCursor()
def mouseMoveEvent(self, event):
if self.rotation_:
self.my_rotation(self.rotation()+1)
return True
orig_cursor_position = event.lastScenePos()
updated_cursor_position = event.scenePos()
orig_position = self.scenePos()
updated_cursor_x = updated_cursor_position.x() - orig_cursor_position.x() + orig_position.x()
updated_cursor_y = updated_cursor_position.y() - orig_cursor_position.y() + orig_position.y()
self.setPos(QPointF(updated_cursor_x, updated_cursor_y))
def createDefaultContextMenu(self):
menu = QMenu()
menu.addAction('Повернуть').triggered.connect(lambda: self.setMode(True))
return menu
def contextMenuEvent(self, event):
menu = self.createDefaultContextMenu()
menu.exec_(event.screenPos())
def setMode(self, mode):
self.rotation_ = mode
def mouseReleaseEvent(self, event):
print('x: {0}, y: {1}'.format(self.pos().x(), self.pos().y()))
if self.rotation_:
self.rotation_=False
def my_rotation(self,angle):
# self.prepareGeometryChange()
c=self.mapToScene(self.boundingRect().center())
self.setRotation(angle)
cNew = self.mapToScene(self.boundingRect().center())
offset = c - cNew
self.moveBy(offset.x(), offset.y())
def mousePressEvent(self, event):
print(event.pos())
def boundingRect(self):
# return QRectF(-10 - penWidth / 2, -10 - penWidth / 2,
# 20 + penWidth, 20 + penWidth)
return QRectF(self.x,self.y,self.w,self.h)
# return QRectF(self.x,self.y,self.w_eq,self.h_eq)
def paint(self, painter, option, widget, PySide2_QtWidgets_QWidget=None, *args, **kwargs):
# painter.drawRoundedRect(-10, -10, 20, 20, 5, 5)
# painter.setBrush()
painter.setRenderHints(QPainter.Antialiasing|QPainter.TextAntialiasing,True)
painter.setPen(self.pen_color)
painter.setBrush(self._brush)
self.types[self.type_obj](painter)
self._brush = painter.brush()
def setBrush(self,brush):
self._brush.setColor(brush)
def get_square(self):
type={'эллипс': round ((((pi*self.w*self.h)/4)/10000),4),
'прямоугольник':(self.h*self.w)/10000}
return type[self.type_obj]
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
self.centralwidget = QWidget(self)
self.centralwidget.setGeometry(0, 0, 600, 700)
self.centralwidget.setObjectName(u"centralwidget")
self.gridLayout = QGridLayout(self.centralwidget)
self.gridLayout.setObjectName(u"gridLayout")
self.verticalLayout = QVBoxLayout()
self.verticalLayout.setObjectName(u"verticalLayout")
self.graphicsView = MyQGraphicsView(self.centralwidget)
self.graphicsView.setObjectName(u"graphicsView")
self.scene = QGraphicsScene(self.graphicsView)
self.scene.setObjectName('scene')
self.scene.setSceneRect(0, 0, 500, 500)
self.graphicsView.setScene(self.scene)
self.graphicsView.setMouseTracking(True)
self.verticalLayout.addWidget(self.graphicsView)
self.horizontalLayout = QHBoxLayout()
self.horizontalLayout.setObjectName(u"horizontalLayout")
self.add_item = QPushButton(self.centralwidget)
self.add_item.setObjectName(u"add_item")
self.horizontalLayout.addWidget(self.add_item)
self.save_items = QPushButton(self.centralwidget)
self.save_items.setObjectName(u"save_items")
self.horizontalLayout.addWidget(self.save_items)
self.load_items = QPushButton(self.centralwidget)
self.load_items.setObjectName(u"load_items")
self.horizontalLayout.addWidget(self.load_items)
self.verticalLayout.addLayout(self.horizontalLayout)
self.gridLayout.addLayout(self.verticalLayout, 0, 0, 1, 1)
self.setGeometry(0, 0, 600, 700)
self.add_item.pressed.connect(self.add_equipment)
self.save_items.pressed.connect(self.save_items_)
self.load_items.pressed.connect(self.load_items_)
self.retranslateUi()
# setupUi
def retranslateUi(self):
self.add_item.setText(QCoreApplication.translate("MainWindow", u"add item", None))
self.save_items.setText(QCoreApplication.translate("MainWindow", u"save items", None))
self.load_items.setText(QCoreApplication.translate("MainWindow", u"load items", None))
# retranslateUi
def add_equipment(self):
self.eq_obj = Drow_equipent(30, 40, 20,
20, 'block', Qt.blue,'прямоугольник')
self.scene.addItem(self.eq_obj)
self.last_selected_item = self.eq_obj
def load_items_(self):
with open(os.path.join(os.getcwd(), 'config.ini'), 'rb') as f:
settings = load(f)
print(settings)
items_keys = [key for key in settings.keys() if key != 'grid']
print(items_keys)
for item in items_keys:
self.eq_obj = Drow_equipent(settings[item]['x'], settings[item]['y'],
settings[item]['w'], settings[item]['h'],
settings[item]['name'],
QBrush(QColor().fromRgb(*settings[item]['brush_color'])),
settings[item]['type_obj'])
self.scene.addItem(self.eq_obj)
def save_items_(self):
settings = {}
number_item = 0
for item in self.scene.items():
settings[f'item_№:{number_item}'] = item.get_file_settings()
number_item += 1
with open(os.path.join(os.getcwd(), 'config.ini'), 'wb') as f:
dump(settings, f)
if __name__ == '__main__':
app = QApplication(sys.argv)
translator = QTranslator()
if len(sys.argv) > 1:
locale = sys.argv[1]
else:
locale = QLocale.system().name()
translator.load('qt_%s' % locale,
QLibraryInfo.location(QLibraryInfo.TranslationsPath))
app.installTranslator(translator)
window = MainWindow()
window.show()
app.exec_()
要始终考虑的非常重要的事情是 QGraphicsItem 的 position 不必与其内容匹配。
考虑两个矩形项目:
rect1 = self.scene.addRect(5, 10, 20, 10)
rect2 = self.scene.addRect(0, 0, 20, 10)
rect2.setPos(5, 10)
虽然它们都显示在相同的位置,但它们不同。这些参数实际上将成为这些项目的 boundingRect
,但第一个的 pos
仍在 (0, 0),第二个已被移动,这是因为图形项目 always 的起始位置为坐标 (0, 0),边界矩形在项目坐标中为 always。
创建新项目时,通常最好将其边界矩形设置为 (0, 0),除非需要特殊要求(例如,始终显示为 centered[=57 的项目) =] 在其位置上)。
在展示如何更正您的代码之前,还有其他重要的问题需要解决。
- 如果你需要允许移动项目,通常不需要自己实现移动,因为 QGraphicsItem 标志
ItemIsMovable
就足够了;如果您需要对鼠标事件进行特殊控制,只需确保在需要移动时调用默认实现即可; - 这也意味着
super().mousePressEvent()
必须 被调用,因为 mouseMoveEvents 仅在按下鼠标按钮后接收; x()
ey()
是所有 QGraphicsItems 的现有功能,虽然您仍然可以通过self.pos().x()
和self.pos().y()
访问它们,但覆盖这些属性确实没有任何好处;- 鼠标事件不应该return一个
bool
;
class Drow_equipent(QGraphicsItem):
def __init__(self, x, y, w, h, name, brush=Qt.blue, type='эллипс'):
super().__init__()
self.setPos(x, y)
self.penWidth = 1
self.name = name
<b>self.h, self.w = h, w</b>
self.setAcceptHoverEvents(True)
self.signal = Communicate()
<b>self.setFlags(
QGraphicsItem.ItemSendsGeometryChanges|
QGraphicsItem.ItemIsSelectable|
QGraphicsItem.ItemIsMovable)</b>
# ...
self.types = {
'эллипс': lambda x: x.drawEllipse(<b>0, 0</b>, self.w, self.h),
'прямоугольник':lambda x: x.drawRect(<b>0, 0</b>, self.w, self.h)
}
# ...
def mouseMoveEvent(self, event):
if self.rotation_:
self.my_rotation(self.rotation() + 1)
else:
super().mouseMoveEvent(event)
def mouseReleaseEvent(self, event):
if self.rotation_:
self.rotation_ = False
super().mouseReleaseEvent(event)
def mousePressEvent(self, event):
print(event.pos())
super().mousePressEvent(event)
def boundingRect(self):
return QRectF(0, 0, self.w, self.h)
最后,将小部件创建为 QMainWindow 的子项是不够的,而且不受支持。您必须将其设置为中央小部件:
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
self.centralwidget = QWidget(self)
self.setCentralWidget(self.centralwidget)
另请注意,虽然对于 运行 不是必需的,但始终建议使用良好的代码风格;应该 总是 逗号后有 space 和等号周围的 space ,否则阅读会更不舒服,因为能够立即区分对象是非常重要:看到self.x,self.y=x,y
(坏)与self.x, self.y = x, y
([=39]不相同=]很好)。阅读官方Style Guide for Python Code.