我正在编写一个应用程序,我希望能够通过单击并拖动它们来移动矩形。到目前为止,下面的代码正确地执行了此操作
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
import sys
class Memory(QWidget):
grid = None
scene = None
def __init__(self, geometry, parent=None):
super(Memory, self).__init__(parent=parent)
self.layout = QGridLayout(self)
self.scene = QGraphicsScene(self)
self.scene.setSceneRect(geometry.x(), geometry.y(), geometry.width(), geometry.height())
self.scene.setBackgroundBrush(Qt.white)
self.view = QGraphicsView()
self.view.setScene(self.scene)
self.layout.addWidget(self.view)
rect = QRectF(40, 40, 220, 110)
self.make_proxy(rect)
rect2 = QRectF(300, 40, 220, 110)
self.make_proxy(rect2)
def make_proxy(self, rect):
label = QLabel('World')
label.setAlignment(Qt.AlignCenter | Qt.AlignCenter)
# create proxy
proxy = QGraphicsProxyWidget()
proxy.setWidget(label)
proxy.setGeometry(rect)
self.scene.addItem(proxy)
# create parent item
rectangle = QGraphicsRectItem(rect)
rectangle.setFlag(QGraphicsItem.ItemIsMovable, True)
self.scene.addItem(rectangle)
# set parent
proxy.setParentItem(rectangle)
def main():
app = QApplication(sys.argv)
form = Memory(QRect(10, 10, 550, 180))
form.show()
app.exec_()
if __name__ == '__main__':
main()
然而,第一个矩形始终位于场景的底部,因为它首先被添加到场景的底部。但是当我点击它时,它应该转到场景的顶部,使它出现在第二个矩形的上方。这就是我想要继承QGraphicsRectItem
并为其添加新功能的原因。但是当我按照以下方式实施时
class RectItem(QGraphicsRectItem):
def __init__(self, rect):
QGraphicsRectItem.__init__(self)
self.rectangle = rect
def boundingRect(self):
super(RectItem, self).boundingRect()
return self.rectangle
并将rectangle
变量定义为
rectangle = RectItem(rect)
项目不再可移动,即QGraphicsItem.ItemIsMovable
标志无效。
是否有一种简单的子类化QGraphicsRectItem
的方法,并且仍然保留setFlag(QGraphicsItem.ItemIsMovable, True)
等所有便利功能?
修改
正如eyllanesc指出的那样,没有必要覆盖boundingRect
方法。当我尝试将QGraphicsRectItem
子类化为
class RectItem(QGraphicsRectItem):
def __init__(self, rect):
QGraphicsRectItem.__init__(self)
并将rectangle
定义为
rectangle = RectItem(rect)
我没有与
相同的行为 rectangle = QGraphicsRectItem(rect)
这是什么原因?
答案 0 :(得分:0)
从类继承时,必须调用父类的构造函数并传递一些参数,在这种情况下,使用以下代码:
QGraphicsRectItem.__init__(self)
审核docs:
QGraphicsRectItem(QGraphicsItem *parent = Q_NULLPTR)
QGraphicsRectItem(const QRectF &rect, QGraphicsItem *parent = Q_NULLPTR)
QGraphicsRectItem(qreal x, qreal y, qreal width, qreal height, QGraphicsItem *parent = Q_NULLPTR)
您正在使用第一个没有父级和QRect的构造函数。
检查docs:
[...]
QGraphicsRectItem
使用矩形和笔宽来合理实施boundingRect()
,shape()
和contains()
。 [...]
从我们看到他使用QRect进行boundingRect()
,此方法用于其他方法,如移动,调整大小等。
由于这个原因我不建议以这种方式覆盖父级,除了无意之外,当我覆盖一个类时,我总是添加信息,即新参数或我将默认值设置为现有的,一般继承方式如下:
class RectItem(QGraphicsRectItem):
def __init__(self, *args, **kwargs):
QGraphicsRectItem.__init__(self, *args, **kwargs)
如果我想添加参数,我可以使用以下模板:
class RectItem(QGraphicsRectItem):
def __init__(self, new_param, *args, **kwargs):
QGraphicsRectItem.__init__(self, *args, **kwargs)
self.new_param = new_param
或设置默认值:
class RectItem(QGraphicsRectItem):
def __init__(self, parent):
QGraphicsRectItem.__init__(self, rect=QRect(0, 0, 100,100), parent=parent)