PySide2 QThread Error: QThread: Destroyed while thread is still running
PySide2 QThread Error: QThread: Destroyed while thread is still running
我是 PySide2 的新手。我只是想启动一个示例应用程序并在应用程序启动时启动一个线程,并希望在应用程序关闭时停止线程。当我关闭应用程序时,出现以下错误:
QThread:在线程仍然 运行 时被销毁。
sample_ui.py 是我从 sample_ui.ui
转换而来的 python 文件
代码:
import time
import sys
import sample_ui
from PySide2 import QtWidgets
from PySide2 import QtCore
class MainWindow(QtWidgets.QMainWindow):
def __init__(self, parent=None):
super(MainWindow, self).__init__(parent)
main_window_ui = sample_ui.Ui_MainWindow()
main_window_ui.setupUi(self)
self.custom_thread = CustomThread()
self.custom_thread.start()
def closeEvent(self, event):
self.custom_thread.stop()
QtWidgets.QMainWindow.closeEvent(self, event)
class CustomThread(QtCore.QThread):
def __init__(self):
super(CustomThread, self).__init__()
def run(self):
while self.isRunning():
print("Thread is Running")
time.sleep(1)
def stop(self):
print("Thread Stopped")
self.quit()
if __name__ == '__main__':
app = QtWidgets.QApplication()
main_window = MainWindow()
main_window.show()
sys.exit(app.exec_())
输出:
Thread is Running
Thread is Running
Thread is Running
Thread Stopped
QThread: Destroyed while thread is still running
如果您的线程没有事件循环,QThread::quit()
什么都不做。您应该在 run()
中使用 "turns off" while
的标志,而不是检查 QThread::isRunning()
returns 的内容。此外,建议始终添加具有特定时间限制的 QThread::wait()
,然后添加(作为备用计划)QThread::terminate()
。
就像实验一样,在调用 stop()
函数后添加对 QThread::isRunning()
的检查并查看它 returns.
解释:
默认情况下,QThread 运行() 方法具有以下实现:
// https://github.com/qt/qtbase/blob/5.14.1/src/corelib/thread/qthread.cpp#L601
void QThread::run()
{
(void) exec();
}
换句话说,运行 方法执行一个事件循环,但是当覆盖该方法时,您将通过 while 循环删除事件循环。
另一方面,如果 the Qt docs 被审查:
void QThread::quit()
Tells the thread's event loop to exit with return code 0 (success).
Equivalent to calling QThread::exit(0).
This function does nothing if the thread does not have an event loop.
(强调我的)
因此,如果没有事件循环,则 quit 方法将不执行任何操作。
解决方案:
一个可能的解决方案是使用isInterruptionRequested()
and requestInterruption()
since the first one indicates the state of the flag and the second one changes the state of that flag. On the other hand you have to wait for the thread to finish executing using the wait()
方法:
class CustomThread(QtCore.QThread):
def run(self):
while not self.isInterruptionRequested():
print("Thread is Running")
time.sleep(1)
def stop(self):
print("Thread Stopped")
self.requestInterruption()
self.wait()
我是 PySide2 的新手。我只是想启动一个示例应用程序并在应用程序启动时启动一个线程,并希望在应用程序关闭时停止线程。当我关闭应用程序时,出现以下错误: QThread:在线程仍然 运行 时被销毁。 sample_ui.py 是我从 sample_ui.ui
转换而来的 python 文件代码:
import time
import sys
import sample_ui
from PySide2 import QtWidgets
from PySide2 import QtCore
class MainWindow(QtWidgets.QMainWindow):
def __init__(self, parent=None):
super(MainWindow, self).__init__(parent)
main_window_ui = sample_ui.Ui_MainWindow()
main_window_ui.setupUi(self)
self.custom_thread = CustomThread()
self.custom_thread.start()
def closeEvent(self, event):
self.custom_thread.stop()
QtWidgets.QMainWindow.closeEvent(self, event)
class CustomThread(QtCore.QThread):
def __init__(self):
super(CustomThread, self).__init__()
def run(self):
while self.isRunning():
print("Thread is Running")
time.sleep(1)
def stop(self):
print("Thread Stopped")
self.quit()
if __name__ == '__main__':
app = QtWidgets.QApplication()
main_window = MainWindow()
main_window.show()
sys.exit(app.exec_())
输出:
Thread is Running
Thread is Running
Thread is Running
Thread Stopped
QThread: Destroyed while thread is still running
QThread::quit()
什么都不做。您应该在 run()
中使用 "turns off" while
的标志,而不是检查 QThread::isRunning()
returns 的内容。此外,建议始终添加具有特定时间限制的 QThread::wait()
,然后添加(作为备用计划)QThread::terminate()
。
就像实验一样,在调用 stop()
函数后添加对 QThread::isRunning()
的检查并查看它 returns.
解释:
默认情况下,QThread 运行() 方法具有以下实现:
// https://github.com/qt/qtbase/blob/5.14.1/src/corelib/thread/qthread.cpp#L601
void QThread::run()
{
(void) exec();
}
换句话说,运行 方法执行一个事件循环,但是当覆盖该方法时,您将通过 while 循环删除事件循环。
另一方面,如果 the Qt docs 被审查:
void QThread::quit()
Tells the thread's event loop to exit with return code 0 (success). Equivalent to calling QThread::exit(0).
This function does nothing if the thread does not have an event loop.
(强调我的)
因此,如果没有事件循环,则 quit 方法将不执行任何操作。
解决方案:
一个可能的解决方案是使用isInterruptionRequested()
and requestInterruption()
since the first one indicates the state of the flag and the second one changes the state of that flag. On the other hand you have to wait for the thread to finish executing using the wait()
方法:
class CustomThread(QtCore.QThread):
def run(self):
while not self.isInterruptionRequested():
print("Thread is Running")
time.sleep(1)
def stop(self):
print("Thread Stopped")
self.requestInterruption()
self.wait()