MITK交互¶
1 屏蔽键盘交互¶
基于mitk框架开发的交互通过 statemachine 和 config 的配置文件件实现自定义。mitk(vtk)默认操作,按下不同按键+左键实现不同操作,不同按键还有组合,比如 shift+ctrl+左键 缩放模型。实际给用户使用时不需要这么多操作。
项目中把所有xml交互全部重新定义过,还拓展了很多自定义交互。交付给用户使用后偶现了一次鼠标无法交互模型。排查后发现是由于键盘某个按键被卡住了。需要调整为 shift alt ctrl
无论按下一个还是多个,均可以通过左键旋转,中键平移。
没有找到可以直接屏蔽的设置,先尝试通过加 <attribute name="Modifiers" value="XXX"/>
来实现,但是每个交互都有 初始、结束、执行中 三个状态,不同按键排列组合有6种,维护很困难。
研究了下框架下交互传递的逻辑,交互保存在 EvnetConfig中,传递到 DataInteractor 会检擦自己的是否定义对应交互,有的话检擦 stateMachine 是否可以做出响应。
bool mitk::EventStateMachine::HandleEvent(InteractionEvent *event, DataNode *dataNode)
{
if (!m_IsActive)
return false;
if (!FilterEvents(event, dataNode))
{
return false;
}
// Get the transition that can be executed
mitk::StateMachineTransition::Pointer transition = GetExecutableTransition(event);
// check if the current state holds a transition that works with the given event.
if (transition.IsNotNull())
{
// all conditions are fulfilled so we can continue with the actions
m_CurrentState = transition->GetNextState();
// iterate over all actions in this transition and execute them
const ActionVectorType actions = transition->GetActions();
for (auto it = actions.cbegin(); it != actions.cend(); ++it)
{
try
{
ExecuteAction(*it, event);
}
catch (const std::exception &e)
{
MITK_ERROR << "Unhandled excaption caught in ExecuteAction(): " << e.what();
return false;
}
catch (...)
{
MITK_ERROR << "Unhandled excaption caught in ExecuteAction()";
return false;
}
}
return true;
}
return false;
}
在需要屏蔽 xml 的自定义的 DataInteractor 类中,重写 FilterEvents 并把对应的 Event 中 Modifiers 置为空即可。
bool NTBoneInteractor3D::FilterEvents(InteractionEvent *interactionEvent, DataNode * /*dataNode*/)
{
if (interactionEvent->GetSender() == nullptr)
return false;
if (interactionEvent->GetSender()->GetMapperID() == BaseRenderer::Standard2D)
return false;
int part = -1;
GetDataNode()->GetIntProperty("current part", part, interactionEvent->GetSender());
if (part == -1)
{
return false;
}
if (std::strcmp(interactionEvent->GetNameOfClass(), "MousePressEvent") == 0) {
auto *mre = dynamic_cast<mitk::MousePressEvent *>(interactionEvent);
if (nullptr != mre) {
if (mitk::InteractionEvent::LeftMouseButton == mre->GetEventButton() ||
mitk::InteractionEvent::MiddleMouseButton == mre->GetEventButton()) {
mre->SetModifiers(mitk::InteractionEvent::NoKey);
}
}
}
if (std::strcmp(interactionEvent->GetNameOfClass(), "MouseMoveEvent") == 0) {
auto *mre = dynamic_cast<mitk::MouseMoveEvent *>(interactionEvent);
if (nullptr != mre) {
mre->SetModifiers(mitk::InteractionEvent::NoKey);
}
}
if (std::strcmp(interactionEvent->GetNameOfClass(), "MouseReleaseEvent") == 0) {
auto *mre = dynamic_cast<mitk::MouseReleaseEvent *>(interactionEvent);
if (nullptr != mre) {
if (mitk::InteractionEvent::LeftMouseButton == mre->GetEventButton() ||
mitk::InteractionEvent::MiddleMouseButton == mre->GetEventButton()) {
mre->SetButtonStates(mitk::InteractionEvent::NoButton);
mre->SetModifiers(mitk::InteractionEvent::NoKey);
}
}
}
return true;
}