代码在调试模式下运行但不是正常[重复]
Posted
技术标签:
【中文标题】代码在调试模式下运行但不是正常[重复]【英文标题】:Code runs in debug mode but not in normal [duplicate] 【发布时间】:2021-07-02 06:23:19 【问题描述】:我正在开发软件,其中包括使用 WHO ICD11 API 的部分。 当我运行代码时:
import json
import re
import threading
import time
from typing import Dict, List
import qdarkgraystyle as qdarkgraystyle
import requests
from PyQt5 import QtCore, QtWidgets
from PyQt5.QtCore import pyqtSignal, QThread
from PyQt5.QtWidgets import QTreeView
from threading import Lock
from gui import Ui_MainWindow
import auth
printlock = Lock()
p = print
def print(*a, **b):
with printlock:
p(*a, **b)
class g:
max = 1
progress = 0
end_workers = False
loaded_dict = None
class ApplicationWindow(QtWidgets.QMainWindow):
def __init__(self):
super(ApplicationWindow, self).__init__()
self.ui = Ui_MainWindow()
self.ui.setupUi(self)
def linearization_url():
return f"https://id.who.int/icd/release/ui.dropRevision.currentText().split('/')[0]/ui.dropRelease.currentText()('/' + ui.dropRevision.currentText().split('/')[1]) if len(ui.dropRevision.currentText().split('/')) > 1 else ''"
def download():
loader = Loader(linearization_url())
loader.statusUpdateHook.connect(updatehook)
loader.statusFinished.connect(finishedLoader)
loader.start()
def updatehook():
ui.progress.setTextVisible(True)
ui.progress.setMaximum(gl.max)
ui.progress.setValue(gl.progress)
def finishedLoader():
json.dump(gl.loaded_dict, open("dict.json"), indent=4)
def split_link(url: str) -> Dict[str, str]:
return re.search(
"https?://id.who.int/icd/release/(?P<revision>[0-9]2)/(?P<release>[^/]*)(/(?P<linearization>.*))?",
url).groupdict()
def worker(loader):
print("Worker booting...")
_token = gl.token
over = True
while not gl.end_workers:
url = ""
with loader.index_lock:
try:
url = loader.working_list[loader.index]
loader.index += 1
except IndexError:
over = False
if over:
json = request_json(url, _token)
with loader.finished_count_lock:
loader.working_dict[url] = json
if "child" in json:
for child in json["child"]:
loader.working_list.append(child)
loader.finished_count += 1
else:
over = True
def loadReleases():
token = getToken(auth.id, auth.secret)
ui.dropRelease.clear()
ui.dropRelease.repaint()
for release in request_json("https://id.who.int/icd/release/" + ui.dropRevision.currentText(), token)[
"release"]:
ui.dropRelease.addItem(split_link(release)["release"])
def getToken(clientID, clientSecret) -> str:
return requests.post('https://icdaccessmanagement.who.int/connect/token',
data='client_id': clientID, 'client_secret': clientSecret, 'scope': 'icdapi_access',
'grant_type': 'client_credentials').json()['access_token']
def request_json(link_: str, token_: str):
headers_ =
'Authorization': 'Bearer ' + token_,
'Accept': 'application/json',
'Accept-Language': 'en',
'API-Version': 'v2'
return requests.get(link_, headers=headers_).json()
class Loader(QtCore.QThread):
statusFinished = QtCore.pyqtSignal()
statusUpdateHook = QtCore.pyqtSignal()
index = 0
finished_count = 0
working_list = []
working_dict =
index_lock = Lock()
finished_count_lock = Lock()
workers = []
def __init__(self, lurl: str):
super().__init__()
self.working_list.append(lurl)
def progressUpdate(self):
gl.max = len(self.working_list)
gl.progress = self.finished_count
self.statusUpdateHook.emit()
def run(self):
for i in range(0, 20):
self.workers.append(threading.Thread(target=worker, args=(self,)))
self.workers[i].start()
while self.finished_count < len(self.working_list):
with self.index_lock:
with self.finished_count_lock:
self.progressUpdate()
time.sleep(5)
for work in self.workers:
if work.isAlive():
gl.end_workers = True
gl.loaded_dict = self.working_dict
self.statusFinished.emit()
if __name__ == "__main__":
import sys
gl = g()
gl.token = getToken(auth.id, auth.secret)
tabs: List[QTreeView] = []
app = QtWidgets.QApplication(sys.argv)
application = ApplicationWindow()
application.setStyleSheet(qdarkgraystyle.load_stylesheet())
ui = application.ui
ui.buttonDownload.clicked.connect(download)
ui.dropRevision.addItems(["10", "11/mms"])
ui.dropRevision.currentIndexChanged.connect(loadReleases)
loadReleases()
application.show()
sys.exit(app.exec_())
在 Pycharms 调试模式下,它确实是我想要的。只要在调试模式下它就可以正常工作,而在正常模式下,当触发buttonDownload.clicked
事件时,整个程序崩溃,唯一的输出是:
QThread: Destroyed while thread is still running
有人知道如何解决这个问题吗?
(出于复制目的:您需要 API 密钥才能访问 API。它们从 auth 导入为 auth.id 和 auth.secret。ID 和密钥可以从the WHO ICD11 API site 上的帐户获得)
【问题讨论】:
【参考方案1】:Loader
继承QThread
,在download
函数QThread
对象绑定到局部变量loader
,在退出函数时,此变量被垃圾收集并且绑定对象被销毁。您需要确保loader
变量超出函数的寿命,例如使其成为全局变量或从函数返回并存储在某处。
【讨论】:
以上是关于代码在调试模式下运行但不是正常[重复]的主要内容,如果未能解决你的问题,请参考以下文章
VBA Excel 在调试中运行良好,但在安全更新 KB4022174 后无法在正常模式下运行