[英]Pyqt5 threading can't work (Fatal Python error: could not acquire lock)
我已經閱讀了一堆QThread教程和SO Answers。 但是我無法使線程工作。 大多數情況下,它只運行一次或打印錯誤消息。 如果我在應用程序啟動后立即啟動線程,則可以正常工作,但是我希望線程在某些功能后運行,因為我想先設置目錄位置。
文件結構的排列如下:
App.py
Controllers/
main_controller.py
recorder.py
Model/
model.py
Views/
main_view.py
App.py
import sys
from PyQt5.QtWidgets import QApplication
from Model.model import Model
from Controllers.main_controller import MainController
from Views.main_view import MainView
class App(QApplication):
def __init__(self, sys_argv):
super().__init__(sys_argv)
self.model = Model()
self.main_controller = MainController(self.model)
self.main_view = MainView(self.model, self.main_controller)
if __name__ == "__main__":
app = App(sys.argv)
sys.exit(app.exec_())
model.py
from PyQt5.QtCore import QObject
class Model(QObject):
def __init__(self):
super().__init__()
self.directory = ""
def get_directory(self):
return self.directory
def set_directory(self, directory):
self.directory = directory
main_view.py
from PyQt5.QtWidgets import QMenu, QSystemTrayIcon, QMainWindow, QFileDialog
from PyQt5 import QtGui
from PyQt5.QtWidgets import QApplication
from Controllers.recorder import Recorder
class MainView(QMainWindow):
def __init__(self, model, main_controller):
super().__init__()
self._model = model
self._main_controller = main_controller
# UI
icon = QtGui.QIcon("icon24x24.png")
menu = QMenu()
start_action = menu.addAction("Start Recording")
stop_action = menu.addAction("Stop Recording")
self.tray = QSystemTrayIcon()
self.tray.setIcon(icon)
self.tray.setContextMenu(menu)
self.tray.show()
start_action.triggered.connect(self.start_app)
stop_action.triggered.connect(self.stop_app)
self.recordThread = Recorder()
def start_app(self):
directory = QFileDialog.getExistingDirectory(self, "Select Directory")
self._main_controller.set_directory(directory)
self.start_thread()
def start_thread(self):
self.recordThread.start()
def stop_app(self):
self.recordThread.terminate()
QApplication.instance().quit()
print("app stopped")
main_controller.py
from PyQt5.QtCore import QObject
class MainController(QObject):
def __init__(self, model):
super().__init__()
self._model = model
def set_directory(self, directory):
self._model.set_directory(directory)
recorder.py
import time
from PyQt5.QtCore import QThread, QTimer, pyqtSignal
from Model.model import Model
class Recorder(QThread):
job_done = pyqtSignal()
def __init__(self):
QThread.__init__(self)
self._model = Model()
def __del__(self):
self.wait()
def run(self):
while True:
print("I am the loop")
print(self._model.get_directory())
# time.sleep(4 - time.time() % 4)
QThread.sleep(4)
print("now is {}".format(time.time()))
self.job_done.emit()
根據各種教程,我嘗試使用各種樣式,包括Qthread,QObject,pyqtsignal。 但對我沒有任何作用。 它要么只是打印“我就是循環”,然后退出。 或打印
I am the loop
Fatal Python error: could not acquire lock for <_io.BufferedWriter name='<stdout>'> at interpreter shutdown, possibly due to daemon threads
Thread 0x00007f5d1bfff700 (most recent call first):
File "/App/Controllers/recorder.py", line 20 in run
Current thread 0x00007f5d3458f700 (most recent call first):
Aborted
謝謝
您的代碼沒有錯。 調用QFileDialog.getExistingDirectory
后,應用立即關閉,因為這是Qt的本質。
關閉所有Windows時退出Qt
該應用已關閉,因為您不再有任何窗口。 您的應用程序沒有任何窗口,但QSystemTrayIcon()
。 將setQuitOnLastWindowClosed()
設置為False可以解決此問題。
yourApp.setQuitOnLastWindowClosed(False)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.