Seite 1 von 1

Farbcode mit ConfigObj speichern und auslesen

Verfasst: Freitag 28. November 2008, 08:51
von Mawilo
Hallo,

ich möchte in einem Config-File mit ConfigObj Farbangaben (z.B. (255, 0, 0, 255))speichern und natürlich auch wieder auslesen. Leider wird der ausgelesene Wert nicht weiter beachtet. Beim Setzen der Farbe aus der cfg-Datei passiert nix.

Hier ein Beispiel:

Code: Alles auswählen

#!/usr/bin/env python
# -*- coding: iso-8859-15 -*-

import wx
import os.path
import sys
from configobj import ConfigObj

CFG = './test.cfg'

class MainWindow(wx.Frame):
    def __init__(self, parent):
        wx.Frame.__init__(self, parent, -1, title='Test ConfigObj')
        panel = wx.Panel(self)
        self.button = wx.Button(panel, -1, size=(100, 21))
        self.save = wx.Button(panel, -1, label='Speichern', size=(100, 21))
        
        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add(self.button)
        sizer.Add(self.save)
        panel.SetSizer(sizer)
        self.Bind(wx.EVT_BUTTON, self.changeColor, self.button)
        self.Bind(wx.EVT_BUTTON, self.writeConfig, self.save)
        self.readConfig()
        
    def changeColor(self, event=None):
        dialog = wx.ColourDialog(None)
        dialog.GetColourData().SetChooseFull(True)
        if dialog.ShowModal() == wx.ID_OK:
            data = dialog.GetColourData()
            color  = data.GetColour().Get()
            self.button.SetBackgroundColour(color)
        dialog.Destroy()
        
    def writeConfig(self, event=None):
        config = ConfigObj()
        config.filename = CFG
        config['Colour'] = {}
        config['Colour']['button'] = self.button.GetBackgroundColour()
        config.write()
        
    def readConfig(self):
        config = ConfigObj(CFG)
        print config['Colour']['button']
        self.button.SetBackgroundColour(config['Colour']['button'])
        
def main():
    app = wx.PySimpleApp()
    frame = MainWindow(None)
    frame.Center()
    frame.Show()
    app.MainLoop()

if __name__ == '__main__':
    main()
Anscheinend wird der Farbcode in einem anderen Format zurückgegeben. Wenn das Programm startet, wird die Farbe des ersten Button nicht gesetzt. Wie kann ich das ändern?

Grüße
Mawilo

Verfasst: Freitag 28. November 2008, 09:44
von jens
Wenn dir nicht wichtig ist, das man die Config Datei per hand editieren kann, dann würde ich zu pickle greifen. Damit kannst du fast alles speichern und wieder laden.

Hab mir mal sowas gebaut:

Code: Alles auswählen

class PickleConfig(dict):

    def __init__(self, filename, defaults={}):
        self.filename = filename
        
        self.update(defaults)
        
        if not os.path.isfile(self.filename):
            print "Info: Config file '%s' doesn't exist, yet." % self.filename
        else:
            print "Reading '%s'..." % self.filename
            try:
                f = file(filename, "r")
            except IOError, err:
                print "Error reading config:", err
            else:
                pickle_data = pickle.load(f)
                f.close()
                self.update(pickle_data)
        

    def save_config(self):
        print "Save '%s'..." % self.filename,
        f = file(self.filename, "w")
        pickle.dump(self, f)
        f.close()
        print "OK"

    def debug(self):
        print "PickleConfig debug:"
        pprint(self)
        print "-"*80

Re: Farbcode mit ConfigObj speichern und auslesen

Verfasst: Freitag 28. November 2008, 09:51
von gerold
Mawilo hat geschrieben:ich möchte in einem Config-File mit ConfigObj Farbangaben (z.B. (255, 0, 0, 255))speichern und natürlich auch wieder auslesen
Hallo Mawilo!

Von ConfigObj habe ich keine ahnung. Aber wenn du kein Tupel speichern oder auslesen kannst, dann kannst du es ja mal mit einem String versuchen. Damit kann wxPython auch umgehen:

