Fehlermeldungen von QDomDocument::setContent() übersetzen
-
Leider werden diese immer von Qt nur auf englisch ausgegeben. Ich könnte diese Strings natürlich selbst aus den Quellen heraus kopieren und mit
linguist
auf deutsch übersetzen; allerdings denke ich, dass dies wirklich ein Rad wäre, das man nicht selbst erfinden müsste...Gibt es im WWW irgendwo Links zu solchen fertigen Übersetzungen (auch ggf. in anderen Sprachen)?
-
~~Die Texte sind nicht in Qt übersetzt - ~~ siehe https://code.woboq.org/qt5/qtbase/src/xml/sax/qxml.cpp.html#63
~~-> Du musst sie selbst übersetzen.
Falsch - wie Du siehst sind sie mit QT_TR_NOOP markiert. Also müssten sie in der Qt-Translation mit dabei sein. Muss diese natürlich laden.
-
Danke, Christian. Allerdings habe ich gemeint, dass QT_TR_NOOP eben ein "no-op" ist, also ein Makro, das eben nichts macht...?
In der Qt-Hilfe steht ebenfalls, dass man die Strings selbst übersetzen muss. Werde ich jetzt wohl machen müssen.
-
@Robert-Hairgrove said in Fehlermeldungen von QDomDocument::setContent() übersetzen:
In der Qt-Hilfe steht ebenfalls, dass man die Strings selbst übersetzen muss. Werde ich jetzt wohl machen müssen.
Wo
Allerdings habe ich gemeint, dass QT_TR_NOOP eben ein "no-op" ist, also ein Makro, das eben nichts macht...?
Siehe https://doc.qt.io/qt-5/i18n-source-translation.html#using-qt-tr-noop-and-qt-translate-noop-in-c
-
@Christian-Ehrlicher said in Fehlermeldungen von QDomDocument::setContent() übersetzen:
@Robert-Hairgrove said in Fehlermeldungen von QDomDocument::setContent() übersetzen:
In der Qt-Hilfe steht ebenfalls, dass man die Strings selbst übersetzen muss. Werde ich jetzt wohl machen müssen.
Wo
Hier: https://doc.qt.io/qt-5/qdomdocument.html#setContent (im 3. Absatz, der mit dem Text beginnt: "If a parse error occurs..."; s. letzten Satz: "Note that, if you want to display these error messages to your application's users, they will be displayed in English unless they are explicitly translated."
-
Sie sind aber in der Qt - ts - Datei mit dabei - siehe https://code.qt.io/cgit/qt/qttranslations.git/tree/translations/qtbase_de.ts?h=5.15.2#n7455
Du musst sie nur selbst im Code übersetzen mit QCoreApplication::translate()
-
Aha ... habe jetzt etwas gefunden. In der Datei
qtbase_de.ts
stehen sie unter dem<context>
-Element mit NamenQXml
.
Ich hatte nach dem KontextQtXml
gesucht und nichts gefunden!Das muss ich jetzt testen, ob die Fehlermeldungen in meiner Anwendung tatsächlich auf deutsch erscheinen ...
qtbase_de.qm
wird natürlich vorher geladen. -
Ok -- es scheint, dass man noch irgendwas machen muss, um zur Laufzeit an die Übersetzungen heranzukommen. Hier ein Test-Konsolenprogrämmchen:
#test_xml.pro QT -= gui QT += xml CONFIG += c++11 console CONFIG -= app_bundle SOURCES += \ main.cpp
// main.cpp #include <QCoreApplication> #include <QDomDocument> #include <QFile> #include <QByteArray> #include <QTranslator> #include <iostream> const char * xmlfile = "<...Pfad zu einer XML-Datei...>"; int main(int argc, char *argv[]) { using namespace std; QCoreApplication a(argc, argv); QTranslator translator; bool trans_loaded = translator.load("qtbase_de.qm"); // muss im aktuellen Anwendungsverzeichnis vorliegen... if (trans_loaded) { trans_loaded = QCoreApplication::installTranslator(&translator); } QString msg; int line = -1; int column = -1; QDomDocument d; QFile f(xmlfile); if (f.open(QIODevice::ReadOnly)) { QByteArray ba = f.readAll(); d.setContent(ba, &msg, &line, &column); } else { cout << "Fehler beim Oeffnen einer Datei: " << f.errorString().toUtf8().constData() << endl; return 1; } if (trans_loaded) { cout << "Translator geladen!" << endl; } if (!msg.isEmpty()) { cout << "XML-Fehler: " << msg.toUtf8().constData() << "\n" << "Zeile: " << line << ", Spalte: " << column << endl; } else { cout << "XML ohne Fehler" << endl; } return a.exec(); }
Wie kann ich nun die bestehenden Übersetzungen zur Laufzeit einbinden? Diese werden doch auf englisch ausgegeben.
-
@Christian-Ehrlicher said in Fehlermeldungen von QDomDocument::setContent() übersetzen:
Du musst sie nur selbst im Code übersetzen mit QCoreApplication::translate()
-
Inzwischen geht es; allerdings funktioniert es nicht mit
QCoreApplication::translate()
(das habe ich auch probiert -- evtl. aber nicht richtig?). Ich musste schonQTranslator::translate()
einsetzen und den Kontext"QXml"
mit übergeben.Ein
QMap
oderstd::map
braucht es auch, weil man keinen Zugriff auf die Fehlermeldung hat, nachdem Qt das schon ausgegeben hat.Hier die vollständige Lösung:
// main.cpp #include <QCoreApplication> #include <QDomDocument> #include <QFile> #include <QByteArray> #include <QTranslator> #include <QMap> #include <QString> #include <iostream> const char * xmlfile = "...<Pfad zur XML-Datei>..."; int main(int argc, char *argv[]) { using namespace std; QCoreApplication a(argc, argv); QTranslator translator; bool trans_loaded = translator.load("qtbase_de.qm"); // muss im aktuellen Anwendungsverzeichnis vorliegen... if (trans_loaded) { trans_loaded = QCoreApplication::installTranslator(&translator); } QMap<QString, QString> xml_error_map; xml_error_map["no error occurred"] = translator.translate("QXml","no error occurred"); xml_error_map["error triggered by consumer"] = translator.translate("QXml","error triggered by consumer"); xml_error_map["unexpected end of file"] = translator.translate("QXml","unexpected end of file"); xml_error_map["more than one document type definition"] = translator.translate("QXml","more than one document type definition"); xml_error_map["error occurred while parsing element"] = translator.translate("QXml","error occurred while parsing element"); xml_error_map["tag mismatch"] = translator.translate("QXml","tag mismatch"); xml_error_map["error occurred while parsing content"] = translator.translate("QXml","error occurred while parsing content"); xml_error_map["unexpected character"] = translator.translate("QXml","unexpected character"); xml_error_map["invalid name for processing instruction"] = translator.translate("QXml","invalid name for processing instruction"); xml_error_map["version expected while reading the XML declaration"] = translator.translate("QXml","version expected while reading the XML declaration"); xml_error_map["wrong value for standalone declaration"] = translator.translate("QXml","wrong value for standalone declaration"); xml_error_map["encoding declaration or standalone declaration expected while reading the XML declaration"] = translator.translate("QXml","encoding declaration or standalone declaration expected while reading the XML declaration"); xml_error_map["standalone declaration expected while reading the XML declaration"] = translator.translate("QXml","standalone declaration expected while reading the XML declaration"); xml_error_map["error occurred while parsing document type definition"] = translator.translate("QXml","error occurred while parsing document type definition"); xml_error_map["letter is expected"] = translator.translate("QXml","letter is expected"); xml_error_map["error occurred while parsing comment"] = translator.translate("QXml","error occurred while parsing comment"); xml_error_map["error occurred while parsing reference"] = translator.translate("QXml","error occurred while parsing reference"); xml_error_map["internal general entity reference not allowed in DTD"] = translator.translate("QXml","internal general entity reference not allowed in DTD"); xml_error_map["external parsed general entity reference not allowed in attribute value"] = translator.translate("QXml","external parsed general entity reference not allowed in attribute value"); xml_error_map["external parsed general entity reference not allowed in DTD"] = translator.translate("QXml","external parsed general entity reference not allowed in DTD"); xml_error_map["unparsed entity reference in wrong context"] = translator.translate("QXml","unparsed entity reference in wrong context"); xml_error_map["recursive entities"] = translator.translate("QXml","recursive entities"); xml_error_map["error in the text declaration of an external entity"] = translator.translate("QXml","error in the text declaration of an external entity"); QString msg, xmlmsg; int line = -1; int column = -1; QDomDocument d; QFile f(xmlfile); if (f.open(QIODevice::ReadOnly)) { QByteArray ba = f.readAll(); d.setContent(ba, &xmlmsg, &line, &column); } else { cout << "Error opening file: " << f.errorString().toUtf8().constData() << endl; return 1; } if (trans_loaded) { cout << "Translator loaded!" << endl; } if (!xmlmsg.isEmpty()) { if (xml_error_map.contains(xmlmsg)) { msg = xml_error_map[xmlmsg]; } else { msg = xmlmsg; } cout << "Error message: " << msg.toUtf8().constData() << "\n" << "Line: " << line << ", column: " << column << endl; } else { cout << "No error" << endl; } return a.exec(); }
Hoffentlich hilft das auch anderen Entwickler/innen.
-
Nun habe ich das in mein aktuelles Projekt ungefähr so eingebracht (
"m_"
ist alsQMap<int, QString>
definiert):QTranslator *current_qt_translator = nullptr; // anderer Code... bool translator_loaded = current_qt_translator || ((current_qt_translator = new QTranslator) && (current_qt_translator->load("<path to qtbase_de.qm>")) && (QCoreApplication::installTranslator(current_qt_translator)); // anderer Code... if (translator_loaded) { m_[E_XMLERR_OK] = current_qt_translator->translate("QXml","no error occurred"); m_[E_XMLERR_ERRORBYCONSUMER] = current_qt_translator->translate("QXml","error triggered by consumer"); m_[E_XMLERR_UNEXPECTEDEOF] = current_qt_translator->translate("QXml","unexpected end of file"); /* ... etc. ... */ } else { //Constants on the right of the assignment are defined elsewhere as the above strings. // Unfortunately, tr() etc. do not work except with literal strings // which is why they are written out in the "if()" branch: m_[E_XMLERR_OK] = SBBL_XMLERR_OK ; m_[E_XMLERR_ERRORBYCONSUMER] = SBBL_XMLERR_ERRORBYCONSUMER; m_[E_XMLERR_UNEXPECTEDEOF] = SBBL_XMLERR_UNEXPECTEDEOF; /* ... etc. ... */ }
Das Problem verbleibt, dass
lupdate
nun in meiner eigenen.ts
-Datei eine KategorieQXml
generiert, die die gleichen Texte zur Übersetzung anbietet. Ich könnte das zwar einfach ignorieren und unübersetzt lassen; viel schöner wäre es, wenn ich sie im Quelltext aber ausschliessen könnte (schliesslich gibt es ja schon die Übersetzungen inqtbase_de.qm
...)Gibt es ein Makro o.ä., das ich zu diesem Zweck einsetzen könnte?
Vielen Dank für Ratschläge!
-
Einfach nicht hier übersetzen sondern bei der späteren Nutzung.
-
Hmm ... ich habe es nochmals mit Konstanten bzw. Makros anstatt Literal-Strings für die englischen Fehlermeldungen versucht, und es scheint jetzt zu funktionieren! Mit der Indirektion über Makros generiert
lupdate
keine überflüssigen Übersetzungen mehr, und der Aufruf vonQTranslator::translate()
funktioniert immer noch.Evtl. wurde
lupdate
zwischen Qt 5.12.9 und 5.15.5 geändert? Früher war das m.E. noch ein Problem, aber vielleicht hatte ich nicht genug getestet...