如何继承 QPointF 并设置自定义属性?
How to subclass QPointF and set custom attribute?
在我的图表中,我需要在每个 QPointF
中存储很多信息,但是当我对 QPointF
进行子类化时,它似乎没有任何效果,有人可以给我好的解决方案或想法吗?
代码为:
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
from PyQt5.QtPrintSupport import *
from PyQt5.QtChart import *
import random
class MyPoint(QPointF):
def __init__(self, *args):
super().__init__(*args)
def set_name(self, name):
self.name = name
def set_info(self, info):
self.info = info
class DemoChar(QChartView):
def __init__(self):
super().__init__()
self.setRenderHint(QPainter.Antialiasing)
self.chart = QChart()
self.chart.setTitle('Demo')
self.chart.setAnimationOptions(QChart.SeriesAnimations)
self.setChart(self.chart)
self.lineItem = QGraphicsLineItem(self.chart)
series = QLineSeries(name="random serie")
series.setPointsVisible(True)
series.clicked.connect(self.on_click)
self.series = series
for i in range(20):
#series << QPointF(0.1 * i, random.uniform(-10, 10))
pt = MyPoint( 0.1 * i, random.uniform(-10, 10) )
pt.set_name(str(pt))
pt.set_info(str(random.randint(1, 100)))
series << pt
self.chart.addSeries(series)
self.chart.createDefaultAxes()
def on_click(self, pt):
one_pt = self.series.pointsVector()[0]
print(one_pt)
# print(one_pt.name) #the point have no name, info attribute
app = QApplication([])
demo = DemoChar()
demo.show()
app.exec()
当您将 QPointF 传递给 QLineSeries 时,使用的复制构造函数只复制 x 和 y 值,也就是说,它不复制对象,只复制一些属性。
因此,与其实现自定义 QPointF,不如使用 QVXYModelMapper 实现映射到 QLineSeries 的模型:
import random
from PyQt5.QtCore import pyqtSlot, QPointF, Qt
from PyQt5.QtGui import QPainter, QStandardItem, QStandardItemModel
from PyQt5.QtWidgets import QApplication
from PyQt5.QtChart import QChart, QChartView, QLineSeries, QVXYModelMapper
class CustomModel(QStandardItemModel):
def add_point(self, pt, name="", info=""):
items = []
for value in (pt.x(), pt.y(), name, info):
it = QStandardItem()
it.setData(value, Qt.DisplayRole)
items.append(it)
self.appendRow(items)
def get_data(self, row):
if 0 <= row < self.rowCount():
pt = QPointF(
self.item(row, 0).data(Qt.DisplayRole),
self.item(row, 1).data(Qt.DisplayRole),
)
name = self.item(row, 2).data(Qt.DisplayRole)
info = self.item(row, 3).data(Qt.DisplayRole)
return pt, name, info
class DemoChar(QChartView):
def __init__(self, parent=None):
super().__init__(parent)
self.setRenderHint(QPainter.Antialiasing)
self.chart = QChart()
self.chart.setTitle("Demo")
self.chart.setAnimationOptions(QChart.SeriesAnimations)
self.setChart(self.chart)
self.model = CustomModel()
self.series = QLineSeries(name="random serie")
self.series.setPointsVisible(True)
self.series.clicked.connect(self.on_click)
self.mapper = QVXYModelMapper(xColumn=0, yColumn=1)
self.mapper.setModel(self.model)
self.mapper.setSeries(self.series)
for i in range(20):
pt = QPointF(0.1 * i, random.uniform(-10, 10))
name = "name-{}".format(i)
info = str(random.randint(1, 100))
self.model.add_point(pt, name, info)
self.chart.addSeries(self.series)
self.chart.createDefaultAxes()
@pyqtSlot(QPointF)
def on_click(self, pt):
# first point
index = 0
value = self.model.get_data(index)
if value is not None:
pt, name, info = value
print(pt, name, info)
def main(args):
app = QApplication(args)
demo = DemoChar()
demo.show()
ret = app.exec()
if __name__ == "__main__":
import sys
sys.exit(main(sys.argv))
在我的图表中,我需要在每个 QPointF
中存储很多信息,但是当我对 QPointF
进行子类化时,它似乎没有任何效果,有人可以给我好的解决方案或想法吗?
代码为:
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
from PyQt5.QtPrintSupport import *
from PyQt5.QtChart import *
import random
class MyPoint(QPointF):
def __init__(self, *args):
super().__init__(*args)
def set_name(self, name):
self.name = name
def set_info(self, info):
self.info = info
class DemoChar(QChartView):
def __init__(self):
super().__init__()
self.setRenderHint(QPainter.Antialiasing)
self.chart = QChart()
self.chart.setTitle('Demo')
self.chart.setAnimationOptions(QChart.SeriesAnimations)
self.setChart(self.chart)
self.lineItem = QGraphicsLineItem(self.chart)
series = QLineSeries(name="random serie")
series.setPointsVisible(True)
series.clicked.connect(self.on_click)
self.series = series
for i in range(20):
#series << QPointF(0.1 * i, random.uniform(-10, 10))
pt = MyPoint( 0.1 * i, random.uniform(-10, 10) )
pt.set_name(str(pt))
pt.set_info(str(random.randint(1, 100)))
series << pt
self.chart.addSeries(series)
self.chart.createDefaultAxes()
def on_click(self, pt):
one_pt = self.series.pointsVector()[0]
print(one_pt)
# print(one_pt.name) #the point have no name, info attribute
app = QApplication([])
demo = DemoChar()
demo.show()
app.exec()
当您将 QPointF 传递给 QLineSeries 时,使用的复制构造函数只复制 x 和 y 值,也就是说,它不复制对象,只复制一些属性。
因此,与其实现自定义 QPointF,不如使用 QVXYModelMapper 实现映射到 QLineSeries 的模型:
import random
from PyQt5.QtCore import pyqtSlot, QPointF, Qt
from PyQt5.QtGui import QPainter, QStandardItem, QStandardItemModel
from PyQt5.QtWidgets import QApplication
from PyQt5.QtChart import QChart, QChartView, QLineSeries, QVXYModelMapper
class CustomModel(QStandardItemModel):
def add_point(self, pt, name="", info=""):
items = []
for value in (pt.x(), pt.y(), name, info):
it = QStandardItem()
it.setData(value, Qt.DisplayRole)
items.append(it)
self.appendRow(items)
def get_data(self, row):
if 0 <= row < self.rowCount():
pt = QPointF(
self.item(row, 0).data(Qt.DisplayRole),
self.item(row, 1).data(Qt.DisplayRole),
)
name = self.item(row, 2).data(Qt.DisplayRole)
info = self.item(row, 3).data(Qt.DisplayRole)
return pt, name, info
class DemoChar(QChartView):
def __init__(self, parent=None):
super().__init__(parent)
self.setRenderHint(QPainter.Antialiasing)
self.chart = QChart()
self.chart.setTitle("Demo")
self.chart.setAnimationOptions(QChart.SeriesAnimations)
self.setChart(self.chart)
self.model = CustomModel()
self.series = QLineSeries(name="random serie")
self.series.setPointsVisible(True)
self.series.clicked.connect(self.on_click)
self.mapper = QVXYModelMapper(xColumn=0, yColumn=1)
self.mapper.setModel(self.model)
self.mapper.setSeries(self.series)
for i in range(20):
pt = QPointF(0.1 * i, random.uniform(-10, 10))
name = "name-{}".format(i)
info = str(random.randint(1, 100))
self.model.add_point(pt, name, info)
self.chart.addSeries(self.series)
self.chart.createDefaultAxes()
@pyqtSlot(QPointF)
def on_click(self, pt):
# first point
index = 0
value = self.model.get_data(index)
if value is not None:
pt, name, info = value
print(pt, name, info)
def main(args):
app = QApplication(args)
demo = DemoChar()
demo.show()
ret = app.exec()
if __name__ == "__main__":
import sys
sys.exit(main(sys.argv))