根据组合框中选择的项目选择算法

时间:2014-11-25 19:36:52

标签: c++ qt geocoding geo

美好的一天,

我正在编写一个程序' geocalculator'作为我们大学的任务。我遇到了设计问题。接口包含两个组:A和B.每个组由两个组合框和一个表组成。第一个组合框允许用户在几个参考系统(WGS-84,SK-42,SK-95等)之间进行选择。第二个 - 在大地坐标系,空间坐标系和坐标系之间。该表用于输入一堆点(标签,X(或B),Y(或L),Z(或H))。转换函数涉及许多常量和大量公式。

我的问题是:组织代码,连接组合框和函数以调用适当的转换函数的最佳方法是什么?

让我们来点。我将一个抽象模型(PointsModel)子类化,其中存储了我的所有点。它不知道组合框和算法。组合框在MainWindow类中声明。我的模型有自定义委托:它用于将输入坐标的表示从十六进制(度,分和秒)转换为十进制(十进制度)。我有两个按钮(toolBar上的动作):将点从A转换为B,反之亦然。我想象下一步的过程:

  1. 用户按下'转换'按钮和相应的功能被调用。
  2. 一般转换功能读取组合框的值并选择所需的转换功能。 ...
  3. 我不想通过" if else"陈述!因为会有大量的条件陈述(如果一个组合框是WGS-84而另一个是SK-42那么这样做,如果一个组合框是SK-42而另一个是WGS- 84然后执行此操作,依此类推,以获得一系列参考系统。)

    我对声明函数和相应的仿函数有一些想法。我想以某种方式将这些仿函数附加到组合框中,然后时间来调用一般方法,它会自动将调用重定向到所需的函数。

2 个答案:

答案 0 :(得分:0)

您可以通过多种方式处理此问题,但我认为最好的方法是在QComboBox的每个元素上设置一个仿函数。

执行(QComboBox::addData)[http://qt-project.org/doc/qt-5/qcombobox.html#addItem]时,您会注意到默认的userData参数。你可以在这里指定一个仿函数。

当您准备好使用它时,只需致电(QBomboBox::currentData)[http://qt-project.org/doc/qt-5/qcombobox.html#currentData-prop]即可将其恢复使用。

至于在QVariant中存储您的仿函数,您可以将仿函数存储在您自己的数组中,只需将索引存储到QVariant中的该数组中即可直接将仿函数存储为使用QVariant(int typeId, const void * copy)的空白*。

修改

从你的评论中听起来像这样的事情可能是有序的:

将您的函数存储在std::map<std::string, std::map<std::string, std::function<X>>>中,外部地图的键是from-type,而内部地图的键是to-type。

然后将密钥存储在QComboBox的{​​{1}}。

答案 1 :(得分:0)

我将描述两个流行的选择:查找表和事件处理程序(按下按钮)。算法的选择取决于您的计算器实现。

查找表

这里的基本原理是你想要一个函数与一个符号相关联。例如,您的解析器想要评估&#39; +&#39;对于堆栈上的表达式。您可以查找与&#39; +&#39;相关联的功能,而不是使用switchif-elseif阶梯。并使用两个表达式执行该函数。

// Synonym for a pointer that accepts two parameters,
// performs an operation, and returns the result as a string.
typedef std::string (*Function_Pointer(const std::string& param1, const std::string& param2))

struct Table_Entry
{
  const char * operator_text;
  Function_Pointer p_operaton_function;
};

const Table_Entry Operation_Table[] =
{
  {"+", Perform_Addition},
  {"-", Perform_Subtraction},
  {"*", Perform_Multiplication},
};

// Or
typedef std::map<std::string, Function_Pointer> Operation_Container;
//...
Operation_Container operations_map;
operations_map["+"] = Perform_Addition;
operations_map["-"] = Perform_Subtraction;

事件处理程序

另一个想法是将计算放在按钮的处理程序中。

void On_Button_Dash(Event& e)
{
  result = operand_1 - operand2;
}

编辑1:OOP

另一种方法是为操作创建基类。基类将具有评估或执行操作的抽象方法。为每个操作定义子类。在lexing阶段创建操作类,并存储在指向基类的指针向量中。

你的主循环可能是:

std::vector<Base_Operation *> operations;
for (unsigned int i = 0; i < operations.size(); ++i)
{
  operations[i].Evaluate(parameter_1, parameter_2);
}