title: PyQt5 add second function to thread but not work
body: <p>Previously I have tried to use Flask for doing the followings simultaneously:</p>
  
  <ul>
  <li>Display live video streaming</li>
  <li>Display real-time data streaming</li>
  <li>Control the robot car</li>
  </ul>
  
  <p>As the above is just for demonstration, with the video streaming performance not good enough, I decided to change the whole application to PyQt5 for further development and production. Now I can create the GUI for displaying live video streaming well, while the real-time data streaming cannot be done well. The error is </p>
  
  <blockquote>
    <p>QObject::startTimer: Timers can only be used with threads started with QThread</p>
  </blockquote>
  
  <p>The following is the whole program. Please help to see what's wrong in the adding thread issue. Thanks!</p>
  
  <pre><code>import sys
  from PyQt5 import QtWidgets, QtCore, QtGui
  import cv2
  from vidgear.gears import CamGear
  from random import random
  data_list=[]
  
  fps=60
  options_cam={"CAP_PROP_FRAME_WIDTH":640,"CAP_PROP_FRAME_HEIGHT":480,"CAP_PROP_FPS":fps}
  stream=CamGear(source=0,logging=False,**options_cam).start()
  
  class MainWindow(QtWidgets.QWidget):
      def __init__(self,*args):
          super(MainWindow, self).__init__()
          self.setWindowTitle('Vehicle control')
          self.grid_layout=QtWidgets.QGridLayout()
          self.video_label = QtWidgets.QLabel('Video streaming',self)
          self.video_frame = QtWidgets.QLabel(self)
          self.grid_layout.addWidget(self.video_label,0,0)
          self.grid_layout.addWidget(self.video_frame,1,0)
  
          self.data_label = QtWidgets.QLabel('Data streaming',self)
          self.data_frame = QtWidgets.QListWidget(self)
          self.grid_layout.addWidget(self.data_label,0,1)
          self.grid_layout.addWidget(self.data_frame,1,1)
          self.setLayout(self.grid_layout)
  
          #self.thread=QtCore.QThread()
          #self.thread.started.connect(self.nextFrameSlot)
          #self.thread.start()
  
          self.timer=QtCore.QTimer()
          self.timer.timeout.connect(self.video_stream)
          self.timer.start(0)
  
          self.thread=QtCore.QThread()
          self.thread.start()
  
          self.timer2=QtCore.QTimer()
          self.timer2.moveToThread(self.thread)
          self.timer2.timeout.connect(self.data_stream)
          self.timer2.start(0)
  
      def video_stream(self):
          frame = stream.read()
  
          # My webcam yields frames in BGR format
          frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
          img = QtGui.QImage(frame, frame.shape[1], frame.shape[0], QtGui.QImage.Format_RGB888)
          pix = QtGui.QPixmap.fromImage(img)
          self.video_frame.setPixmap(pix)
          QtCore.QThread.sleep(0)
  
      def data_stream(self):
          print("data stream")
          stream_data=round(random()*10,3)
          data_list.insert(0,str(stream_data)+'\n')
          if len(data_list)&gt;10:
              del data_list[-1]
          for i in range(len(data_list)):
              self.data_frame.addItem(data_list[i])
          self.data_frame.show()
          QtCore.QThread.sleep(1000)
  
  if __name__ == '__main__':
  
      import sys
      app = QtWidgets.QApplication(sys.argv)
      window = MainWindow()
      window.show()
      sys.exit(app.exec_())
  </code></pre>
  
  <p><strong>Edit:</strong> 
  Thanks @musicamante's answer. I have updated the code as follows but still have the error "segmentation fault" for the video streaming, while if I run for data stream only, the updated list can be shown. So what's wrong with the setPixmap function? Thanks again!</p>
  
  <pre><code>import sys
  from PyQt5 import QtWidgets, QtCore, QtGui
  import cv2
  from vidgear.gears import CamGear
  from random import random
  
  fps=60
  options_cam={"CAP_PROP_FRAME_WIDTH":480,"CAP_PROP_FRAME_HEIGHT":480,"CAP_PROP_FPS":fps}
  stream=CamGear(source=0,logging=False,**options_cam).start()
  
  class CamGrabber(QtCore.QThread):
      frame = QtCore.pyqtSignal(QtGui.QImage)
  
      def run(self):
          while True:
              new_frame = stream.read()
              new_frame = cv2.cvtColor(new_frame, cv2.COLOR_BGR2RGB)
              img = QtGui.QImage(new_frame, new_frame.shape[1], new_frame.shape[0], QtGui.QImage.Format_RGB888)
              self.frame.emit(img)
  
  class DataProvider(QtCore.QThread):
      data = QtCore.pyqtSignal(object)
  
      def run(self):
          while True:
              newData = round(random()*10,3)
              self.data.emit(newData)
              QtCore.QThread.sleep(1)
  
  class MainWindow(QtWidgets.QWidget):
      def __init__(self,*args):
          super(MainWindow, self).__init__()
          self.setWindowTitle('Vehicle control')
          self.grid_layout=QtWidgets.QGridLayout()
          self.video_label = QtWidgets.QLabel('Video streaming',self)
          self.video_frame = QtWidgets.QLabel(self)
          self.grid_layout.addWidget(self.video_label,0,0)
          self.grid_layout.addWidget(self.video_frame,1,0)
  
          self.data_label = QtWidgets.QLabel('Data streaming',self)
          self.data_frame = QtWidgets.QListWidget(self)
          self.grid_layout.addWidget(self.data_label,0,1)
          self.grid_layout.addWidget(self.data_frame,1,1)
          self.setLayout(self.grid_layout)
  
          self.camObject = CamGrabber()
          self.camObject.frame.connect(self.newFrame)
          self.camObject.start()
  
          self.dataProvider = DataProvider()
          self.dataProvider.data.connect(self.newData)
          self.dataProvider.start()
  
      def newFrame(self, img):
          self.video_frame.setPixmap(QtGui.QPixmap.fromImage(img))
  
      def newData(self, data):
          self.data_frame.insertItem(0,str(data))
          if self.data_frame.count() &gt; 10:
              self.data_frame.takeItem(9)
  
  if __name__ == '__main__':
  
      import sys
      app = QtWidgets.QApplication(sys.argv)
      window = MainWindow()
      window.show()
      sys.exit(app.exec_())```
  </code></pre>