【问题标题】:Collecting values from form's widgets从表单的小部件中收集值
【发布时间】:2015-12-17 14:25:38
【问题描述】:

鉴于以下情况:

struct Property {
  QWidget *label;
  QWidget *field;
};
QList<Property*> properties;

其中大部分fields 是QLineEdits,但有些是QTimeEdits 并且可能是其他类型,例如QDateEdit

这用于(方便地)以这种方式制作表单:

for(int i = 0; i != properties.size(); i++)
    formLayout->addRow( properties.at(i)->label,properties.at(i)->field );

我正在考虑以同样的方式从表单的fields 中收集值:

foreach (const Property *p, properties) 
    p->field->value()

问题是没有value()这个函数。

这个设计好吗?为了实现value(),应该采用哪种方法?

【问题讨论】:

    标签: c++ qt data-structures qt4 qt5


    【解决方案1】:

    有多种方法可以做到这一点。

    1. 一种丑陋的方法是使用p-&gt;metaObject()-&gt;className() 方法。
    2. 更好的方法是将qobject_cast&lt;Class*&gt;(p) 用于所有可能的类型。不为 NULL 的那个是正确的类型。
    3. 您可以使用p-&gt;inherits("CLASS") 请求继承。

    【讨论】:

      【解决方案2】:

      天真的方法是预先对所有可能性进行硬编码,方法是:

      if (QLineEdit *le = qobject_cast<QLineEdit *>(obj)) {
          le->text(); 
      } else if (QDateTimeEdit *dte = qobject_cast<QDateTimeEdit *>(obj)) {
          dte->dateTime();
      } else if (...) { // repeat for all the cases
      
      }
      

      适当的稳健的方法是利用 Qt 的元对象功能。特别是a class can mark one of its properties to be the USER property,即用户与之交互的属性。这是为 Qt 自己的编辑小部件完成的。

      所以好的和通用的方法是:

      QVariant result;
      QMetaObject *mo = obj->metaObject();
      const int propertyCount = mo->propertyCount();
      for (int i = 0; i < propertyCount; ++i) {
          QMetaProperty mp = mo->property(i);
          if (mp.isUser(obj)) { 
              result = mp.read(obj);
              break;
          }
      }
      // use result
      

      【讨论】:

        猜你喜欢
        • 2018-09-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-05-30
        • 2011-09-22
        • 2013-04-03
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多