Почему модификатор alt не запускает событие отпускания ключа при первом нажатии в Maya? - PullRequest
2 голосов
/ 01 апреля 2020

В autodesk maya 2019 я хочу записать событие нажатия / отпускания для модификаторов клавиатуры, но после добавления QPushButton к рабочему пространству контроля maya клавиша Alt ведет себя не так, как другие модификаторы.

  1. нажмите клавишу alt, Событие keyPress срабатывает
  2. отпускание клавиши Alt, отсутствие события отпускания клавиши
  3. повторное нажатие клавиши Alt, отсутствие нажатия клавиши
  4. повторное отпускание клавиши Alt, событие отпускания клавиши срабатывает

Я ожидал увидеть соответствующие события в 2 и 3.

import maya.cmds as MC
from maya import OpenMayaUI
import shiboken2
from PySide2 import QtCore, QtGui, QtWidgets
modifierKeyInverseMap = {v: k for k, v in QtCore.Qt.KeyboardModifier.values.items()}


class TestButton(QtWidgets.QPushButton):
    def __init__(self, *args):
        super(TestButton, self).__init__(*args)
        self.installEventFilter(self)

    def eventFilter(self, source, event):
        # print('-', event.type(), event, source)
        def debug():
            for k in modifierKeyInverseMap:
                if k & modifiers:
                    print('-', modifierKeyInverseMap[k])

        if event.type() == QtCore.QEvent.KeyPress:
            print('key press')
            if hasattr(event, 'modifiers'):
                modifiers = event.modifiers()
                debug()

        elif event.type() == QtCore.QEvent.KeyRelease:
            print('key release')
            modifiers = event.modifiers()
            debug()

        elif event.type() == QtCore.QEvent.Enter:
            source.setFocus()


def createUI():
    ptr = OpenMayaUI.MQtUtil.getCurrentParent()
    workspace_control = shiboken2.wrapInstance(long(ptr), QtWidgets.QWidget)
    layout = QtWidgets.QHBoxLayout()
    # workspace control has a vboxlayout placeholder on creation when direction is horizontal
    workspace_control.layout().addLayout(layout)


name = 'test'

if MC.workspaceControl(name, exists=True):
    MC.deleteUI(name)

ctrl = MC.workspaceControl(name, label='test workspace ctrl',
                           loadImmediately=True, uiScript="createUI()",
                           initialHeight=23)

MC.workspaceControl(ctrl, edit=True, dockToControl=['TimeSlider', 'top'])

ptr = OpenMayaUI.MQtUtil.findControl(ctrl)
qctrl = shiboken2.wrapInstance(long(ptr), QtWidgets.QWidget)

qlayout = qctrl.children()[-1].children()[0]

button = TestButton('yeah')
button.setFixedWidth(50)
qlayout.addWidget(button)

horizontalSpacer = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
qlayout.addItem(horizontalSpacer)

Я воссоздал эту проблему за пределами Maya, создав окно qmain с окном меню, а затем добавив к нему кнопку с помощью Eventfilter. Если я устанавливаю фильтр событий в главное окно, то обнаружение модификатора alt работает, но мне нужно детализированное управление несколькими кнопками, поэтому я хочу, чтобы EventFilters были установлены непосредственно на кнопку.

import os
import sys

from PySide2 import QtCore, QtGui, QtWidgets

modifierKeyInverseMap = {v: k for k, v in QtCore.Qt.KeyboardModifier.values.items()}


class MainWindow(QtWidgets.QMainWindow):

    def __init__(self, parent=None):
        super(MainWindow, self).__init__(parent)

        menuBar = self.menuBar()
        fileMenu = menuBar.addMenu('&File')
        fileMenu.addAction(QtWidgets.QAction('yeah', self))

        button = QtWidgets.QPushButton('Button')
        self.setCentralWidget(button)
        self.setWindowTitle('test')
        button.installEventFilter(self)

    def eventFilter(self, source, event):
        # print('-', event.type(), event, source)
        def debug():
            for k in modifierKeyInverseMap:
                if k & modifiers:
                    print('-', modifierKeyInverseMap[k])

        if event.type() == QtCore.QEvent.KeyPress:
            print('key press')
            if hasattr(event, 'modifiers'):
                modifiers = event.modifiers()
                debug()

        elif event.type() == QtCore.QEvent.KeyRelease:
            print('key release')
            modifiers = event.modifiers()
            debug()

        elif event.type() == QtCore.QEvent.Enter:
            source.setFocus()


in_maya = False
try:
    import maya.cmds
    in_maya = True
except:
    app = QtWidgets.QApplication(sys.argv)

win = MainWindow()
win.show()

win.raise_()
win.move(500, 500)

if not in_maya:
    sys.exit(app.exec_())

Редактировать: Это Кажется, это вызвано нажатием клавиши alt в главном окне с помощью меню, при котором фокус перемещается в меню «Файл» при первом отпускании клавиши alt, а затем с этого момента на кнопке не срабатывает фильтр событий, пока фокус не вернется.

...