Выставление дочерних свойств в родительском
Я хочу создать собственный виджет, который содержит 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, "максимум")
Чтобы прояснить ситуацию,
- Вы будете использовать этот пользовательский виджет в дизайнере.
- Вам нужен пользовательский виджет, чтобы иметь свойства, которые отображают свойства QSpinBox в качестве свойств виджета
Так,
в основном вы захотите создать свойство в своем пользовательском виджете, используя 'Q_PROPERTY' и использовать методы setter и getter для изменения свойств QSpinBox. Надеюсь, этот пример поможет http://doc.qt.nokia.com/latest/properties.html