在用于鼠标按键事件的事件处理程序的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_变量,代码看起来也很糟糕。 =(两个多自由度:按钮类型,修饰符,......绝对不可读。
有没有办法克服这种“开关堆”?
答案 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
};
然后,ModeView
和ModeEdit
等具体实现可以处理事件。如果您不想在所有情况下处理所有事件,请将此接口设置为空实现而不是纯虚函数。如果特定模式之间存在共享功能,您甚至可以创建这些模式类继承的中间类。
让_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语句移动到函数