Settings in Qt 3.0

Qt 3.0 will have built-in cross-platform solutions for the management of configuration settings. Note that what I discuss here is based on the beta release of Qt 3.0, and thus is subject to change. It is also not a completely satisfactory solution, since you still need to be aware of the type of platform you're running on, whether Windows (all 32 bits flavors), Apple's OS X or any Unix with X11.

The Qt 3.0 system is built around the QSettings class. On Windows systems, all settings are saved in the registry; on Linux or other Unices settings are saved in a file. The exact location of the file is determined by a "search path". This is a list of directories, similar to the $PATH environment variable, that lists all places Qt will look for a configuration file.

QSettings saves all settings in a hierarchical tree format, conforming to the layout of the Windows registry. You cannot use keys longer than 255 Unicode characters or values longer than 16.300 characters (silly limitation, but there you are). The complete path—i.e., all keys plus the value—must fit into the memory of a Commodore 64 (that is, 64 kb). You can exceed these limits if you are targeting only Unix. It remains to be seen what the limitations will be on OS X, but since OS X is Unix based, you can assume it will follow the general Unix scheme of configuration files.

Let's translate the Kalam example above to QSettings. Note that this is untested code: I've merely extrapolated from the known C++ interface to what I assume will become the PyQt interface. (QSetting wasn't in the subset of Qt 3 classes that were implemented when I finished this text). Note also that there are two ways of using QSettings. You can either read all settings from the registry or configuration file and assign them as attributes to the Config object, or you can open a QSettings object and add that to Config; then you can query the settings object directly every time you need a value.

The first approach has a few advantages: it is compatible with current code, you can approach settings with a simple Config.geometry.app_x variable, and if the user removes the configuration file, your app can merrily continue.

The second approach, which is advised by Trolltech, also has advantages. It is simpler to write, does not demand much startup time, and does not fill the memory with data that is not (yet) needed. Furthermore, the app can dynamically react to changes in the configuration file.

I chose the first approach, as it fits better with Kalam. Besides, it gives me the chance to show the interesting bits and bobs of QSettings without touring Kalam again.

"""
kalamconfig.py - Configuration class for the Kalam Unicode Editor

copyright: (C) 2001, Boudewijn Rempt
email:     boud@rempt.xs4all.nl
"""

import sys, os, types
from qt import *


class Config:
    defaults = {
        "APPNAME" : "kalam",
        "APPVERSION" : "ch13",
        "viewmanager" : "tabmanager",
        "app_x" : 0,
        "app_y" : 0,
        "app_w" : 640,
        "app_h" : 420},
        "fontfamily" : "courier",
        "pointsize" : 12,
        "weight" : 50,
        "italic" : 0,
        "encoding" : 22
        }

def init(self):
    Config.settings = QSettings()
    Config.settings(QSettings.Windows,
                    "/kalam")
    Config.settings(QSettings.Unix,
                    "/usr/local/share/kalam")

def readConfig(configClass = Config):
    for key in configClass.defaults.keys():
        v = configClass.settings.readEntry("/kalam/" + key)
        configClass.key = v


def writeConfig(configClass = Config):
    sys.stderr.write( "Saving configuration\n")
    for key in dir(Config):
        if key[:2]!='__':
            val=getattr(Config, key)
            configClass.settings.writeEntry("/kalam/" + key, val)

...
    

As you can see, there is an initialization phase (init()), that creates a settings objects. This is the one place where QSettings is not platform independent, and you have to add a search path.

Windows and Unix use different search paths. The Windows search path refers to the registry key under "/Software", and Qt looks through the main branches in the following order — and whenever it encounters a duplicate setting, it takes the last one read.: HKEY_CURRENT_USER, HKEY_CURRENT_USER, HKEY_LOCAL_MACHINE, HKEY_LOCAL_MACHINE.

On Unix, the sequence is comprised of the path you added yourself, then $QTDIR/etc, and then $HOME/.qt. That's also the directory where all Qt applications will save their configuration files. Your application settings are thus saved in a file that is named from the combination of the first key you save under ("kalam" in this case), and the suffix rc. And that file is places in the .qt directory in the user's home directory.

The class QSettings also offers functions to retrieve strings, lists, doubles, integers and boolean values from the configuration database, as well as functions to add, remove and list keys and subkeys.