Python 基于ROS订阅数据的补录图
架构Python 基于ROS订阅数据的补录图,python,pyqt,ros,qwt,Python,Pyqt,Ros,Qwt,架构 def initUI(self): # x11.XInitThreads() # xlib.XInitThreads() # initialising the window QtGui.QWidget.__init__(self) # self.setGeometry(300, 300, 160, 1000) # self.setWindowTitle('Visualizer') # main layout se
def initUI(self):
# x11.XInitThreads()
# xlib.XInitThreads()
# initialising the window
QtGui.QWidget.__init__(self)
# self.setGeometry(300, 300, 160, 1000)
# self.setWindowTitle('Visualizer')
# main layout
self.layout = QtGui.QVBoxLayout(self)
# Creating the elements in this widget
a = QtGui.QLabel("Navigation", self)
a.setStyleSheet("QLabel{ background-color: white; color: black; font-size: 25px; }")
self.plot = Qwt.QwtPlot(self)
self.plot.setCanvasBackground(Qt.black)
self.plot.setAxisTitle(Qwt.QwtPlot.xBottom, 'Time')
self.plot.setAxisScale(Qwt.QwtPlot.xBottom, 0, 10, 1)
self.plot.setAxisTitle(Qwt.QwtPlot.yLeft, 'Temperature')
self.plot.setAxisScale(Qwt.QwtPlot.yLeft, 0, 250, 40)
self.plot.replot()
self.curve = Qwt.QwtPlotCurve('')
self.curve.setRenderHint(Qwt.QwtPlotItem.RenderAntialiased)
pen = QPen(QColor('limegreen'))
pen.setWidth(2)
self.curve.setPen(pen)
self.curve.attach(self.plot)
self.layout.addWidget(a)
self.layout.addWidget(self.plot)
def listener(self):
rospy.init_node('listener', anonymous=True)
rospy.Subscriber(TOPIC_NAME, String, self.callback)
def callback(self, data):
self.xData.append(self.counter + 1)
self.yData.append(int(str(data.data)))
self.counter += 1
self.curve.setData(self.xData, self.yData)
self.plot.replot()
我有一个阴谋。图中有一条曲线。
我在文件中有一个节点和一个订阅服务器。此订阅服务器订阅正在发布的某些浮点数据。
每次发布某些数据时,我都会通过将新数据点添加到现有集合来更新曲线
问题
图表未正确更新。由于数据每秒都会出现,GUI会被挂起,一段时间后,GUI会由于分段错误而中止
代码
def initUI(self):
# x11.XInitThreads()
# xlib.XInitThreads()
# initialising the window
QtGui.QWidget.__init__(self)
# self.setGeometry(300, 300, 160, 1000)
# self.setWindowTitle('Visualizer')
# main layout
self.layout = QtGui.QVBoxLayout(self)
# Creating the elements in this widget
a = QtGui.QLabel("Navigation", self)
a.setStyleSheet("QLabel{ background-color: white; color: black; font-size: 25px; }")
self.plot = Qwt.QwtPlot(self)
self.plot.setCanvasBackground(Qt.black)
self.plot.setAxisTitle(Qwt.QwtPlot.xBottom, 'Time')
self.plot.setAxisScale(Qwt.QwtPlot.xBottom, 0, 10, 1)
self.plot.setAxisTitle(Qwt.QwtPlot.yLeft, 'Temperature')
self.plot.setAxisScale(Qwt.QwtPlot.yLeft, 0, 250, 40)
self.plot.replot()
self.curve = Qwt.QwtPlotCurve('')
self.curve.setRenderHint(Qwt.QwtPlotItem.RenderAntialiased)
pen = QPen(QColor('limegreen'))
pen.setWidth(2)
self.curve.setPen(pen)
self.curve.attach(self.plot)
self.layout.addWidget(a)
self.layout.addWidget(self.plot)
def listener(self):
rospy.init_node('listener', anonymous=True)
rospy.Subscriber(TOPIC_NAME, String, self.callback)
def callback(self, data):
self.xData.append(self.counter + 1)
self.yData.append(int(str(data.data)))
self.counter += 1
self.curve.setData(self.xData, self.yData)
self.plot.replot()
调用这些函数:-
self.listener()
self.initUI()
一旦调用了侦听器,订户就会自动与回调函数关联。回调函数查看新数据,将其添加到y轴,然后重新绘制图形
错误
每次发布新数据点时,我都会遇到此错误:-
QCoreApplication::sendPostedEvents: Cannot send posted events for objects in another thread
QPixmap: It is not safe to use pixmaps outside the GUI thread
QPixmap: It is not safe to use pixmaps outside the GUI thread
QPainter::begin: Paint device returned engine == 0, type: 2
QPainter::setPen: Painter not active
QPainter::setBrush: Painter not active
QPainter::drawRects: Painter not active
QPainter::begin: Paint device returned engine == 0, type: 2
QPainter::translate: Painter not active
QPainter::save: Painter not active
QPainter::setRenderHint: Painter must be active to set rendering hints
QPainter::save: Painter not active
QPainter::setPen: Painter not active
QPainter::restore: Unbalanced save/restore
QPainter::restore: Unbalanced save/restore
QPainter::end: Painter not active, aborted
我不理解这个错误
关于出版商的信息
ROS遵循这种模式。我已经创建了一个发布随机整数的节点。该整数应绘制在图形上
规格
Ubuntu 12.04
ROS Hydro
PyQt4
Qwt5
您的
回调
方法正在线程中运行。不能从另一个线程更新Qt GUI对象。这就是为什么您会看到错误并得到错误
解决办法是:
- 在回调中,将数据附加到列表中。使用从主线程启动的
定期检查列表的更新,并重新打印图表(这不是理想的解决方案,但可能会完成任务)QTimer
- 在回调中,将数据放入python
中。在从此队列读取时使用Queue.Queue()
块,并在每次从QThread
读取内容时发出qt信号(其中包含数据)。将主线程中的方法连接到此qt信号。因此,主线程中的方法可以获取数据,并可以从主线程更新绘图队列