在 Qt/C++ 应用程序中管理测量单位转换的最佳实践
Posted
技术标签:
【中文标题】在 Qt/C++ 应用程序中管理测量单位转换的最佳实践【英文标题】:Best practice to manage units of measurement conversion in a Qt/C ++ application 【发布时间】:2022-01-10 05:14:57 【问题描述】:在使用 Qt/QML 和 C++ 编写的应用程序中增加用户选择首选度量单位的可能性的最佳实践是什么?
我的案例是一个前端应用程序,它显示来自 PLC 的数据,还可以编辑其中的一些数据。 PLC 数据以毫米、克、摄氏度和米/分钟为单位,需要保持这些单位。
我想在前端应用程序中添加选择是否要以毫米或英尺、摄氏度或华氏度等显示数据的可能性...
我在考虑一个单例 QObject 派生类,它以 Q_PROPERTY 的形式返回测量单位(“mm”、“oz”等),但我不确定开发一些转换值的槽,因为当用户切换测量单位时,我无法动态更新界面。
附:我想避免使用 boost 库
【问题讨论】:
【参考方案1】:我不知道这是否是最佳实践,但我处理它的方式是将其视为在 PLC 的本机数据格式和等效的用户可读 QString 之间转换的问题,然后返回。
鉴于此,我可能会为知道如何执行此操作的类创建一个抽象接口,如下所示:
class IUnitsPresentationLayer
public:
virtual QString lengthToString(long lengthInMillimeters) const = 0;
virtual long stringToLength(const QString & lengthStr) const = 0;
virtual QString temperatureToString(float temperatureCelsius) const = 0;
virtual float stringToTemperature(const QString & tempStr) const = 0;
[... and so on...]
;
然后,您的 GUI 代码的其余部分可以传递一个 const IUnitsPresentationLayer *
指针,以便在需要显示 PLC 数据值(或将用户输入的 QString 解析回 PLC 数据值)时使用。实际实现可以在一个.cpp
文件中保持私有,它可以是一个单例,或者如果需要,您可以为不同的行为创建不同的IUnitsPresentationLayer
-子类,并可能通过QPointer
或std::shared_ptr
传递它们有必要的。由于这些对象完全是 const/不可变的,因此许多 GUI 小部件都可以同时共享对它们的只读访问权限。
【讨论】:
【参考方案2】:我有一个 QML Qt C++ UI。它与后端应用程序交互。 UI 支持英制和公制模式。用户可以在运行时从 UI 中进行此选择。 用户可以通过 UI 查看和编辑数据值。 后端应用程序仅在英制模式下工作。
C++ 实用程序对象作为上下文属性公开给 QML。此实用程序对象具有以下方法:
设置和获取测量系统。 将单位字符串从英制转换为公制。示例:°F 到 °C。 将数据值从英制转换为公制,将公制转换为英制。示例:华氏到摄氏 -> 50 到 10,摄氏度到华氏 -> 0 到 32。C++ 数据对象有这两个属性:
Q_PROPERTY(QVariant value READ value WRITE setValue NOTIFY valueChanged)
Q_PROPERTY(QString unitString READ unitString NOTIFY unitStringChanged)
// value - In Imperial mode, you get Imperial value. In Metric mode, you get Metric value.
// unitString - In Imperial mode, you get Imperial units. In Metric mode, you get Metric units.
QVariant data::value()
// fetch Imperial data value from back-end application
// get current System of measurement
// if current System of measurement is Metric, convert data value from Imperial to Metric
// return data value
QString data::unitString()
// fetch Imperial unit from back-end application
// get current System of measurement
// if current System of measurement is Metric, convert unit from Imperial to Metric
// return unit
void data::setValue(QVariant value)
// get current System of measurement
// if current System of measurement is Metric, convert value from Metric to Imperial
// write value to back-end Controller application
【讨论】:
以上是关于在 Qt/C++ 应用程序中管理测量单位转换的最佳实践的主要内容,如果未能解决你的问题,请参考以下文章