QThread 无法正确使用 QTimer
QThread fails to use a QTimer properly
在我的应用程序中,我有一个自定义 QThread 负责与后端通信,并使用 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 .在我传回信息之前,我正在解析一些我不想 return 并希望存储在 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:计时器无法从另一个线程启动
根据我对线程的了解和了解,QThread 中的 运行() 是另一个线程,它可能不知道主线程中发生了什么。
调试,似乎计时器仍然是 运行ning,即使它设置为 singleShot。
如有任何建议,我将不胜感激:)
我通过不使用计时器解决了这个问题。
我最终做的是:
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]
我正在尝试使用互斥锁,但它与计时器有类似的问题。
我仍然希望得到解释或处理此类问题的建议。
在我的应用程序中,我有一个自定义 QThread 负责与后端通信,并使用 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 .在我传回信息之前,我正在解析一些我不想 return 并希望存储在 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:计时器无法从另一个线程启动
根据我对线程的了解和了解,QThread 中的 运行() 是另一个线程,它可能不知道主线程中发生了什么。 调试,似乎计时器仍然是 运行ning,即使它设置为 singleShot。
如有任何建议,我将不胜感激:)
我通过不使用计时器解决了这个问题。 我最终做的是:
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]
我正在尝试使用互斥锁,但它与计时器有类似的问题。 我仍然希望得到解释或处理此类问题的建议。