问题描述
我已经实现了一个 sync 块
,它使用 input_items
值在它的 work
函数中绘图.现在的问题是绘图机制对于输入流来说不够快(input_items
的值不断变化).
I have implemented a sync block
which plots inside its work
function using the input_items
values. Now the problem is that the plotting mechanism isn't fast enough for the input stream ( the value of input_items
keeps on changing ).
我已尝试尽可能简化代码并添加注释.这是:
I have tried to simplify the code as much as possible and added comments. Here it is:
....
import matplotlib
from matplotlib.backends.backend_wxagg import FigureCanvasWxAgg as FigCanvas
from matplotlib.backends.backend_wx import NavigationToolbar2Wx
from matplotlib.figure import Figure
temp = ''
class xyz(gr.sync_block):
def __init__(self,parent,title,order):
a = []
self.count = 1
gr.sync_block.__init__(self,
name="xyz",
in_sig=[numpy.float32,numpy.float32],
out_sig=None)
self.win = xyzPlot(parent) #I have a Top Block(wxFrame). I am just making it the parent of xyzPlot(wxPanel) here.
def work(self, input_items, output_items):
global temp
if (self.count == 1):
temp = input_items+list()
bool = not(np.allclose(temp,input_items))#bool will be true if the value of `input_items` changes.
.......
#the code that evaluates z1,z2 depending on the value of input_items
.......
if ( bool or self.count == 1 ):
#If bool is true or it is the first time then I am calling plot() which plots the graph.
self.win.plot(tf(self.z1,self.z3),None,True,True,True,True)
self.count = 0
temp = input_items+list()
return len(input_items[0])
class xyzPlot(wx.Panel):
def __init__(self, parent, dB=None, Hz=None, deg=None):
wx.Panel.__init__(self , parent , -1 ,size=(600,475))
self.fig = Figure()
self.axes = self.fig.add_subplot(111)
def plot(self, syslist, omega=None, dB=None, Hz=None, deg=None, Plot=True, *args , **kwargs):
self.axes.clear() #I clear the graph here so that new values can be plotted.
.....
self.axes.semilogx(omega,mag,*args,**kwargs)
self.canvas = FigCanvas(self, -1, self.fig)
self.canvas.draw()
如您所见,我正在使用 wxPython,但是每当我将 input_items
的值更改得太快时,面板就会冻结(如果我缓慢更改它,它会正常工作).有什么建议吗?我是新手.
As you can see I am working with wxPython but the panel freezes whenever I change the value of input_items
too fast ( It works fine if I change it slowly ). Any recommendations? I am new to this.
推荐答案
引用 另一个答案我给出了:
这也会很快出现多线程问题.要明确:什么你正在尝试做(从块线程调用绘图函数)是有问题,通常不起作用.
问题在于您在复杂的多线程环境中工作:
The problem is that you're working in a complex multithreading environment:
- 每个 GNU Radio 块都在自己的线程中工作
- WX Gui 主循环持续运行以更新屏幕.
您在这里所做的是,从 GNU Radio 块线程更改窗口中显示的内容.这是一件坏事,因为它改变了 WX Gui 线程上下文中的内容.这可以工作,如果这些更改不冲突,并且如果 WX Gui 线程在您更改数据时没有访问此类数据(在某些时候,它必须访问它 -- 否则,没有人会更新您的窗口).
What you're doing here is, from a GNU Radio block thread, change what is shown in the window. That is a bad thing, because it changes things that are in the context of the WX Gui thread. This can work, if these changes don't conflict, and if the WX Gui thread doesn't access this kind of data while you're changing it (at some point, it has to access it -- otherwise, noone will update your window).
这是所有类型的更新 GUI 的共同问题,不仅仅是 GNU Radio!
This is a problem common to all kind of updated GUIs, not only to GNU Radio!
是否发生这种情况只是概率问题:随着显示更新缓慢,您发生冲突的概率较低,但如果您经常更新,则接近 1.
Whether or not that happens is a mere case of probability: With a slowly updated display, your probability of conflict is low, but when you update often, it approaches 1.
现有的可视化是用 C++ 编写的,并且非常小心地以正确的方式做事——也就是说,让你的 Gui 工具包(在你的情况下是 WX,尽管我明确推荐并推荐,远离那个) 知道需要更新的东西,然后给 WX 提供一个函数来更新自己线程中的显示.
The existing visualizations are written in C++ and take very great care to do things the right way -- which is, letting your Gui toolkit (WX in your case, though I explicitely recommend, and have recommended, to move away from that) know that things need to be updated, and then offering WX a function to update the display in its own thread.
这篇关于由于 GNU Radio 块的快速输入流而导致绘图冻结的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!