Unicode Error bei wx.StaticText

Plattformunabhängige GUIs mit wxWidgets.
snakeseven
User
Beiträge: 405
Registriert: Freitag 7. Oktober 2005, 14:37
Wohnort: Berlin
Kontaktdaten:

Dienstag 5. Februar 2008, 13:29

Hi Black Jack,

es gab ein großes Durcheinander, weil Teile der Daten aus Internetseiten stammt und andere Teile aus Dateien, welche in der PC (typischen?) cp1252 Codierung abgespeichert sind.

Jetzt bin ich der Empfehlung hier im Forum (u.a. Gerold) gefolgt und habe Ordnung geschaffen.
Alles was reinkommt wird in Unicode gewandelt und alles was raus auf die Disc geht, im systemeigenen Format gespeichert. Mein Rechner ist auf cp1252 eingestellt. Über locale() stellt sich das Programm das aber selber ein.

Jetzt werden die Sonderzeichen jedenfalls in den Widgets korrekt angezeigt und in den Textfiles korrekt gespeichert.

Danke für eure ausführliche Hilfe! Ich hoffe, auch anderen konnte damit geholfen werden.

Grüße, Seven
BlackJack

Dienstag 5. Februar 2008, 14:11

Wobei ich empfehlen würde möglichst auf eine Kodierung zu setzen, die auch alle Unicode-Zeichen kennt, also UTF-8 oder UTF-16. Sonst kann man Probleme bekommen wenn auf den Webseiten etwas ist, dass sich nicht in cp1252 kodieren lässt, oder wenn man das System wechselt. cp1252 ist Windows+Westeuropa-typisch.
sea-live
User
Beiträge: 440
Registriert: Montag 18. Februar 2008, 12:24
Wohnort: RP

Donnerstag 6. März 2008, 19:17

Code: Alles auswählen

wx.StaticText(parent, id, label, pos, size, style, name)
A::Was kann man unter Style für Schriftarten wählen
B::Kann man mit Size die Grösse der Schrift einstellen oder nur die Länge und Breite des Anzeigefeldes

danke
in der Python Doc ist da nix erwähnt!
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

Donnerstag 6. März 2008, 20:02

sea-live hat geschrieben:A::Was kann man unter Style für Schriftarten wählen
B::Kann man mit Size die Grösse der Schrift einstellen oder nur die Länge und Breite des Anzeigefeldes

danke
in der Python Doc ist da nix erwähnt!
Hallo sea-live!

Bei wxPython kannst du dich meist an die wxWidgets-Dokumentation halten. Für wx.StaticText: http://wxwidgets.org/manuals/stable/wx_ ... ctext.html

Und hier ist die Klassenreferenz zu finden: http://wxwidgets.org/manuals/stable/wx_classref.html

Und mit "size" kannst du nur die Größe des StaticText-Feldes angeben. -- Was man aber normalerweise nicht macht, da man Sizer verwendet. Und wenn du jetzt nicht weißt wovon ich spreche, dann empfehle ich dir "wxPython in Action". ;-)

mfg
Gerold
:-)
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
sea-live
User
Beiträge: 440
Registriert: Montag 18. Februar 2008, 12:24
Wohnort: RP

Freitag 7. März 2008, 20:39

Danke Gerold
Ich würde halt gerne mein Tkinter layout mit wxPython aufmotzen so mit runterklapenden kalendern und File_dialogen bestimmt toll
aber das mit den Texten nur STATIC ist nicht schön!

eine Anlhenung an MLDOWNLOADER Kommerzioell möchte ich vermeiden.

PS kein witz nur OpenSource zugelassen auf der Softwaresammlung für die
Mars1 2020 nasa.org
meine bewerbung steht schon fest
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

Freitag 7. März 2008, 21:23

sea-live hat geschrieben:aber das mit den Texten nur STATIC ist nicht schön
Hallo sea-live!

Das muss ich jetzt nicht verstehen, oder? Das Beispiel mit ``wx.StaticText`` ist ja von dir gekommen.

mfg
Gerold
:-)
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
sea-live
User
Beiträge: 440
Registriert: Montag 18. Februar 2008, 12:24
Wohnort: RP

