Unicode Problem...

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
Robokopp
User
Beiträge: 64
Registriert: Mittwoch 3. November 2010, 12:04

Hallo

ich weiß mal wieder nicht weiter^^
Mein Quiz hat eine integrierte Funktion "Fragen einreichen" mit der die Benutzer später bequem eigene Fragen an mich senden können, die ich dann per Updater an die Quizclienten liefere.

Aus einem meiner Threads resultierend verwende ich folgende Schreibweise für all meine Fragen:

Code: Alles auswählen

Question(u"Wieviele Stunden hat der Tag", u"24",u"36",u"7",u"8"),
Die Sektion "Fragen einreichen" besitzt 5 QLineEdits für die Frage und alle dazugehörigen Antworten und aus Bequemlichkeit möchte ich, das die fertige Formatierung für meinen Fragenkatalog bei mir als Email ankommt.Klappt auch, nur die Umlaute machen mir zu schaffen!

Code: Alles auswählen

        self.emailfrage=self.ui.emailquestion.text()
        self.emailfrage.decode("utf-8")
        
        self.emailright=self.ui.emailright.text()
        self.emailwrong1=self.ui.emailwrong1.text()
        self.emailwrong2=self.ui.emailwrong2.text()
        self.emailwrong3=self.ui.emailwrong3.text()
        emailtext="Question(u'"+str(self.emailfrage)+"',u'"+str(self.emailright)+"',u'"+str(self.emailwrong1)+"',u'"+str(self.emailwrong2)+"',u'"+str(self.emailwrong3)+"')"  
        .
        .
        .
        Blabla send
Die Zeile self.emailfrage.decode("utf-8") wirft den Fehler aus:

Code: Alles auswählen

    self.emailfrage.decode("utf-8")
AttributeError: 'QString' object has no attribute 'decode'

Code: Alles auswählen

self.emailfrage=unicode(self.emailfrage)
ändert nichts und

Code: Alles auswählen

self.emailfrage=unicode(self.emailfrage, "utf-8")
und

Code: Alles auswählen

self.emailfrage=unicode(self.ui.emailquestion.text())
ebenfalls nicht.

emailtext=u"" bringt auch nix und so weiter^^

Die Email die bei mir ankommt, wenn ich äöö als Frage eingebe enthält den Text:
Question(u'öää',u'',u'',u'',u'')

Ich steh irgendwie auf dem Schlauch, weil das sonst auch immer überall geklappt hat

MfG
Benutzeravatar
snafu
User
Beiträge: 6738
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Du willst Unicode in einen 8-Bit String umwandeln, richtig? Das macht man nicht mit `.decode()`, sondern mit `.encode()`. Aber auch das wird nicht mit `QString()`s funktionieren, weil es eben etwas anderes ist als Pythons Built-in `unicode()`. Generell scheint es, als würdest du nicht wirklich verstehen, was du da tust. Aber da biste nicht alleine mit. ;)

`QString()`s in PyQt werden jedenfalls zu einem nativen Python 2.x (Byte-)String, wenn man z.B. ihre Methode `.toLatin1()` benutzt. Diese gibt ein `QByteArray()` zurück, aus welchem du mittels `data()` einen Python-String bekommst. Das heißt also:

Code: Alles auswählen

self.emailfrage.toLatin1().data()
BlackJack

@Robokopp: Du möchtest anscheinend `unicode`-Objekte als literale `unicode`-Zeichenkette haben. Also das was `repr()` auf solche Objekte angewendet ergibt.

Aber ich würde das Zielformat an sich in Frage stellen. Du hast da Daten, also denk Dir ein passendes Format aus um Daten zu speichern. JSON oder XML würden sich dafür eher anbieten als Python-Quelltext.
Robokopp
User
Beiträge: 64
Registriert: Mittwoch 3. November 2010, 12:04

Ich bekomme folgenden Fehler

self.emailfrage.toLatin1().data()
AttributeError: 'unicode' object has no attribute 'toLatin1'

