How to update kdelibs variables globally

David Faure faure at kde.org
Sat Apr 28 18:44:08 BST 2007


On Saturday 28 April 2007, David Jarvie wrote:
> I'm implementing the time zones KDEDModule, and it needs to update a couple of 
> variables in KSystemTimeZones at initialisation and whenever it detects a 
> change. This update needs to be available to all applications which are using 
> KSystemTimeZones. What is the best way of doing this? I'm not familiar enough 
> with how shared libraries work - is it possible to share a variable between 
> applications, or is there always a separate copy of each static variable 
> (class static or global static) for each individual application?

You want inter-process communication here, so you need DBUS.
(real shared memory is very complex to setup and not so portable, and overkill
for one variable).

It's quite standard to synchronize all instances of a given class among all processes
using DBUS, a number of konqueror and kdepim classes do it.
For instance, from kdepim/libkpimidentity/identitymanager.cpp :

IdentityManager::IdentityManager([...]) : [...]
{
  new IdentityManagerAdaptor( this );
  QDBusConnection dbus = QDBusConnection::sessionBus();
  const QString dbusPath = newDBusObjectName(); // because there can be more than one instance per process. Otherwise just hardcode a name here.
  const QString dbusInterface = "org.kde.pim.IdentityManager";
  dbus.registerObject( dbusPath, this );
  dbus.connect( QString(), dbusPath, dbusInterface, "identitiesChanged", this, SLOT(slotIdentitiesChanged(QString)) );
  [...]
}

void IdentityManager::someSlot()
{
  // save new config to file
  // (but you could just emit the variable value in the signal, too)

  // DBus signal for other IdentityManager instances
  emit identitiesChanged( QDBusConnection::sessionBus().baseService() );
}

void KPIM::IdentityManager::slotIdentitiesChanged( const QString &id )
{
  kDebug()<<" KPIM::IdentityManager::slotIdentitiesChanged :"<<id<<endl;
  if ( id != QDBusConnection::sessionBus().baseService() ) {
    mConfig->reparseConfiguration();
    readConfig( mConfig );
    // or just setting a variable instead
    [...]
  }
}

Hmm in your case it's even simpler, the emitter (the kded module) isn't the receiver (the kdelibs class)
so there's no need to ship the baseService at all; just let the kded module emit a dbus signal and let
the kdelibs class connect to it.

-- 
David Faure, faure at kde.org, sponsored by Trolltech to work on KDE,
Konqueror (http://www.konqueror.org), and KOffice (http://www.koffice.org).




More information about the kde-core-devel mailing list