kicad_pyshell/__init_py: avoid loading pcbnew module if the board editor is not open.

It happens when opening the python console from Eeschema.
In this case, and on msys2, Pgm() returns a null pointer because the pcbnew
application is not initialized, and the first call to Pgm()
from a python script crashes Kicad
This commit is contained in:
jean-pierre charras 2021-08-15 15:06:00 +02:00
parent eece74efa7
commit 7a7eee86ce
1 changed files with 34 additions and 6 deletions

View File

@ -10,22 +10,36 @@ or shown, as per user requirements.
IF makePcbnewShellWindow() is called again, a second/third shell window
can be created.
Note:
**DO NOT** import pcbnew module if not called from Pcbnew: on msys2 it creates a serious issue:
the python script import is broken because the pcbnew application is not running, and for instance
Pgm() returns a nullptr and Kicad crashes when Pgm is invoked.
"""
import wx
import sys
import os
from wx.py import crust, version, dispatcher
from .kicad_pyeditor import KiCadEditorNotebookFrame, KiCadEditorNotebook
import pcbnew
from .kicad_pyeditor import KiCadEditorNotebookFrame
from .kicad_pyeditor import KiCadEditorNotebook
class KiCadPyShell(KiCadEditorNotebookFrame):
isPcbframe = False # is True only if the board editor is open,
# i.e. if Pcbnew application exists
def __init__(self, parent):
KiCadEditorNotebookFrame.__init__(self, parent)
# Search if a pcbnew frame is open, because import pcbnew can be made only if it exists.
# frame names are "SchematicFrame" and "PcbFrame"
frame = wx.FindWindowByName( "PcbFrame" )
if frame is not None:
isPcbframe = True
def _setup_startup(self):
"""Initialise the startup script."""
# Create filename for startup script.
@ -65,7 +79,18 @@ class KiCadPyShell(KiCadEditorNotebookFrame):
module.__dict__['__builtins__'] = builtins
namespace = module.__dict__.copy()
'''
Import pcbnew **only** if the board editor exists, to avoid strange behavior if not.
pcbnew.SETTINGS_MANAGER should be in fact called only if the python console is created
from the board editor, and if created from schematic editor, should use something like
eeschema.SETTINGS_MANAGER
'''
if self.isPcbframe:
import pcbnew
self.config_dir = pcbnew.SETTINGS_MANAGER.GetUserSettingsPath()
else:
self.config_dir = ""
self.dataDir = self.config_dir
self._setup_startup()
@ -76,6 +101,7 @@ class KiCadPyShell(KiCadEditorNotebookFrame):
"PyShell_pcbnew.cfg")
self.config = wx.FileConfig(localFilename=self.config_file)
self.config.SetRecordDefaults(True)
self.autoSaveSettings = False
self.autoSaveHistory = False
self.LoadSettings()
@ -215,4 +241,6 @@ def makePcbnewShellWindow(parentid):
"""
parent = wx.FindWindowById( parentid )
frmname = parent.GetName()
return KiCadPyShell(parent)