EDIT:

Habs schon, hatte weiter oben noch die Unicode Codierung drin, aber es ändert irgendwie dennoch nichts an der Email


DANKE =)
deets

Das liegt daran, das du offensichtlich wild zwischen QString und Python unicode-Objekten hin und her wechselst.

Mach dir mal klar, was woher kommt. Wenn es ein QString ist (weil du etwas aus der GUI holst), dann musst du das erst umwandeln. Aber danach nicht mehr! Und das wandeln machst du direkt beim holen, nicht spaeter.
Benutzeravatar
snafu
User
Beiträge: 6738
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Oder man verwendet einfach PySide. :)
Robokopp
User
Beiträge: 64
Registriert: Mittwoch 3. November 2010, 12:04

Werde ich auch mal machen

Noch eine Frage:

Gibt es Unicode-Unterschiede zwischen Python 2.5 und Python 2.6/2.7?

Ich werd noch zum Hirsch.Auf dem PC funktioniert alles einwandfrei, auf dem Handy nicht.Da werden richtige Fragen dann als falsch angesehen, weil wieder was nicht richtig kodiert ist
Benutzeravatar
snafu
User
Beiträge: 6738
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Das wird wohl nicht an der Python-Version liegen, sondern eher an der Plattform, auf der dein Programm verwendet wird. Vermutlich brauchst du nämlich eine jeweils andere Kodierung zur Ausgabe der Daten. Unter unixartigen Systemen (z.B. Linux) ist das ja häufig `utf-8`, während man unter Windows `cp1252` vewenden kann. Wenn auf dem Handy jetzt Symbian o.ä. drauf ist, dann wirst du da womöglich wieder etwas anderes brauchen (ich habe keine Ahnung von Smartphone-Programmierung).

Vielleicht reicht aber schon folgendes:

Code: Alles auswählen

import platform

on_windows = platform.system() == 'Windows'
encoding = 'cp1252' if on_windows else 'utf-8'
Robokopp
User
Beiträge: 64
Registriert: Mittwoch 3. November 2010, 12:04

ich hab das encoding im Header definiert

Code: Alles auswählen

# -*- coding: utf-8 -*-
Daran kann es also nicht liegen.

Ich mach das nach folgendem Prinzip:

ich hole die Frage und die 4 Antworten aus einer Liste.Die erste Antwort ist immer die richtige.

Die 4 Antworten werden auf 4 Buttons gelegt.Nun greife ich den Text des geklickten Buttons ab und vergleiche ihn mit der richtigen Antwort.Da tritt dann meistens der Fehler auf....
BlackJack

@Robokopp: Wo genau? Bei welchem Code auf welcher Plattform? Was vergleichst Du da? Also welche Typen habe die Objekte jeweils die Du vergleichst?
Robokopp
User
Beiträge: 64
Registriert: Mittwoch 3. November 2010, 12:04

Also, die Plattform ist Maemo (Debian).

Der Codeausschnitt, der Probleme bereitet:

Code: Alles auswählen

      self.question = random.choice(fragenkatalog.questions)
        self.ui.textfrage.setText(self.question.question)
        self.antwort1=unicode(self.question.answer, "utf-8")
        self.antwort2=unicode(self.question.answer2, "utf-8")
        self.antwort3=unicode(self.question.answer3, "utf-8")
        self.antwort4=unicode(self.question.answer4, "utf-8")

        l=[self.antwort1,self.antwort2,self.antwort3,self.antwort4]
        random.shuffle(l)
        
        self.ui.antwort_1.setText(l[0])
        self.ui.antwort_2.setText(l[1])
        self.ui.antwort_3.setText(l[2])
        self.ui.antwort_4.setText(l[3])

       
    def antwort_1(self):  
        antwort=self.ui.antwort_1.text()
        #antwort=antwort.toLatin1()
        if self.antwort1==antwort:
            self.ui.textfrage.append("\nIhre Antwort ist richtig")
            self.score+=10
            self.richtigefragen+=1
            self.ui.punktestand.setText("Punktestand: "+str(self.score)+" Falsche Antworten: "+str(self.niederlagencounter))
            self.ui.nextquest.show()
            self.ui.antwort_1.hide()
            self.ui.antwort_2.hide()
            self.ui.antwort_3.hide()
            self.ui.antwort_4.hide()
            self.soundrichtig()
        else:
            self.ui.textfrage.append("\nIhre Antwort ist falsch.\nDie richtige Anwort ist: "+self.antwort1)
            self.score-=10
            self.niederlagencounter+=1
            self.ui.punktestand.setText("Punktestand: "+str(self.score)+" Falsche Antworten: "+str(self.niederlagencounter))
            self.ui.antwort_1.hide()
            self.ui.antwort_2.hide()
            self.ui.antwort_3.hide()
            self.ui.antwort_4.hide()            
            self.ui.nextquest.show()
            self.soundfalsch()   
                
        self.status_check()
