Выставление дочерних свойств в родительском

Я хочу создать собственный виджет, который содержит QSpinBox. Я хочу, чтобы пользовательский виджет предоставлял некоторые свойства QSpinBox как свои собственные, чтобы он мог удобно работать в Designer.

Есть ли удобный способ сделать прокси свойств такого типа в Qt?

Я хочу повторить, что отношения между моим пользовательским виджетом и QSpinBox - это сдерживание, а не наследование. Я использую pyqt, но с радостью приму чистый ответ qt.

Чтобы уточнить, я хочу создать варианты стандартных виджетов, которые имеют некоторые дополнительные украшения. Например, я буду добавлять переключаемый значок рядом с моим QSpinBox. Однако я все еще хочу иметь возможность настроить QSpinBox в конструкторе (то есть установить суффикс, верхний и нижний пределы, приращение и т. Д.).

3 ответа

Решение

Alrite, так вот способ сделать это.

Это лучше, чем писать функцию вручную для каждого свойства. По сути, вы пишете макрос, который расширяет код для вас. У меня есть виджет doubleSpinBox в моем виджете, и его значение изменяется всякий раз, когда я меняю свойство. И вы посылаете сигнал всякий раз, когда свойство изменяется, что связано с doubleSpinBox->setValue(). Проверено и работает отлично. Полный код по этой ссылке.

#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_

Вот версия PyQt, вдохновленная blueskin. Основное оперативное отличие заключается в том, что пользовательский класс виджета создается во время выполнения, а не во время компиляции. Преимущество этого состоит в том, что мы можем программно проверять целевой метаобъект и использовать его для создания свойств прокси.

Теперь PyQt скомпилирован из C++, поэтому я должен верить, что также возможно генерировать типы qt во время выполнения в C++. Я держу пари, что это было бы адски, однако.

из PyQt4 импорт QtGui, QtCore

def makeProxyProperty (childname, childtype, childpropname):

    metaobject = childtype.staticMetaObject
    metaproperty = metaobject.property (metaobject.indexOfProperty (childpropname))

    def getter (self):
        вернуть metaproperty.read (getattr (self, childname))

    def setter (self, val):
        вернуть metaproperty.write (getattr (self, childname), val)

    return QtCore.pyqtProperty (metaproperty.typeName (), fget = getter, fset = setter)


Класс Widget1(QtGui.QWidget):
    def __init__(self, parent=None):
        супер ().__ INIT __ (родитель)
        self.spinbox = QtGui.QSpinBox()
        self.checkbox = QtGui.QCheckBox()
        layout = QtGui.QHBoxLayout()
        layout.addWidget(self.checkbox)
        layout.addWidget(self.spinbox)
        self.setLayout(макет)

    spinbox_suffix = makeProxyProperty ("spinbox", QtGui.QSpinBox, "суффикс")
    spinbox_prefix  = makeProxyProperty("spinbox", QtGui.QSpinBox, "prefix")
    spinbox_minimum = makeProxyProperty("spinbox", QtGui.QSpinBox, "минимум")
    spinbox_maximum = makeProxyProperty("spinbox", QtGui.QSpinBox, "максимум")

Widget1 в дизайнере

Чтобы прояснить ситуацию,

  1. Вы будете использовать этот пользовательский виджет в дизайнере.
  2. Вам нужен пользовательский виджет, чтобы иметь свойства, которые отображают свойства QSpinBox в качестве свойств виджета

Так,

в основном вы захотите создать свойство в своем пользовательском виджете, используя 'Q_PROPERTY' и использовать методы setter и getter для изменения свойств QSpinBox. Надеюсь, этот пример поможет http://doc.qt.nokia.com/latest/properties.html

Другие вопросы по тегам