Samstag 8. März 2008, 12:59

gerold hat geschrieben:
sea-live hat geschrieben:aber das mit den Texten nur STATIC ist nicht schön
Hallo sea-live!

Das muss ich jetzt nicht verstehen, oder? Das Beispiel mit ``wx.StaticText`` ist ja von dir gekommen.

mfg
Gerold
:-)
Mir ging es rein darumm das es doch sinnvoll wäre in Python wenigstens
mal Fett andere Schriftart oder Grösser zu Schreiben in einem Frame Dialog oder der gleichen

einfach so wie in Tkinter oder wx.richText
warumm ist da nur Plain Text möglich gibt es dafür einen Plausiblen grund

Hintergrund mein Hauptprogramm ist nun in Tkinter wegen TEXT
das Unterprogramm in Frame und das wiederum ruft PyQ auf wegen stylings im calender

ist das bei den profies auch so das Module aus den verschiedenen Skriptsprachen kombiniert werden?
Leonidas
Administrator
Beiträge: 16024
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Samstag 8. März 2008, 13:34

sea-live hat geschrieben:ist das bei den profies auch so das Module aus den verschiedenen Skriptsprachen kombiniert werden?
Es ist üblich, das man in einer Sprache auch Dinge verwendet die in anderen Sprachen geschrieben sind. Oder was meinst du eigentlich?
My god, it's full of CARs! | Leonidasvoice vs Modvoice
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

Samstag 8. März 2008, 14:21

sea-live hat geschrieben:warumm ist da nur Plain Text möglich
Hallo sea-live!

Bitte schau dir doch noch mal die ganze wxPython-Demo an. Dort wird ja nicht unbedingt mit Formatierungen gezeizt. Und der Grund, weshalb der gesamte Text in einem wx.StaticText nur eine Schriftart haben kann, liegt schlicht und ergreifend darin zu suchen, dass dieses Ding genau dafür geschrieben wurde.

Wenn du Formatierungen willst, dann setze "wx.lib.fancytext" oder noch einfacher, "wx.lib.fancytext.StaticFancyText" ein. Suche einfach immer in der wxPython-Demo ob du dort etwas findest, was dem entspricht, was du haben möchtest.

mfg
Gerold
:-)

PS: "wxPython in Action" ;-)
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
sea-live
User
Beiträge: 440
Registriert: Montag 18. Februar 2008, 12:24
Wohnort: RP

Samstag 8. März 2008, 17:59

DANKE DAS WARS

***wx.lib.fancytext***

was ich in den letzten Tagen gesucht hatte.!

Mercy Gerold
snakeseven
User
Beiträge: 405
Registriert: Freitag 7. Oktober 2005, 14:37
Wohnort: Berlin
Kontaktdaten:

Freitag 14. März 2008, 13:19

Hallo nochmal,

auch wenn mir sea-live ein anderes Problem in mein Thema gemogelt hat :wink: , möchte ich doch nochmal auf mein Kodierungsproblem zurückkommen. Inzwischen funktioniert das, was bis gestern noch funktionierte, nicht mehr!? Warum weiß ich nicht :roll:

Hier der Programm-Code, welcher zu folgender Fehlermeldung führt:

Code: Alles auswählen

n = n.encode(systemencoding)
  File "C:\Programme\Python25\lib\encodings\cp1252.py", line 12, in encode
    return codecs.charmap_encode(input,errors,encoding_table)
UnicodeEncodeError: 'charmap' codec can't encode character u'\x84' in position 1: character maps to <undefined>

Code: Alles auswählen

#!/usr/bin/env python
# -*- coding: UTF-8 -*-

import os
import urllib2
import locale

workspace = os.getcwd()
systemencoding =  locale.getdefaultlocale()[1]

country_names = []
country_ids = []