Das ist der Fehler der auf dem N900 ausgeworfen wird:

Bild

Vlt sollte ich noch dazu sagen, dass der Fehler erst auftritt, seit ich das Spiel im Extras-Devel Katalog habe.Wenn es unter /home/user/MyDocs/ liegt, funktioniert es wieder.Zz befindet es sich in /opt
deets

Und dein Problem ist immer noch, dass du nicht wirklich weisst, was du da tust. So wie es aussieht, dekodierst und enkodiertst du mal wild durch die Gegend.

Dein Problem laesst sich so nachvollziehen:

Code: Alles auswählen


# -*- coding: utf-8 -*-

u = u"ä"

u == u.decode("utf-8")

Ein .decode auf einem unicode-objekt macht halt Bloedsinn, weil es den unicode-string erstmal in einen byte-string wandeln will, bevor es ihn wieder umwandelt. Du kannst das umgehen, indem du das hier machst:

Code: Alles auswählen

# -*- coding: utf-8 -*-

u = u"ä"
u ==  u.decode("utf-8") if isinstance(u, str) else u
Aber eigentlich solltest du mal anfangen dich wirklich damit zu beschaeftigen, was unicode ist. Das was du hier zeigst ist alles ziemlicher Cargo-Cult.

[edit] Ich hab' die fragliche Zeile uebersehen, das war also falsch von mir zu behaupten die waere nicht dabei gewesen. Mea culpa.[/edit]
Robokopp
User
Beiträge: 64
Registriert: Mittwoch 3. November 2010, 12:04

Achso ja stimmt, die Zeile hab ich rausgenommen.

Hier das aktuelle Bild von der Ausgabe:

Bild

Okay, aber ich versteh nicht ganz was daran so falsch sein kann wenn es doch auf dem Pc funktioniert.

Hab das jetzt nochmal abgeändert:

Code: Alles auswählen

        self.antwort1=self.question.answer.decode("utf-8")
        self.antwort2=self.question.answer2.decode("utf-8")
        self.antwort3=self.question.answer3.decode("utf-8")
        self.antwort4=self.question.answer4.decode("utf-8")
Der Fehler besteht weiterhin
Benutzeravatar
snafu
User
Beiträge: 6738
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Was sagt in Meamo denn ein `sys.stdout.encoding`?
Robokopp
User
Beiträge: 64
Registriert: Mittwoch 3. November 2010, 12:04

Hat sich schon erledigt

habe antwort=antwort.toLatin1()
durch antwort="%s" % unicode(antwort) ersetzt.
BlackJack

@Robokopp: Das ist das gleiche wie nur ``antwort = unicode(antwort)``.
Benutzeravatar
snafu
User
Beiträge: 6738
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Das dürfte gleichwertig sein mit:

Code: Alles auswählen

'Die Antwort ist: {0}'.format(QString('42'))
//edit: Oder auch nicht. In der anderen Version kommt Unicode raus. Ich hatte gedacht, `%s` würde `str()` aufrufen.
Antworten