Code: Alles auswählen

>>> import wx
>>> c = wx.Color()
>>> c.GetAsString()
u'black'
>>> c.GetAsString(flags = wx.C2S_HTML_SYNTAX)
u'#000000'
>>> wx.NamedColor("#000000")
wx.Colour(0, 0, 0, 255)
>>> wx.NamedColor("#666666")
wx.Colour(102, 102, 102, 255)
>>>
lg
Gerold
:-)

Verfasst: Freitag 28. November 2008, 10:32
von BlackJack
@Mawilo: Bei solchen Sachen zu Fehlersuche immer `repr()` zur Ausgabe verwenden, dann wäre Dir aufgefallen, dass Du beim Auslesen eine Zeichenkettendarstellung des Tupels bekommst und kein Tupel. Und diese Zeichenkette steht auch so in der *.cfg-Datei. Also ist der erste Schritt die Farbe beim Schreiben in eine Liste umzuwandeln.

Beim Einlesen bekommst Du dann eine Liste mit Zeichenketten zurück. In der *.cfg-Datei wird ja nirgends gespeichert dass das nur Zahlen sein können. Also beim Einlesen alle Elemente in Zahlen umwandeln und dass dann wieder in ein Tupel. Und schon funktionierts.

Mal abgesehen von dem Fall, wenn es keine *.cfg-Datei gibt, dann beendet sich das Programm beim Versuch die Farbe aus zu lesen einfach.

Verfasst: Freitag 28. November 2008, 20:38
von roschi
hallo!

@Mawilo:
vielleicht gefaellt dir das.

lg
roschi

Verfasst: Samstag 29. November 2008, 09:04
von Mawilo
Danke für die Hinweise. Ich habe mich letztendlich für die wx-Variante entschieden, da mein Programm eh mit einer wx-Oberfläche arbeitet. Ich speicher nun die Farben als String.

Code: Alles auswählen

#!/usr/bin/env python
# -*- coding: iso-8859-15 -*-

import wx
import os.path
import sys
from configobj import ConfigObj

CFG = './test.cfg'

class MainWindow(wx.Frame):
    def __init__(self, parent):
        wx.Frame.__init__(self, parent, -1, title='Test ConfigObj')
        panel = wx.Panel(self)
        self.button = wx.Button(panel, -1, size=(100, 21))
        self.save = wx.Button(panel, -1, label='Speichern', size=(100, 21))
        
        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add(self.button)
        sizer.Add(self.save)
        panel.SetSizer(sizer)
        self.Bind(wx.EVT_BUTTON, self.changeColor, self.button)
        self.Bind(wx.EVT_BUTTON, self.writeConfig, self.save)
        self.readConfig()
        
    def changeColor(self, event=None):
        dialog = wx.ColourDialog(None)
        dialog.GetColourData().SetChooseFull(True)
        if dialog.ShowModal() == wx.ID_OK:
            data = dialog.GetColourData()
            color  = data.GetColour().Get()
            self.button.SetBackgroundColour(color)
        dialog.Destroy()
        
    def writeConfig(self, event=None):
        config = ConfigObj()
        config.filename = CFG
        config['Colour'] = {}
        config['Colour']['button'] = self.button.GetBackgroundColour().GetAsString(flags = wx.C2S_HTML_SYNTAX) 
        config.write()
        
    def readConfig(self):
        try:
            config = ConfigObj(CFG)
            self.button.SetBackgroundColour(config['Colour']['button'])
        except KeyError:
            pass
    

        
def main():
    app = wx.PySimpleApp()
    frame = MainWindow(None)
    frame.Center()
    frame.Show()
    app.MainLoop()

if __name__ == '__main__':
    main()
Das Beispiel funktioniert bei mir unter Windows, jedoch nicht unter Linux. Das verstehe ich nicht so ganz. Da ich es aber nur unter Windows benötige, ist es mir nicht ganz so wichtig.

Danke und Grüße
Mawilo