【问题标题】:QThread fails to use a QTimer properlyQThread 无法正确使用 QTimer
【发布时间】:2017-01-01 03:52:29
【问题描述】:

在我的应用程序中,我有一个自定义 QThread 负责与后端通信,并使用来自 run() 方法的 url 和数据调用实用函数:

class SomeThread(QtCore.QThread):
  def __init__(self, parent=None...):
    QtCore.QThread.__init__(self, parent)
    ...
  def run(self):
    final_desired_content = some_utility_method(url, data ...)
    # emitting success with final_desired_content

在实用程序方法中,我正在创建一个 http POST,返回响应,解析响应,并最终将所需信息传递给上述线程变量 final_desired_content。在我将信息传回之前,我正在解析一些我不想返回的更多信息,并希望将其存储在 SomeClass 单例实例中:

def some_utility_method( ... ):
  ...
  return response_parsing(response)

def response_parsing(response):
  ...
  some_file.SomeClass.instance().setNewData(otherData)
  return mainParsedData

因为可能有多个线程在几秒钟内(特别是在应用程序启动期间)联系BE,所以我想防止在过去之前写入数据(可以将我们忽略的数据丢弃):

class SomeClass(QtCore.QObject):

  _instance = None

  @classmethod
  def instance(klass):
    if not klass._instance:
      klass._instance = SomeClass()
    return klass._instance

  def __init__(self):
    QtCore.QObject.__init__(self)
    self._recentlyUpdatedTimer = QtCore.QTimer()
    self._recentlyUpdatedTimer.setSingleShot(True)
    self._recentlyUpdatedTimer.timeout.connect(self._setOkToUpdateCB)
    self._storedData = None
    self._allowUpdate = True

  def _setOkToUpdateCB(self):
    self._allowUpdate = True

  def setNewData(self, newData):
    if self._allowUpdate:
      print "UPDATING!"
      self._allowUpdate = False
      self._storedData = newData
      self._recentlyUpdatedTimer.start(<some_time>)
    else:
      print "BLOCKED!" # ok to ignore newData

问题是这个成功更新一次,然后第二次更新成功后,我得到这个错误:QObject::startTimer: Timers cannot be started from another thread

根据我对线程的了解和阅读,QThread 中的 run() 是另一个线程,它可能不知道主线程中发生了什么。 调试中,定时器似乎仍在运行,即使它设置为singleShot。

我将不胜感激任何建议:)

【问题讨论】:

    标签: python pyqt pyqt5 qthread qtimer


    【解决方案1】:

    我通过不使用计时器解决了这个问题。 我最终做的是:

    class SomeClass(QtCore.QObject):
      ...
      DATA_EXPIRE_THRESHOLD = 3
      ...
      def __init__(self):
        ...
        self._counter = 0 # Just for debugging
        self._dataExpireTime = None
        self._data = None
    
      def setNewData(self, new_data):
        self._counter += 1
        if self._dataExpireTime is None or self._isExpired():
          print "self._isExpired(): [%s], counter: [%s]" % (self._isExpired(), self.counter)
          self._data = new_data
          self._dataExpireTime = time.time() + self.DATA_EXPIRE_THRESHOLD
    
      def _isExpired(self):
        return time.time() >= self._dataExpireTime 
    

    所以将阈值设置为三秒,输出为:

    self._isExpired(): [True], counter: [1] 
    self._isExpired(): [True], counter: [2]
    self._isExpired(): [True], counter: [6]
    self._isExpired(): [True], counter: [15]
    self._isExpired(): [True], counter: [17]
    self._isExpired(): [True], counter: [18]
    

    我试图使用互斥锁,但它与计时器有类似的问题。 对于处理此类问题,我仍然希望得到解释或建议。

    【讨论】:

      猜你喜欢
      • 2013-10-15
      • 2019-02-01
      • 1970-01-01
      • 1970-01-01
      • 2021-01-08
      • 2012-05-16
      • 2018-06-27
      • 2022-08-05
      • 1970-01-01
      相关资源
      最近更新 更多