如何正确处理鼠标事件处理程序中的不同情况?

时间:2009-11-12 15:59:11

标签: c++ qt event-handling

在用于鼠标按键事件的事件处理程序的Qt应用程序中,我有如此难看的代码

void Render::Viewer::mousePressEvent(QMouseEvent* e)
{
  switch (e->button())
  {
  case Qt::LeftButton:
    switch (mode_)
    {
    case Render::Viewer::ModeView:
      switch (e->modifiers())
      {
      case Qt::NoModifier:
        ...
        break;
      ...
      default:
        break;
      }
      break;
    case Render::Viewer::ModeEdit:
      ...
      break;
    }
    break;
  case Qt::RightButton:
    ...
    break;
  }
}

即使没有打开mode_变量,代码看起来也很糟糕。 =(两个多自由度:按钮类型,修饰符,......绝对不可读。

有没有办法克服这种“开关堆”?

4 个答案:

答案 0 :(得分:4)

另一种方法是使用Qt的新State Machine Framework。我自己没有使用它,但是从我读过的内容来看,它旨在用一个更简单,更正式的窗口小部件行为表示来替换你的状态变量和切换语句。

答案 1 :(得分:4)

观察嵌套开关可以反转:内部开关可以提升到外部,反之亦然。这样,您就可以将mode_上的开关提升到外层。

然后可能的解决方案是创建一个接口,比如说Mode,处理特定模式的事件:

class Mode {
  public:
    virtual void mousePressEvent(QMouseEvent *e) = 0;
    // ... and so on for other events
};

然后,ModeViewModeEdit等具体实现可以处理事件。如果您不想在所有情况下处理所有事件,请将此接口设置为空实现而不是纯虚函数。如果特定模式之间存在共享功能,您甚至可以创建这些模式类继承的中间类。

_mode成为指向当前模式的Mode的指针,然后您的“主”处理程序变为:

void Render::Viewer::mousePressEvent(QMouseEvent* e) {
  _mode->mousePressEvent(e);
}

答案 2 :(得分:2)

如果将任务分解为自己的功能,那么阅读和维护会更容易:

void Render::Viewer::mousePressEvent(QMouseEvent* e) 
{ 
  switch (e->button()) 
  { 
  case Qt::LeftButton: 
    handleLeftButton(e);
    break;
  case Qt::RightButton: 
    handleRightButton(e);
    break; 
  } 
}

void Render::Viewer::handleLeftButton(QMouseEvent* e)
{
    switch (mode_) 
    { 
    case Render::Viewer::ModeView: 
      switch (e->modifiers()) 
      { 
      case Qt::NoModifier: 
        ... 
        break; 
      ... 
      default: 
        break; 
      } 
      break; 
    case Render::Viewer::ModeEdit: 
      ... 
      break; 
    } 
}

void Render::Viewer::handleRightButton(QMouseEvent* e)
{
  ...
}

将其分解为您需要的许多功能,以使其可读。

答案 3 :(得分:1)

您可以将一些switch语句移动到函数