Is it possible to make it so that at the end it is moved with the mouse cursor? - Similar to what happens when footprints are added after updating pcbnew from the schematic.
The screen and cursor moved onto the newly added footprint. This is decent.
Even without that, I found that the footprint is always selected right after adding to board. Maybe sending a keystroke “m” to Kicad could trigger mouse move? But I don’t know how to send keystroke.
Check out KiBuzzard plugin code. If I remember correctly it does exactly what you are asking for (i.e. attaches generated object to move action after it completes).
It was a bit too complicated for my liking though, but fortunately, I achieved similar by sending “m” key.
Here final code snippet:
fp : pcbnew.FOOTPRINT = pcbnew.FootprintLoad(libpath, footprint_name)
fp.SetPosition(pcbnew.VECTOR2I(0, 0))
board.Add(fp)
pcbnew.Refresh()
pcbnew.FocusOnItem(fp)
//find PCB window and send 'm' key to initiate move command:
self._pcbnew_frame = [x for x in wx.GetTopLevelWindows() if ('pcbnew' in x.GetTitle().lower() and 'python' not in x.GetTitle().lower()) or ('pcb editor' in x.GetTitle().lower())]
if len(self._pcbnew_frame) == 1:
self._pcbnew_frame = self._pcbnew_frame[0]
wnd = [i for i in self._pcbnew_frame.Children if i.ClassName == 'wxWindow'][0]
evt = wx.KeyEvent(wx.wxEVT_CHAR_HOOK)
evt.SetKeyCode(ord('m'))
wx.PostEvent(wnd, evt)
Keep in mind that shortcuts can be changed by user. You can read kicad’s user config file (they are json) or if you have some settings, let user choose the key sent at the end.
My solution is not perfect.
I found out, actually, I can only select the item with FocusOnItem(fp). But this moves the canvas, which is undesired when dragging with the mouse.
Additionally, if there was only another footprint selected, both will be moved after sending the keystroke.
I will try KiBuzzard’s clipboard solution later and post it here, as it seems optimal, even though requires extra code.
Here is the method of placing footprint with a mouse using clipboard workaround:
import pcbnew
import wx
clipboard = wx.Clipboard.Get()
if clipboard.Open():
# read file
with open(os.path.join(libpath, component_name + ".kicad_mod"), 'r') as file:
footprint_string = file.read()
clipboard.SetData(wx.TextDataObject(footprint_string))
clipboard.Close()
if self._pcbnew_frame is None:
try:
self._pcbnew_frame = [x for x in wx.GetTopLevelWindows() if ('pcbnew' in x.GetTitle().lower() and not 'python' in x.GetTitle().lower()) or ('pcb editor' in x.GetTitle().lower())]
if len(self._pcbnew_frame) == 1:
self._pcbnew_frame = self._pcbnew_frame[0]
else:
self._pcbnew_frame = None
except:
pass
# Footprint string pasting based on KiBuzzard https://github.com/gregdavill/KiBuzzard/blob/main/KiBuzzard/plugin.py
if self.IsVersion(['5.99','6.', '7.']):
if self._pcbnew_frame is not None:
# Set focus to main window and attempt to execute a Paste operation
try:
evt = wx.KeyEvent(wx.wxEVT_CHAR_HOOK)
evt.SetKeyCode(ord('V'))
#evt.SetUnicodeKey(ord('V'))
evt.SetControlDown(True)
# self.logger.log(logging.INFO, "Using wx.KeyEvent for paste")
wnd = [i for i in self._pcbnew_frame.Children if i.ClassName == 'wxWindow'][0]
# self.logger.log(logging.INFO, " Injecting event: {} into window: {}".format(evt, wnd))
wx.PostEvent(wnd, evt)
except:
# Likely on Linux with old wx python support :(
# self.logger.log(logging.INFO, "Using wx.UIActionSimulator for paste")
keyinput = wx.UIActionSimulator()
self._pcbnew_frame.Raise()
self._pcbnew_frame.SetFocus()
wx.MilliSleep(100)
wx.Yield()
# Press and release CTRL + V
keyinput.Char(ord("V"), wx.MOD_CONTROL)
wx.MilliSleep(100)
else:
# self.logger.log(logging.ERROR, "No pcbnew window found")