Python 如何将自定义AxisItem添加到现有PlotWidget?

Python 如何将自定义AxisItem添加到现有PlotWidget?,python,python-2.7,pyqt,pyqt4,pyqtgraph,Python,Python 2.7,Pyqt,Pyqt4,Pyqtgraph,我正在尝试将pyqtgraph中的自定义AxisItem添加到由Qt设计器生成的现有PlotWidget中。这是一个相关的主题,但代码示例并没有确切的答案,我无法发表评论,所以我创建了一个新主题 这是我的自定义AxisItem(基于代码): 这是我的主要QtPlotter类: 然后我尝试添加我的自定义AxisItem: 我没有错误,但这不会产生任何影响。类没有setAxis方法,只有getAxis方法来获取当前轴。您可以在PlotItem构造函数的axisItems参数中指定包含轴项目的字典,但

我正在尝试将pyqtgraph中的自定义AxisItem添加到由Qt设计器生成的现有PlotWidget中。这是一个相关的主题,但代码示例并没有确切的答案,我无法发表评论,所以我创建了一个新主题

这是我的自定义AxisItem(基于代码):

这是我的主要QtPlotter类:

然后我尝试添加我的自定义AxisItem:


我没有错误,但这不会产生任何影响。

类没有
setAxis
方法,只有
getAxis
方法来获取当前轴。您可以在
PlotItem
构造函数的
axisItems
参数中指定包含轴项目的字典,但似乎无法更新现有
PlotItem
AxisItem

尽管
PlotItem.axes
字典是一个公共属性,但它没有文档记录,因此仅使用它有点风险。PyQtGraph的作者可能会改变其行为,或者重命名它(尽管发生这种情况的可能性很小)。IMHO应该将其设置为私有属性

在任何情况下,通过查看
PlotItem
构造函数的,您可以看到如何将
axisItem
参数中的轴项添加到绘图项:

    ## Create and place axis items
    if axisItems is None:
        axisItems = {}
    self.axes = {}
    for k, pos in (('top', (1,1)), ('bottom', (3,1)), ('left', (2,0)), ('right', (2,2))):
        if k in axisItems:
            axis = axisItems[k]
        else:
            axis = AxisItem(orientation=k, parent=self)
        axis.linkToView(self.vb)
        self.axes[k] = {'item': axis, 'pos': pos}
        self.layout.addItem(axis, *pos)
        axis.setZValue(-1000)
        axis.setFlag(axis.ItemNegativeZStacksBehindParent)
也许您可以通过查看上面的代码使其工作。同样,这是未记录的行为,使用风险自负!此外,在设置新项目以防止内存泄漏时,应正确删除和取消链接旧的
AxisItem
。也许这很棘手,这可能是
PlotItem.setAxis
方法不存在的原因。

我查看了
PlotItem
构造函数的一整天,但我无法使其工作

最后,我发现QtDesigner/QtCreator在PlotWidget上只输出三行。与尝试将TimeAxisItem添加到现有PlotWidget不同,只需删除现有PlotWidget,然后使用TimeAxisItem创建一个新的PlotWidget就更容易(但绝对不是更好),如前所述


由于有人试图在这里找到一些东西,我将发布我的简单但不优雅的解决方法

在使用pyuic将Qt设计器生成的模板转换为python模板文件后,我将通过替换相应的PlotWidget将自定义AxisItem直接添加到python模板文件中。这一切都可以通过简单的bash脚本完成:

pyuic4 template.ui -o template.py 

match="from PyQt4 import QtCore, QtGui"
insert_class="from timeaxisitem_class import TimeAxisItem"
match_widget="self.plot = PlotWidget(Form)"
insert_timeaxis="self.plot = PlotWidget(Form, axisItems={'bottom': TimeAxisItem(orientation='bottom')})"

file="template.py"
sed -i "s/$match/$match\n$insert_class/" $file
sed -i "s/$match_widget/$insert_timeaxis/" $file

我知道这是一篇老文章,但我遇到了一个类似的问题,并在中遇到了一个解决方案,这是一个AxisItem子类,它实现了一个
AttachTopMotItem
方法

所以关于原来的帖子,而不是

self.ui_plot.getPlotItem().axes['bottom']['item'] = TimeAxisItem(orientation='bottom')
在TimeAxisItem子类中需要以下方法(从上面链接的示例复制):

    def attachToPlotItem(self, plotItem):
        """Add this axis to the given PlotItem
        :param plotItem: (PlotItem)
        """
        self.setParentItem(plotItem)
        viewBox = plotItem.getViewBox()
        self.linkToView(viewBox)
        self._oldAxis = plotItem.axes[self.orientation]['item']
        self._oldAxis.hide()
        plotItem.axes[self.orientation]['item'] = self
        pos = plotItem.axes[self.orientation]['pos']
        plotItem.layout.addItem(self, *pos)
        self.setZValue(-1000)
它甚至保留了原来的AxisItem,以便在需要时可以重新恢复

然后在QtPlotter构造函数中,添加

axis = TimeAxisItem(orientation='bottom')
axis.attactToPlotItem(self.ui_plot.getPlotItem())

这太容易了。PlotItem类没有setAxis方法。取而代之的是一个名为setAxisItems的方法。这个代码对我有用

date_axis = pg.graphicsItems.DateAxisItem.DateAxisItem(orientation = 'bottom')
self.mainSoundPlot.setAxisItems(axisItems = {'bottom': date_axis})
使用
deleteLater()
更好地为我工作!见:
self.ui_plot.getPlotItem().axes['bottom']['item'] = TimeAxisItem(orientation='bottom')
    def attachToPlotItem(self, plotItem):
        """Add this axis to the given PlotItem
        :param plotItem: (PlotItem)
        """
        self.setParentItem(plotItem)
        viewBox = plotItem.getViewBox()
        self.linkToView(viewBox)
        self._oldAxis = plotItem.axes[self.orientation]['item']
        self._oldAxis.hide()
        plotItem.axes[self.orientation]['item'] = self
        pos = plotItem.axes[self.orientation]['pos']
        plotItem.layout.addItem(self, *pos)
        self.setZValue(-1000)
axis = TimeAxisItem(orientation='bottom')
axis.attactToPlotItem(self.ui_plot.getPlotItem())
date_axis = pg.graphicsItems.DateAxisItem.DateAxisItem(orientation = 'bottom')
self.mainSoundPlot.setAxisItems(axisItems = {'bottom': date_axis})