How to work with a subclass when instances of the original class are generated by a method from another class?
I have a small application that I am building and I am having a hard time figuring out how to implement this part for it. Basically, the problem here is that I need to add a method to the class. However, instances of this class are generated using a method in another class. So I don't understand how to implement the subclass without subclassing the second class.
More specifically, these two classes are PlotItem and GraphicsLayoutWidget (classes from pyqtgraph - abbreviated as pg below).
So, in my application, I have:
self.plotWidget = pg.GraphicsLayoutWidget
instances of the PlotItem class are generated by calling the addPlot () method from the GraphicsLayoutWidget. I.e:.
plt = self.plotWidget.addPlot(*args)
The problem is I need to add a method to the PlotItem class, which I was planning to do by just subclassing it. However, I then don't know how to generate instances of this without subclassing GraphicsLayoutWidget.
Is this the best solution? I've read a bit about how the monkey fixes this method in the PlotItem class, but I'm not familiar with this approach at all (relatively new to the whole thing).
In case it matters, the (simplified) subclass definition is:
class MyPlotItem(PlotItem):
def paint(self, painter, *args):
painter.setPen(...)
painter.drawRect(self.boundingRect())
PlotItem.paint(self, painter, *args)
source to share
You can add a new constructor to your class that instantiates MyPlotItem
from PlotItem
, for example:
class MyPlotItem(PlotItem):
@classmethod
def from_plotitem(cls, plotitem):
return cls(plotitem.parent, plotitem.name, ...)
def paint(self, painter, *args):
painter.setPen(...)
painter.drawRect(self.boundingRect())
PlotItem.paint(self, painter, *args)
Then you can replace:
plt = self.plotWidget.addPlot(*args)
from:
plt = MyPlotItem.from_plotitem(self.plotWidget.addPlot(*args))
and have an instance with the desired method.
source to share
I recently had a similar problem where I wanted a subclass PlotItem
to trigger a signal when it was pressed.
Instead of having to subclass GraphicsLayoutWidget
and then use addPlot()
, I used the function GraphicsLayoutWidget
addItem()
like this:
from PyQt4.QtCore import *
from PyQt4.QtGui import *
import pyqtgraph as pg
import sys
class myPlotItem(pg.PlotItem):
clicked = pyqtSignal(QObject)
def __init__(self, parent = None):
super(myPlotItem, self).__init__(parent)
def mousePressEvent(self, ev):
super(myPlotItem, self).mousePressEvent(ev)
self.clicked.emit(self)
def on_click(plot):
print 'clicked! ' + str(plot)
app = QApplication([])
figure = pg.GraphicsLayoutWidget()
plot = myPlotItem()
plot.clicked.connect(on_click)
figure.addItem(plot)
figure.show()
sys.exit(app.exec_())
This works because it addPlot()
calls itself addItem()
in the same way as soon as it created PlotItem
:
source to share