Properties in Qt and Symbian

From Qt Wiki
Jump to navigation Jump to search

Template:ArticleNeedsUpdate Template:ArticleMetaData


Overview[edit | edit source]

Template:Abstract

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 );
}

Sample application[edit | edit source]

File:Property S60 Qt.zip