如何替换PyQtGraph图表X轴下方的按钮(附实现代码)
PyQtGraph X轴底部按钮替换实现方案
你当前代码的核心问题是直接通过addItem()把按钮代理扔到了绘图场景里,既没法固定在X轴下方的位置,也没有预留替换按钮的逻辑,按下面的方法改就能实现需求:
- 优先用外层垂直布局给按钮留固定占位:
PlotWidget本身已经加在QVBoxLayout里,直接在它下方加一个专属的水平布局放按钮,位置会固定在X轴正下方,不会漂移到绘图区域里遮挡曲线 - 封装独立的按钮替换方法:换按钮时先清空占位布局里的旧控件,再挂载新按钮,同时给新按钮绑定对应的业务逻辑,不会出现控件重叠、内存泄漏的问题
- 如果需要按钮和绘图场景绑定(比如随视图缩放移动),就用
QGraphicsProxyWidget锚定到X轴下方位置,替换时直接调用代理的setWidget()方法传入新按钮即可,不需要重复创建代理对象
可直接运行的修正代码
代码里做了按钮互斥替换的演示:点击初始的「Clip」按钮会自动替换为「Export」按钮,点击「Export」会换回「Clip」,你可以按需替换成自己的业务逻辑:
from pyqtgraph.Qt import QtGui, QtCore import numpy as np import pyqtgraph as pg app = pg.mkQApp() mw = QtGui.QMainWindow() mw.setWindowTitle('Spectrum analysis') cw = QtGui.QWidget() mw.setCentralWidget(cw) main_layout = QtGui.QVBoxLayout() cw.setLayout(main_layout) pw3 = pg.PlotWidget() main_layout.addWidget(pw3) # 在PlotWidget下方加专属按钮布局,位置固定在X轴正下方 btn_container = QtGui.QHBoxLayout() main_layout.addLayout(btn_container) def switch_btn(new_btn): # 清空旧按钮 while btn_container.count(): old_item = btn_container.takeAt(0) if old_item.widget(): old_item.widget().deleteLater() # 挂载新按钮并绑定对应逻辑 btn_container.addWidget(new_btn) if new_btn.text() == "Clip": new_btn.clicked.connect(lambda: switch_btn(export_btn)) elif new_btn.text() == "Export": new_btn.clicked.connect(lambda: switch_btn(clip_btn)) # 预定义需要切换的按钮 clip_btn = QtGui.QPushButton("Clip") export_btn = QtGui.QPushButton("Export") # 初始化加载默认按钮 switch_btn(clip_btn) mw.show() # 原有绘图逻辑 curve = pw3.plot(np.random.normal(size=100)*1e0, clickable=True) curve.curve.setClickable(True) curve.setPen('w') curve.setShadowPen(pg.mkPen((70,70,30), width=6, cosmetic=True)) def clicked(): print("curve clicked") curve.sigClicked.connect(clicked) def regionUpdate(regionItem): lo,hi = regionItem.getRegion() print(lo, hi) lr = pg.LinearRegionItem([1, 30], movable=True) lr.sigRegionChanged.connect(regionUpdate) pw3.addItem(lr) if __name__ == '__main__': pg.exec()
场景内嵌按钮的实现方式
如果需要把按钮放在绘图场景内部,而不是外层布局里,不要直接addItem就完事,要给代理加位置锚定,固定在X轴下方,替换按钮时直接调用proxy.setWidget(新按钮)即可:
# 场景代理初始化 proxy = QtGui.QGraphicsProxyWidget() init_btn = QtGui.QPushButton("Clip") proxy.setWidget(init_btn) pw3.addItem(proxy) # 锚定位置到X轴下方,视图缩放/窗口大小变化时自动调整位置 def anchor_btn(): view_bottom = pw3.plotItem.vb.sceneBoundingRect().bottom() proxy.setPos(10, view_bottom - 35) pw3.plotItem.vb.sigResized.connect(anchor_btn) anchor_btn() # 替换按钮示例 new_btn = QtGui.QPushButton("Export") proxy.setWidget(new_btn)
内容的提问来源于stack exchange,提问作者Cosis94
相关产品推荐
相关产品推荐