def get_countrynames():
    url = 'http://topartists.myspace.com/index.cfm?fuseaction=music.topBands'
    
    connected = False
    try:
        u = urllib2.urlopen(url)
    except urllib2.URLError:
        pass
    else:
        try:
            source =  u.read()
            connected = True
        except:
            pass
        else:
            try:
                charset = get_charset(source)
            except:
                charset = ''
            if charset != '':
                try:
                    source = unicode(source, charset)   
                except:
                    pass
    
                    
    if connected:
        pos1 = source.find('</option><option value="AF">')
        if pos1 > 0: 
            pos2 = source.find('</select></td>',pos1)
            wholestring = source[pos1:pos2]
            wholestring = wholestring.replace('</option><option value=','%')
            wholestring = wholestring.replace('selected>','')
            wholestring = wholestring.replace('</option>','')
            ws = wholestring.split('%')

            savefile = []
            for n in ws:
                country_names.append(n[5:])
                country_ids.append(n[1:3])
                savefile.append(n[5:]+'%'+n[1:3])
            del country_names[0]
            del country_ids[0]
            del savefile[0]
            
            sf = ''
            for n in savefile:
                sf += n+'\n'
                
            d= open(workspace + "/countries.txt", "w")
            d.write(sf.encode(systemencoding))
            d.close()

            
            
def get_charset(code):
    pos1 = code.find('<meta')
    pos2 = code.find('charset=', pos1) + 8
    pos3 = code.find('"', pos2)
    charset = code[pos2:pos3]
        
    if charset not in ['utf-8','UTF-8','iso-8859-15','ISO-8859-15','iso-8859-1','ISO-8859-1']:
        charset = 'utf-8'
        
    return charset
    
    
get_countrynames()
Ich dachte, ich hätte alles so gemacht, wie mir empfohlen. Was reingeht in Unicode wandeln, was rausgeht in den Code, den das System zum Speichern verwendet.

Grüße,
Seven
Benutzeravatar
mkesper
User
Beiträge: 919
Registriert: Montag 20. November 2006, 15:48
Wohnort: formerly known as mkallas
Kontaktdaten:

Freitag 14. März 2008, 14:00

snakeseven hat geschrieben:

Code: Alles auswählen

n = n.encode(systemencoding)
  File "C:\Programme\Python25\lib\encodings\cp1252.py", line 12, in encode
    return codecs.charmap_encode(input,errors,encoding_table)
UnicodeEncodeError: 'charmap' codec can't encode character u'\x84' in position 1: character maps to <undefined>
Ich dachte, ich hätte alles so gemacht, wie mir empfohlen. Was reingeht in Unicode wandeln, was rausgeht in den Code, den das System zum Speichern verwendet.
Nein, empfohlen ist, alles auch in Unicode zu speichern. Sonst fällst du mit eben diesem Fehler auf die Schnauze, falls ein Code nicht nach cp1252 umgewandelt werden kann.
Kurz: Alte Daten können in verschiedenen Formaten reinkommen, damit muß man leben und diese nach Unicode umwandeln. Vom Programm erzeugte Daten nur in Unicode (bzw. eben UTF-8, eine Art gepackte Darstellung von Unicode) abspeichern.
Leonidas
Administrator
Beiträge: 16024
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Freitag 14. März 2008, 14:50

mkallas hat geschrieben:Nein, empfohlen ist, alles auch in Unicode zu speichern.
Du kannst Unicode nicht einfach so speichern. Dazu musst du es so oder so enkodieren. Etwa in UTF-8. Aber: UTF-8 ist nicht Unicode - dieses Mißverständnis ist eben eines der Probleme mit Unicode.
My god, it's full of CARs! | Leonidasvoice vs Modvoice
Benutzeravatar
mkesper
User
Beiträge: 919
Registriert: Montag 20. November 2006, 15:48
Wohnort: formerly known as mkallas
Kontaktdaten:

Freitag 14. März 2008, 15:07

Leonidas hat geschrieben:UTF-8 ist nicht Unicode - dieses Mißverständnis ist eben eines der Probleme mit Unicode.
So habe ich es auch nicht gesagt.
Wikipedia hat geschrieben:UTF-8 (Abk. für 8-bit Unicode Transformation Format) ist die am weitesten verbreitete Kodierung für Unicode-Zeichen.
snakeseven
User
Beiträge: 405
Registriert: Freitag 7. Oktober 2005, 14:37
Wohnort: Berlin
Kontaktdaten:

