<p>下面是我做的一个很好的例子。
可以重用它来进行更多的绘图,而无需增加代码,只需更改<code>self.num</code>的值并使用函数<code>add_data(x,y,ind)</code>添加相应的数据,其中<code>x</code>和<code>y</code>是数据的值<code>ind</code>是框的索引(从<code>0</code>到<code>n-1</code>)</p>
<pre><code>import sys
import numpy as np
import pyqtgraph as pg
from pyqtgraph.Qt import QtCore, QtGui
class MyApp(QtGui.QWidget):
def __init__(self):
QtGui.QWidget.__init__(self)
self.central_layout = QtGui.QVBoxLayout()
self.plot_boxes_layout = QtGui.QHBoxLayout()
self.boxes_layout = QtGui.QVBoxLayout()
self.setLayout(self.central_layout)
# Lets create some widgets inside
self.label = QtGui.QLabel('Plots and Checkbox bellow:')
# Here is the plot widget from pyqtgraph
self.plot_widget = pg.PlotWidget()
# Now the Check Boxes (lets make 3 of them)
self.num = 6
self.check_boxes = [QtGui.QCheckBox(f"Box {i+1}") for i in range(self.num)]
# Here will be the data of the plot
self.plot_data = [None for _ in range(self.num)]
# Now we build the entire GUI
self.central_layout.addWidget(self.label)
self.central_layout.addLayout(self.plot_boxes_layout)
self.plot_boxes_layout.addWidget(self.plot_widget)
self.plot_boxes_layout.addLayout(self.boxes_layout)
for i in range(self.num):
self.boxes_layout.addWidget(self.check_boxes[i])
# This will conect each box to the same action
self.check_boxes[i].stateChanged.connect(self.box_changed)
# For optimization let's create a list with the states of the boxes
self.state = [False for _ in range(self.num)]
# Make a list to save the data of each box
self.box_data = [[[0], [0]] for _ in range(self.num)]
x = np.linspace(0, 3.14, 100)
self.add_data(x, np.sin(x), 0)
self.add_data(x, np.cos(x), 1)
self.add_data(x, np.sin(x)+np.cos(x), 2)
self.add_data(x, np.sin(x)**2, 3)
self.add_data(x, np.cos(x)**2, 4)
self.add_data(x, x*0.2, 5)
def add_data(self, x, y, ind):
self.box_data[ind] = [x, y]
if self.plot_data[ind] is not None:
self.plot_data[ind].setData(x, y)
def box_changed(self):
for i in range(self.num):
if self.check_boxes[i].isChecked() != self.state[i]:
self.state[i] = self.check_boxes[i].isChecked()
if self.state[i]:
if self.plot_data[i] is not None:
self.plot_widget.addItem(self.plot_data[i])
else:
self.plot_data[i] = self.plot_widget.plot(*self.box_data[i])
else:
self.plot_widget.removeItem(self.plot_data[i])
break
if __name__ == "__main__":
app = QtGui.QApplication(sys.argv)
window = MyApp()
window.show()
sys.exit(app.exec_())
</code></pre>
<p>请注意,在de<code>PlotWidget</code>中,我使用<code>plot()</code>方法添加绘图,它返回一个<code>PlotDataItem</code>,保存在调用<code>self.plot_data</code>之前创建的列表中。
有了它,您可以很容易地从<code>Plot Widget</code>中删除它并再次添加它。此外,如果您的目标是更复杂的程序,例如,可以在运行时更改每个框的数据的程序,那么如果您在<code>PlotDataItem</code>上使用<code>setData()</code>方法,则绘图将更新,而不会出现重大问题</p>
<p>正如我在开始时所说的,这应该适用于许多复选框,因为选中/取消选中复选框时调用的函数首先将每个框的实际状态与前一个框(存储在<code>self.state</code>)进行比较,并且只对对应于该特定框的绘图进行更改。这样,您就避免了每次选中/取消选中一个复选框时,为每个复选框执行一个函数,并为所有de框执行replot(如<a href="https://stackoverflow.com/users/8408080/user8408080">user8408080</a>)。我并不是说这是不好的,但是如果您增加复选框的数量和/或数据的复杂性,那么重新填充所有数据的工作量将急剧增加</p>
<p>唯一的问题是当窗口太小,无法支持大量的复选框(例如96个)时,您将不得不在另一个小部件而不是布局中组织复选框</p>
<p>下面是上面代码的一些截图:
<a href="https://i.stack.imgur.com/q87Wh.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/q87Wh.png" alt="enter image description here"/></a></p>
<p>然后将<code>self.num</code>的值更改为<code>6</code>,并向其中添加一些随机数据:</p>
<pre><code>self.add_data(x, np.sin(x)**2, 3)
self.add_data(x, np.cos(x)**2, 4)
self.add_data(x, x*0.2, 5)
</code></pre>
<p><a href="https://i.stack.imgur.com/H3hP7.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/H3hP7.png" alt="enter image description here"/></a></p>