QGIS多窗口应用退出触发QBasicTimer错误的排查求助
QGIS多窗口应用退出报错与窗口关闭方式疑问
问题描述
- 开发QGIS多窗口应用时,每次退出都会弹出错误提示:
QBasicTimer::start: QBasicTimer can only be used with threads started with QThread。尝试退出时关闭所有窗口,错误仍会出现,且错误行数随退出窗口不同而变化。 - 咨询:通过表单按钮关闭窗口与点击窗口右上角叉号关闭是否存在区别?
原始代码
from qgis.core import * from qgis.gui import * import os import sys from PyQt5 import * import mainSubSysWin_design import mapAndCharWin import mapAndCharWin_design import compTechWin import compTechWin_design import locNetWin import locNetWin_design class mainSubSysWin (QtWidgets.QDialog, mainSubSysWin_design.Ui_Dialog) : def __init__(self): QtWidgets.QDialog.__init__(self) self.setupUi(self) self.compTechButt.clicked.connect(self.compTechWin) self.compTech_window = compTechWin.compTechWin() self.compTech_window.backToMainButt.clicked.connect(self.toMainWin) self.charLocalButt.clicked.connect(self.netWin) self.locNet_window = locNetWin.locNetWin() self.locNet_window.toMainButt.clicked.connect(self.toMainWin) self.mapButt.clicked.connect(self.mapChar) self.mapChar_window = mapAndCharWin.mapAndCharWin() self.mapChar_window.backMapButt.clicked.connect(self.toMainWin) def compTechWin(self): self.compTech_window.show() self.hide() def netWin(self): self.locNet_window.show() self.hide() def mapChar(self): self.mapChar_window.show() self.hide() def toMainWin(self): self.show() self.compTech_window.hide() self.mapChar_window.hide() self.locNet_window.hide() def closeWin(self): self.compTech_window.close() self.mapChar_window.close() self.locNet_window.close() self.close() def main(): QgsApplication.setPrefixPath("qgis-ltr-dev", True) qgs=QgsApplication([],True) QgsCredentials.instance() qgs.initQgis() dir_path = os.path.dirname(os.path.realpath(__file__)) QgsProject.instance().read(dir_path+'/NEWproject/qgis222.qgz') print("yep") main_app = QApplication(sys.argv) #main_app.aboutToQuit.connect(exitHandler()) window = mainSubSysWin() window.show() sys.exit(main_app.exec_()) exit_code = qgs.exec_() qgs.exitQgis() if __name__ == '__main__': main()
修改后的main函数代码
def main(): QgsApplication.setPrefixPath("qgis-ltr-dev", True) qgs=QgsApplication([],True) QgsCredentials.instance() qgs.initQgis() dir_path = os.path.dirname(os.path.realpath(__file__)) QgsProject.instance().read(dir_path+'/NEWproject/qgis222.qgz') print("yep") window = mainSubSysWin() window.show() sys.exit(qgs.exec_()) if __name__ == '__main__': main()
问题解决与说明
1. 退出报错的修复
原始代码中同时创建QApplication和QgsApplication是核心问题——QGIS应用必须以QgsApplication作为主应用实例,不能单独创建QApplication,否则会引发线程管理冲突,触发QBasicTimer错误。
修改后的代码已移除多余的QApplication,但还需补充资源清理逻辑:
- 重写主窗口的
closeEvent方法,确保子窗口先被正确关闭 - 保证
qgs.exitQgis()被执行,清理QGIS核心资源
调整后的完整关键代码示例:
class mainSubSysWin (QtWidgets.QDialog, mainSubSysWin_design.Ui_Dialog) : # 保留原有代码... def closeEvent(self, event): # 关闭所有子窗口 self.compTech_window.close() self.mapChar_window.close() self.locNet_window.close() event.accept() def main(): QgsApplication.setPrefixPath("qgis-ltr-dev", True) qgs=QgsApplication([],True) QgsCredentials.instance() qgs.initQgis() dir_path = os.path.dirname(os.path.realpath(__file__)) QgsProject.instance().read(dir_path+'/NEWproject/qgis222.qgz') print("yep") window = mainSubSysWin() window.show() exit_code = qgs.exec_() qgs.exitQgis() sys.exit(exit_code) if __name__ == '__main__': main()
额外注意:若子窗口类(如compTechWin)存在定时器或线程资源,需在其closeEvent中停止相关资源,避免残留。
2. 两种窗口关闭方式的区别
- 点击右上角叉号:触发窗口的
closeEvent事件,Qt按默认流程处理(如检查窗口是否可关闭、释放资源等),若为主窗口,还会触发应用的aboutToQuit信号。 - 按钮调用
close():同样触发closeEvent事件,但可在按钮点击槽函数中添加自定义逻辑(如保存数据、确认关闭)后再调用close();若直接调用hide()则仅隐藏窗口,不释放资源。
简言之:两种方式最终都会触发closeEvent,但按钮关闭可提前加入自定义逻辑,叉号是系统默认触发的关闭流程。
内容的提问来源于stack exchange,提问作者poostyak
相关产品推荐
相关产品推荐

