It looks like you're new here. If you want to get involved, click one of these buttons!
My python macro creates a plugin via the architecture suggested on this page:
class MyPlugin(pya.Plugin):
def __init__(self):
super(MyPlugin, self).__init__()
def activated(self):
# do a whole bunch of beautiful things
# including spawning dialogs with 'finish'
# buttons
pass
class MyPluginFactory(pya.PluginFactory):
def __init__(self):
super(MyPluginFactory, self).__init__()
toolbar_btn = self.register(-1000, "my_plugin", "My Plugin")
def create_plugin(self, manager, root, view):
return MyPlugin()
MyPluginFactory()
When I run this macro, a new button is added to my window toolbar. When this toolbar button is clicked, it stays pressed, runs activated()
, and launches my dialogs. That's all good!
Alas when my user is finished and closes the dialogs, the plugin's toolbar button stays pressed. It undesirably cannot be clicked again. I need some way to programmatically deactivate the plugin so that its toolbar button becomes un-pressed, but remains in the toolbar, available to be clicked again and re-trigger a MyPlugin()
instantiation.
The most relevant plugin method seems to be _destroy()
, but only kills/corrupts the state of the plugin, and I expect isn't intended to be used for this purpose. So; what can I call?
Comments
Was lucky enough to accidentally find the answer in this thread! I simply call
to select another toolbar menu (the
"select"
tool incidentally), which un-presses my plugin's toolbar button, and triggers theMyPlugin
class'sdeactivated()
method.Hi TysonJones,
Not quit sure what is the correct way to exit the plug in,
the way I exit the plugin is sending a esc key command by script.
Exiting via triggering an
Esc
press seems fine too.I have a new issue with both methods however. Sometimes the conditions for my plugin have not been met (a user has not pre-selected polygons, for example) and the
activated()
function ofMyPlugin
above must "exit". That is, in lieu of displaying dialogs, it triggers plugin deactivation immediately, for instance via...The above code leaves kLayout in a bugged state where the
My Plugin
toolbar button remains pressed, and cannot be pressed again. In this state, hitting theEsc
key also does nothing. The user must manually select another toolbar tool to deactivate the plugin.I figured this is because the plugin has not had "sufficient time" after
activated()
to load completely before the toolbar trigger. So, I try to delay the deactivation viaQTimer
. Something as simple as using Qt's doc'dsingleShot
...throws an error
'getset_descriptor' object has no attribute 'instance'
, becausesingleShot
has been made a python property as per here.So, I instead attempt to verbosely create a single-shot timer, via:
where the Qt
connect
method oftimer.timeout
is documented in many places, like here.Alas this also fails with error
'pya._Signal' object has no attribute 'connect'
.The kLayout-specific
QTimer
doc says that "The object exposes a writable attribute 'timeout'. This is the setter." Alas, changing the line tostill doesn't work; now, nothing happens, and
deactivate_plugin()
is never called aftertimer.start()
.This is a horrible rabbit hole to tumble down in order to workaround a bugged implementation of what I expect to be a common kLayout macro use-case; an early-exit after input validation. What am I doing wrong?
Hi TysonJones,
I ran into similar issue, I like the user to pre-select some shapes for further process,
but failed ti find a way to exit directly using normal method.
My work around is to send a
esc
by script inmouse_moved_event
, so once the cursor moves into the layout region it'll do the check and determine whether the script should proceed or exit.This shows a hint to remind user to select something before activate the plugin.
after showing the tip at cursor, exit by calling
self.deactive()
and send theesc
key using code in previous postDear all,
thanks for this discussion!
I need to say I do not fully understand the initial request. "activated" is a callback that is not meant to triggering dialogs. It just says someone triggered this mode.
If you simply need a button in the toolbar that does something fancy, you do not need the Plugin API. This API is intended for creating interactive tools acting on the canvas. This will also create a new button in the toolbar:
Matthias