【问题标题】:Exposing child's properties in the parent在父级中暴露子级的属性
【发布时间】:2011-11-06 04:41:33
【问题描述】:

我想创建一个包含 QSpinBox 的自定义小部件。我希望自定义小部件将 QSpinBox 的一些属性公开为自己的,以便它可以在 Designer 中方便地工作。

有没有一种方便的方法可以在 Qt 中进行这种属性代理?

我想重申,我的自定义小部件和 QSpinBox 之间的关系是包含,而不是继承。我正在使用 pyqt,但很乐意接受纯 qt 答案。

为了澄清,我想创建具有一些额外装饰的标准小部件的变体。例如,我将添加一个可切换图标放在我的 QSpinBox 旁边。但是我仍然希望能够在设计器中配置 QSpinBox(即设置后缀、上下限、增量等)。

【问题讨论】:

    标签: qt properties pyqt designer


    【解决方案1】:

    Alrite,所以这是一种方法。

    这比为每个属性手动编写函数要好。基本上,您编写一个为您扩展代码的宏。 我的小部件中有一个 doubleSpinBox,每当我更改属性时,它的值都会更改。每当属性更改时,您都会发出一个信号,该信号连接到 doubleSpinBox->setValue()。测试并完美运行。 完整代码在link。

    #ifndef MYWIDGET_H_
    #define MYWIDGET_H_
    
    #include <QtGui/QWidget>
    #include <QtGui/QLabel>
    #include "ui_mywidgetform.h"
    
    #define MYPROPERTY_SET_FUNC(_PROPCLASS_, _PROP_PARAM_NAME_, _PROP_SET_FUNC_NAME_, _PROP_NOTIFY_) \
      void _PROP_SET_FUNC_NAME_(_PROPCLASS_ _PROP_PARAM_NAME_) \
      { \
        emit _PROP_NOTIFY_(_PROP_PARAM_NAME_); \
      }
    
    #define MYPROPERTY_GET_FUNC(_PROPCLASS_, _PROP_READ_FUNC_NAME_, _PROP_VARIABLE_)\
      _PROPCLASS_ _PROP_READ_FUNC_NAME_() const  \
      { return _PROP_VARIABLE_; }
    
    class MyWidget : public QWidget
    {
      Q_OBJECT
    
    public:
      MyWidget(QWidget *parent = 0);
      ~MyWidget();
      enum Accuracy {Good, Bad};
    
    signals:
      void doubleSpinBoxValueChanged(double);
      void accuracyChanged(Accuracy);
    
    private:
        Q_PROPERTY(Accuracy accuracy READ accuracy WRITE setAccuracy NOTIFY accuracyChanged)
        Q_PROPERTY(double doubleSpinBoxValue READ doubleSpinBoxValue WRITE setDoubleSpinBoxValue)
    
    private:
      Accuracy m_accuracy;  //custom class property
      Ui::Form m_ui;
    
    public:
      //Getter functions
      MYPROPERTY_GET_FUNC (double, doubleSpinBoxValue, m_ui.doubleSpinBox->value())
      MYPROPERTY_GET_FUNC (Accuracy, accuracy, m_accuracy)
      //Setter functions
      MYPROPERTY_SET_FUNC(Accuracy, accuracy, setAccuracy, accuracyChanged)
      MYPROPERTY_SET_FUNC(double, doubleSpinBoxValue, setDoubleSpinBoxValue, doubleSpinBoxValueChanged)
    
    };
    
    #endif // MYWIDGET_H_
    

    【讨论】:

      【解决方案2】:

      这是一个受 blueskin 启发的 PyQt 版本。这里的主要操作区别是自定义小部件类是在运行时而不是编译时组成的。这样做的好处是我们可以以编程方式检查目标元对象并使用它来生成代理属性。

      现在PyQt是从c++编译而来的,所以我不得不相信在c++中运行时也可以生成qt类型。然而,我敢打赌那将是地狱般的。

      从 PyQt4 导入 QtGui,QtCore def makeProxyProperty(childname, childtype, childpropname): 元对象 = childtype.staticMetaObject metaproperty = metaobject.property(metaobject.indexOfProperty(childpropname)) def getter(自我): 返回 metaproperty.read(getattr(self, childname)) def setter(self, val): 返回 metaproperty.write(getattr(self, childname), val) 返回 QtCore.pyqtProperty(metaproperty.typeName(), fget=getter, fset=setter) 类 Widget1(QtGui.QWidget): def __init__(self, parent=None): super().__init__(父) self.spinbox = QtGui.QSpinBox() self.checkbox = QtGui.QCheckBox() 布局 = QtGui.QHBoxLayout() layout.addWidget(self.checkbox) layout.addWidget(self.spinbox) self.setLayout(布局) spinbox_suffix = makeProxyProperty("spinbox", QtGui.QSpinBox, "suffix") spinbox_prefix = makeProxyProperty("spinbox", QtGui.QSpinBox, "prefix") spinbox_minimum = makeProxyProperty("spinbox", QtGui.QSpinBox, "minimum") spinbox_maximum = makeProxyProperty("spinbox", QtGui.QSpinBox, "maximum")

      【讨论】:

      • 很好,我猜 PyQt 会在运行时提供更大的灵活性。我几乎没用过。
      【解决方案3】:

      所以说清楚一点,

      1. 您将在设计器中使用此自定义小部件。
      2. 您需要自定义小部件具有将 QSpinBox 属性公开为小部件属性的属性

      所以,

      基本上你会想在你的自定义小部件中创建一个属性 使用 'Q_PROPERTY' 并使用 setter 和 getter 方法来更改 QSpinBox 的属性 我希望这个例子对你有帮助 http://doc.qt.nokia.com/latest/properties.html#a-simple-example

      【讨论】:

      • 我正在寻找更自动化的东西。我将制作包含许多基本小部件类型的自定义小部件,并且每个小部件都有许多要代理的属性。手动代理每个属性容易出错且费力。
      • ok.. 明白了,为什么要将子小部件的属性作为主小部件的属性?如果您已经将自定义小部件作为 Qt-Designer 插件,那么您应该能够设置/获取所有子小部件的属性
      • 我正在运行一个自定义小部件(源自 QWidget),其中包含一个 QCheckBox 和一个 QSpinBox。在 Designer 中,我看不到编辑子小部件属性的方法。
      • @goertzenator:: 我的错。我以为我们可以做到这一点。好吧,那我不知道还有什么办法。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-03-29
      • 1970-01-01
      • 1970-01-01
      • 2021-11-05
      • 1970-01-01
      • 2013-07-28
      相关资源
      最近更新 更多