Freitag 14. März 2008, 15:18

Hallo,

ich habe das Problem ja nicht nur beim Speichern (obwohl es an anderer Stelle, wo die geladenen Seiten UTF-8 sind, nicht auftritt, sogar Skandinavische Sonderzeichen werden da richtig gespeichert), sondern auch beim Darstellen in einer Listbox. Obwohl Unicode, kann wxPython einige Zeichen offenbar nicht richtig darstellen (ich habe die Unicode-Version installiert). Auch dieses Problem taucht nicht bei den Seiten auf, die UTF-8 sind. Erst seit MySpace mich auf ihren Deutschen Server umleitet, wo ISO-8859-15 verwendet wird, habe ich diesen Ärger.

Und in Unicode abspeichern geht auch nicht:

Code: Alles auswählen

d.write(sf)                          #.encode(systemencoding))
UnicodeEncodeError: 'ascii' codec can't encode characters in position 15-16: ordinal not in range(128)

Code: Alles auswählen

#!/usr/bin/env python
# -*- coding: UTF-8 -*-

import wx
import os
import urllib2
import locale

workspace = os.getcwd()
systemencoding =  locale.getdefaultlocale()[1]

country_names = []
country_ids = []


def get_countrynames():
    url = 'http://topartists.myspace.com/index.cfm?fuseaction=music.topBands'
    
    connected = False
    try:
        u = urllib2.urlopen(url)
    except urllib2.URLError:
        pass
    else:
        try:
            source =  u.read()
            connected = True
        except:
            pass
        else:
            try:
                charset = get_charset(source)
            except:
                charset = ''
            if charset != '':
                try:
                    source = unicode(source, charset)   
                    print type(source)
                except:
                    pass
    
                    
    if connected:
        pos1 = source.find('</option><option value="AF">')
        if pos1 > 0: 
            pos2 = source.find('</select></td>',pos1)
            wholestring = source[pos1:pos2]
            wholestring = wholestring.replace('</option><option value=','%')
            wholestring = wholestring.replace('selected>','')
            wholestring = wholestring.replace('</option>','')
            ws = wholestring.split('%')

            savefile = []
            for n in ws:
                country_names.append(n[5:])
                country_ids.append(n[1:3])
                savefile.append(n[5:]+'%'+n[1:3])
            del country_names[0]
            del country_ids[0]
            del savefile[0]
            
            #sf = ''
            #for n in savefile:
                #sf += n+'\n'
                
            #d= open(workspace + "/countries.txt", "w")
            #d.write(sf.encode(systemencoding))
            #d.close()
            
            Ausgabe()

            
            
def get_charset(code):
    pos1 = code.find('<meta')
    pos2 = code.find('charset=', pos1) + 8
    pos3 = code.find('"', pos2)
    charset = code[pos2:pos3]
        
    if charset not in ['utf-8','UTF-8','iso-8859-15','ISO-8859-15','iso-8859-1','ISO-8859-1']:
        charset = 'utf-8'
        
    return charset
    
    
    
class Ausgabe(wx.Frame):
    def __init__(self):
        wx.Frame.__init__(self, None, -1, '', size=(250, 325))
        panel = wx.Panel(self, -1)
        self.lbcountry = wx.ListBox(panel, -1, (19, 19), (204, 173), country_names, wx.LB_MULTIPLE)
        
        self.Show()
        self.Center()



class MyApp(wx.App):
    def OnInit(self):
        get_countrynames()
        return True
   
   
app = MyApp(0)
app.MainLoop()
Update:
Unicode muss zum Speichern in utf-8 oder Latin-1 encodiert werden. (Python Cookbook S.51), da hat Leonidas Recht.
Das geht auch ohne Probleme. Lade ich das File dann aber zur Kontrolle wieder in SciTE und stelle SciTE auf utf-8, werden auch hier Umlaute und Sonderzeichen falsch dargestellt. Also ist der gespeicherte Text nicht utf-8 ?

Grüße,
Seven
Antworten