Properties in Qt and Symbian
Template:ArticleNeedsUpdate Template:ArticleMetaData
Overview[edit | edit source]
Description[edit | edit source]
Both Qt and S60 have a property system for easy storage and retrieval of data using standard APIs. S60 offers setting/retrieval of properties through the IPC mechanism, which is currently not available in Qt. In Qt, properties are intended to be class-specific variables which can be shared across classes by using the standard setter/getter functions without knowing class-specific functions to achieve the same.
Operation | Symbian/S60 | Qt |
Property management system | RProperty class | Q_PROPERTY |
Nature of properties | Global variables which can be set and retrieved. | Class-level variables that can be set and retrieved. |
Change notifications | Publish & Subscribe IPC mechanism enables interested threads/processes to know when a key changes. | No publish/subscribe IPC in Qt. Within the same process, observer pattern or signal/slot mechanism can be used to get notifications (using QEvent). |
Security | It is possible restrict which applications can set/get the properties. | No security restrictions possible. |
Required class hierarchy | None. | Class in which properties are defined has to be a class derived from QObject. |
Persistency | The user-defined properties persist in the kernel until the OS reboots or the properties are deleted. | Properties are member variables and values are lost when the object is destroyed. |
Defining a property | RProperty::Define() | Q_PROPERTY(type name READ getFunction [WRITE setFunction] [RESET resetFunction] [DESIGNABLE bool] [SCRIRTABLE bool] [STORED bool]) |
Setting a property | RProperty::Set() | QObject::setProperty() |
Getting a property | RProperty::Get() | QObject::property() |
Deleting a property | RProperty::Delete() (Property can be deleted only by the owning thread). | None. |
Subscribing to a property | RProperty::Attach() and then RProperty::Subscribe(). The subscriber is an Active Object whose RunL() will be invoked when change notifications are received. | QEvent::event of QObject (from which the class is derived) is called whenever a property changes. Then, a signal can be emitted by the class which owns the property. Interested parties can catch the signal and do the necessary operation (no IPC available). Alternatively, the interested applications can register as observers and get notified whenever the properties change. |
Solution[edit | edit source]
This solution describes how to create a property, get values, set values and usage of signal/slot mechanism used to inform other classes of any change in the property.
This example has 2 classes, 76ytuiytuityutyutututyutyutyu (which needs to be compiled first) and 76ytuiytuityutyutututyutyutyu which is an application dependent on 76ytuiytuityutyutututyutyutyu. 76ytuiytuityutyutututyutyutyu class has 2 buttons: Hello and Exit. When the Hello button is pressed, it increments and sets the property value in 76ytuiytuityutyutututyutyutyu. A notification is received in 76ytuiytuityutyutututyutyutyu through signal slot mechanism when the property value changes and the new value is displayed in the text box.
Method I
class MyProperty : public QObject
{
Q_OBJECT
// Defining a property
Q_PROPERTY( Priority priority READ priority WRITE setPriority )
Q_ENUMS( Priority )
public:
enum Priority { High = 1, Low, VeryHigh, VeryLow };
// Property can be set either through this function
// or base class function setProperty()
void setPriority( Priority value ) { priority = value; }
// Property can be retrieved either through this function
// or base class function property()
Priority priority() const { return priority; }
// Any change in property value is notified through this function
// This function is overridden function of QEvent::event()
bool MyProperty::event( QEvent* e );
signals:
// emitted when property changes
void propertyChanged(QByteArray name, int value);
public slots:
// Sets the property
void settingProperty();
private:
// Property that needs to be set
Priority priority;
int val;
};
void MyProperty::settingProperty()
{
if(val > VeryLow) {
val = High;
}
// Using setProperty from QObject
setProperty("Priority", val);
val++;
}
// Event handler for property change event.
// Will be called whenever the value of a property is changed
bool MyProperty::event( QEvent* e )
{
// Check if event is for property change
if( e->type() == QEvent::DynamicPropertyChange ) {
// Check if the event is for property of our interest
QDynamicPropertyChangeEvent event( "Priority" );
if( event.propertyName() == "Priority" ) {
// Gets the property value and emits a signal
// with the name and value of property
emit propertyChanged( event.propertyName(),
property( "Priority" ).toInt() );
return true;
}
}
return false;
}
// Class that gets notified when a property is changed
// through signal/slot mechanism
class MyPropertyChanger : public QWidget
{
Q_OBJECT
public:
MyPropertyChanger( QWidget *parent = 0 );
~MyPropertyChanger();
public slots:
// Function to show the property value
void ShowHelloText( QByteArray name, int changedValue );
private:
Ui::MyPropertyChangerClass ui;
MyProperty* prop;
};
MyPropertyChanger::MyPropertyChanger( QWidget *parent )
:QWidget( parent )
{
ui.setupUi( this );
// Property object creation
prop = new MyProperty();
// When a button is clicked call a function to set the property
QObject::connect(ui.hello, SIGNAL(clicked()), prop, SLOT(SettingProperty()));
// When property changed signal is emitted handle it
QObject::connect( prop, SIGNAL( propertyChanged( QByteArray, int ) ),
this, SLOT( ShowHelloText( QByteArray, int ) ) );
}
MyPropertyChanger::~MyPropertyChanger()
{
delete prop;
}
void MyPropertyChanger::ShowHelloText( QByteArray name, int changedValue )
{
QString s = QString::number( changedValue, 10 );
ui.label->setText( s );
}