How to do key press and key release in script please?

Are you still using actions to assign shortcuts? As I told you won’t get a keypress ans keyrelease events from keys assigned to any action?

I still don’t really understand what exactly you eant to do with all those buttons? Does it really require pressing 4 keys at once? Can’t you start with just one button not assigned to anything and try to do what needs to be done then?

None of the four keys work right? How about just searching for “Key_X” and getting it’s modifiers with event.modifiers() - if x is not assigned to any action in krita it should give you the event on pressed x, and you can check if all of the needed modifiers were already pressed.

In the code above you can see that I’m actually using shortcuts the same way you have (hardcoded) not from krita, I decided not to try to figure out that part and just do it the same way as you :wink:

Pressing multiple keys at once itself is not a problem if the propagation wasn’t caught somewhere else :frowning:

One of my test cases would be multikey shortcut (you know you don’t always have just one single letter available (especially in Krita since like every key is already taken or vast majority).

But again these itself are not the problem the problem is that all the keys taken by Krita I think it’s the same problem you mentioned so I’m looking for some way around it if possible.

Or maybe my code is wrong in some way but I’m looping through shortcuts list as you do to find which key was pressed. Did I implement it wrong? In the code there’s line:
if event.type() == QEvent.KeyPress:
I’d eventually change it to:
if event.type() == QEvent.KeyPress: and event.key() == Qt.Key_X:
To get only for X key but my problem is that if event.type() == QEvent.KeyPress: doesn’t give me anything to begin with so filtering out X doesn’t make a difference.

I’m a bit lost now :cry:

The code looks ok.

So basically there are no keypress events at all, even if you press a key that is not assigned to any action or canvas input in krita itself?

As I already said, I don’t think you can get those events for keys assigned to any action in krita.

this looks ballzy to me. if you delete this and test to just a single key doing the whole process will it work?
if it was me I would probably discriminate every key (that you want to use) with single ifs before trying something like this for the keyboard. not to mention if your on linux I am sure this will probably clog your system pretty fast. if I have to imagine I think this would cause flickering of some sort but i would have to test to be sure, but maybe it works and I dont know.

You dont need to install the event filter inside the create actions filter you should opt for one or another method. you can place the installation of the event filter in the init function instead per example.

I must say I was following the code now too for Extensions, and now I have too some questions on how to proceed.

class BlankExtension(Extension):

    def __init__(self, parent):
            super(BlankExtension, self).__init__(parent)

    class mdiAreaFilter(QMdiArea):
        def __init__(self, parent=None):
            super().__init__(parent)

        def eventFilter(self, obj, event):
            if (event.type() == QEvent.KeyPress and event.key() == Qt.Key_A):
                Krita.instance().action('mirror_canvas').trigger()
             return False

    def setup(self):
        pass

    def createActions(self, window):
        # Install Event Filter
        self.mdiAreaFilter = self.mdiAreaFilter()
        window.qwindow().centralWidget().findChild(QMdiArea).installEventFilter(self.mdiAreaFilter)

Krita.instance().addExtension(BlankExtension(Krita.instance()))

if I do this the shortcut is applied always False or like a double press of the key rendering it void.
However if I use a shortcut for something like a tool the double press does not affect it negativily as it will activate twice in a row?
Am I missing something?

@EyeOdin
Ballzy, well for the time being from the code I’m not using it, I’m not even checking for specific key, the code has only one if
if event.type() == QEvent.KeyPress:
And then it should technically print with Dialog, but it doesn’t unless (as describbed earlier about losing focus for app with alt).

Though I don’t think it’s that bad or is it? I just need to go through the array of shortcuts which has 4 length currently.

The for loop doesn’t block it even commenting it out makes no difference, the only way the keypress is registered is if I press alt (release it then) and then I hit for example ctrl. This way it works ok but obviously that’s not ok. Especially since this is probably a win behaviour intruding in (alt is what you usually press to get to the top menu of programs as default).

I’ll check the different even install method.

So to sum it up as in the code above there is no condition for shortcuts, right now I’m literally just trying to get a keyPress event on qwindow but it’s not working properly I think it’s because it already has something like that built in to catch keybinds in Krita and maybe I can’t use it like that?
I assume keyreleaes works fine simply because Krita probably doesn’t use it for anything (?).

@wojtryb
Yeah I think Krita has an eventfilter for keypress on at least QWindow or has some other means to catch key presses for it’s structure for keybinds and that’s interfering here mabye (?). While keyRelease is probably not used so it’s free.

Sry I can’t help much with your code :’-( To be honest I don’t even understand it from your description.

Tomorrow I want to check if I can use it for unassigned keys (need to unassigns something first) and I wonder if I keybinds from dockers can be used for the whole canvas or only if mouse over the docker?

Thanks guys. I’m not sure how to lock this thread but I finished my little plugin.

Eventually I decided to go with toggle instead of trigger to simulate keypress plus QTimer and keyRelease to simulate release.

I haven’t figured out a better way to do this (turns out my original way wasn’t usable on tablets I tested since pen buttons and dispaly buttons don’t trigger the trigger action all the time as keyboard does so my original way worked only with keyboard with a slight “lag” at the beginning since it seems first trigger call is immediate while the one or two after aren’t and then it’s a smooth ride for whatever reason.

Shortcuts might actually not be exposed to python (I’m not 100% sure but in docs I found something related to shortcuts in sections outside python so I evnetually gave up on that). But since I use toggle instead of event.keyPress I can utilize built-in shortcuts from Krita anyway so this solved my shortcut issue (I can’t register them for release event properly but it’s not a problem for my plugin - at least it’s just a minor inconvenience).

Git link is here I thnanked both of you @EyeOdin , @wojtryb for helping me out guys :slight_smile:
It was a pain, I don’t even know what kind of bugs are awaiting me but on my system it works just fine so far.

https://github.com/viksl/krita-plugin-custom-canvas-rotation/14722

I hope it will serve as a stepping stone for the same functionality getting one day into krita directly (definitely a cleaner solution than what I have xD).

Thanks one more time!

@wojtryb

I managed to get the shortcuts working, here is how to use built in shortcuts in eventFilter:

    def eventFilter(self, obj, e):
        if e.type() == QEvent.KeyRelease:
            Dialog(Krita.instance().action('KritaShape/KisToolBrush').shortcut().matches(e.key()))
            
        return False

Here for test purposes I used a KritaShape/KisToolBrush but you can use any action that has a shortcut assigned, for example I use my plugins action name which results in a match with my shortcut set in Krita - Settings - Shortcuts (shortcut defined in .action file is default and works just fine too).

Though I can’t figure out that keyPress event. Instead I use an action.trigger(), with action..setAutoRepeat(False) this way the trigger works just once for keyPress and then I use release in eventFilter for key release with shortcut().matches(e.key()) to make sure I only get my assigned shortcut.

For some weird reason when you release a key I get multiple keyRelease events even when checking for isAutoRepeat so I had to make bool variable which I assign in trigger.connect(methodName) <-- methodName method this way I was able to remove the timers from my code without getting multiple calls to functions

I hope this helps.

EDIT: Dialog is just my personal class to print results nothing specil and no need fo it.

1 Like

Oh, that’s wonderful! Big thanks for that. I’ll check it out once I have time and possibly update my addon, so that it’s not necessary for the users to open plugin code.

1 Like