Language Probleme

Alles rund um die Programmierung mit Qt
patrik08
Beiträge: 746
Registriert: 27. Februar 2006 10:48
Wohnort: DE Freiburg

Beitrag von patrik08 »

der file wird geladen ....

aber das ist keine qt class!

class MyWidget : public QWidget
{
/////Q_OBJECT

public:
MyWidget(QWidget* parent = 0);
};

frage dich doch warum tr("Quit") nicht uebersetz wird in der main.cpp!
ohne Q_OBJECT .... ist es etwa das selbe....

viele beispiele von diesem forum werden schnell auf 8/15 per hand gescrieben... doch selten werden beispiele mit ui file gemacht wo es eben zwingend ist eine richtige qt class zu machen!

gehe di doc durch (nicht von boost) um zu lernen richtige qt class zu setzen....

gruesse aus der Italienische Schweiz.....

main.cpp

Code: Alles auswählen

#include <MyWidget.hpp>

#include <QApplication>
#include <QTranslator>
#include <QLocale>
#include <QLibraryInfo>
#include <QMessageBox>
#include <QtGui>
#include <QString>
#include <QProcess>
#include <QFile>

bool is_file(QString fullFileName)
{
    QFile f( fullFileName );
	if ( f.exists() ) {
    return true;
	} else {
	return false;
    }
}


int main(int argc, char *argv[])
{
	QApplication app(argc, argv); 

	
     QString langfile =QString(QLocale::system().name());  
     langfile.resize(2); /* return first two lowercase letter !*/ 
     langfile.toLower();
   
    
#if defined( Q_WS_X11 ) 
QString transdirfile=PREFIX"/share/appname/i18n/QtBoost_"+langfile+".qm"; 
#endif 
#if defined( Q_WS_MACX ) 
QString transdirfile="/Applications/appname/Contents/Resources/i18n/QtBoost_"+langfile+".qm";  
#endif 
#if defined(Q_WS_WIN) 
QString transdirfile=QCoreApplication::applicationDirPath()+"/i18n/QtBoost_"+langfile+".qm"; 
#endif 
    
    
	 QTranslator translator; 
     translator.load(transdirfile); 
     app.installTranslator( &translator ); 

	 bool langHere = is_file(transdirfile);
    
    
	if(!langHere) {
		QMessageBox::warning(0, "Language from os "+QString(QLocale::system().name()), "too bad ... not found file ... "+transdirfile);
    }
	

	MyWidget widget; 
	widget.show(); 
	
	return app.exec();
} 

QtBerserker
Beiträge: 71
Registriert: 15. Mai 2006 09:07

Beitrag von QtBerserker »

das Q_OBJECT auskommentiert ist, ist schon richtig bei Verwendung von boost.signals in Verbindung mit Qt :D Das haben die leider vergessen zu erwähnen auf der boost.org Seite.

Q_OBJECT ist ja u.a. auch für das "RTTI" von Qt zuständig, entsprechend bekomme ich beim linken dann viele Errors wegen den Meta Dateien wenn ich es drinnen lasse. Diese Meta Infos werden durch boost ja nicht ersetzt. Daher die obige Einschränkung bzgl. der Verwendung von Qt + Boost.signals, da ich dass Qt-RTTI nicht probiert habe.

CU Olaf
QtBerserker
Beiträge: 71
Registriert: 15. Mai 2006 09:07

Beitrag von QtBerserker »

so, mutig geworden, geht es nun weiter, ohne boost.signals um vor Überraschungen sicher zu sein bzw. an der falschen Stelle zu suchen :twisted:

Nun soll die App dynamisch die Language ändern können, dazu habe ich das SDI Programm geändert :lol:

Code: Alles auswählen

void MainWindow::init()
{
    ...
    createActions();
    ...
    retranslateStrings();
    ...
}
void MainWindow::createActions()
{
    newAct = new QAction(this);
    newAct->setIcon(QIcon(":/images/new.png"));
    connect(newAct, SIGNAL(triggered()), this, SLOT(newFile()));

    openAct = new QAction(this);
    ....
}
void MainWindow::createMenus()
{
    fileMenu = menuBar()->addMenu(tr("&File"));
    ....
    createLangMenu();
    ....
}
QStringList MainWindow::findAppLangFiles()
{
	appLangPath = qApp->applicationDirPath() + "/i18n";
	QDir appLangDir(appLangPath);

	if(!appLangDir.exists()) {
		QMessageBox::warning(0, tr("Language Support Missing"), 
			tr("Unable to find application\n"
			"specific directory for language files."));
	}

	QStringList langFiles = 
		appLangDir.entryList(QStringList("*.qm"), QDir::Files, QDir::Name);

	for(QStringList::iterator i = langFiles.begin(); i != langFiles.end(); ++i) {
		*i = appLangDir.filePath(*i);
		langFileMap[languageName(*i)] = *i; // XXX displaced OO
	}

	return langFiles;
}
QString MainWindow::languageName(const QString &langFile)
{
	QTranslator translator;
    translator.load(langFile);

    return translator.translate("MainWindow", defaultLang.toLatin1());
}

void MainWindow::switchLanguage(QAction *act)
{
	qDebug() << "Switch Language, load " << langFileMap[act->text()];

	QTranslator translator;
	translator.load(langFileMap[act->text()]);
	qApp->installTranslator(&translator);
}
void MainWindow::createLangMenu()
{
	langMenu = menuBar()->addMenu(tr("&Language"));
	langActGrp = new QActionGroup(this);

    QStringList langFiles = findAppLangFiles();

    for (int i = 0; i != langFiles.size(); ++i) {
		QString lang = languageName(langFiles[i]);
		QAction *langAct = new QAction(lang, langActGrp);
		langAct->setCheckable(true);
		langAct->setChecked(lang == defaultLang);
		langAct->setActionGroup(langActGrp);
#if 1
		langMenu->addAction(langAct);
#else	// XXX Doesn't work! Why???
		langAct->setMenu(langMenu);
#endif
    }
	
	connect(langActGrp, SIGNAL(triggered(QAction *)),
		this, SLOT(switchLanguage(QAction *)));
}
void MainWindow::retranslateStrings()
{
    newAct->setText(tr("&New"));
    newAct->setShortcut(tr("Ctrl+N", "New"));
    newAct->setStatusTip(tr("Create a new file"));

    openAct->setText(tr("&Open..."));
    ...
    foreach(QAction *action, langActGrp->actions())
        action->setStatusTip(tr("Changes to Language to %1").arg(action->text()));
}
void MainWindow::changeEvent(QEvent *e)
{
	if (e->type() == QEvent::LanguageChange) {
		qDebug() << "got LanguageChange event";
		retranslateStrings();	
	} else {
		QMainWindow::changeEvent(e);
	}
}

const QString MainWindow::defaultLang(tr("English", "translated Language Name"));
Leider klappt das Translate beim Language Wechsel nicht, obwohl lt. qDebug alles relevante aufgerufen wird.

Wie kann ich die Menüs im nachhinein neu texten? Früher bei QT3 konnte man IDs vergeben .... Das gleiche Problem betrifft die Tool- und Statusbar. Wie bekomme ich QMessageBox::{warning|...} in anderen Sprachen hin?

Ich habe eine Hashmap für Language zu qm mapping eingeführt, hier im source etwas deplaziert aber wirksam. Ich könnte es in eigene Fkt. werfen, allerdings werden dann einige Variablen nochmals abgefragt konkret languageName(). Gibt's andere Möglichkeiten?

Müssen die anderen Widgets, zB FindDlg, ebenfalls die event Funktion überschreiben und FindDlg::retranslateStrings() aufrufen? Alle DialogTexte in einer Klasse zu behalten, wie das einige Bsp. von qt mH. des Context machen, halte ich für zu umständlich; Jede Klasse sollte ihren eigenen retranslateStrings() member haben.

Zuletzt, was ist der Unterschied zu langMenu->addAction(langAct) und langAct->setMenu(langMenu)? Bei ersteren erscheint das menu, beim letzteren nicht.

Viele Grüße
Olaf
patrik08
Beiträge: 746
Registriert: 27. Februar 2006 10:48
Wohnort: DE Freiburg

Beitrag von patrik08 »

mit event solte das gehen.. style switschen geht ja auch...
aber ich sehe kein "removeTranslator"

void QCoreApplication::removeTranslator ( QTranslator * messageFile ) [static]
Removes the message file messageFile from the list of message files used by this application. (It does not delete the message file from the file system.)
QtBerserker
Beiträge: 71
Registriert: 15. Mai 2006 09:07

Beitrag von QtBerserker »

removeTranslator fehlt tatsächlich, ansonsten such Qt lt. Doku alle installierten Languages durch bis der String passend ist. Zumindest klappt es erstmal so:

Code: Alles auswählen

void MainWindow::switchLanguage(QAction *act)
{
	qDebug() << "Switch Language, load " << langFileMap[act->text()];

	QCoreApplication::removeTranslator(appTranslator);
	appTranslator = new QTranslator(this);
	appTranslator->load(langFileMap[act->text()]);
	qApp->installTranslator(appTranslator);
}
In init() musste ich retranslateStrings() rausnehmen, da es ansonsten 2x aufgrufen worden wäre. So richtig klar ist mir das nicht - anscheinend bekommt die App bereits beim starten einen languageChange Event?

CU Olaf
patrik08
Beiträge: 746
Registriert: 27. Februar 2006 10:48
Wohnort: DE Freiburg

Beitrag von patrik08 »

ist dass alles in der main ? oder hast du ein signal pointer zu qApp?

zwichen qt4 opensource 4.0 bis 4.1.3 habe ich eine demo gesehen die ...sprache umschaltet....

aber wenn deine methode geht .... ist ja super... :D
QtBerserker
Beiträge: 71
Registriert: 15. Mai 2006 09:07

Beitrag von QtBerserker »

Sehe ich das richtig, dass ich nur statische Strings zB der Menus und Action in retranslateStrings zu packen brauche? Die QMessageBox::msg nehmen alle die übersetzten Texte nach Wechsel des QTranslators an, ebenso die Statusbar.

patrik08, leider klappt die dyn. Language Umschaltung im Main nicht, da alles ausserhalb der Event Schleife von Qt ist ... (lasse mich aber gerne eines besseren belehren) :wink:

verbleiben nur noch:
- Design Problem mit der QHash<LangName,LangPathToQm> map - Ideen/Erfahrungen?
- retranslateStrings auch für die anderen Widgets? Imo ja, da die events ja durchgereicht werden (Observer Pattern). Allerdings scheint mir die Qt Doku da nicht sehr konsistent zu sein, mal überschreiben die event und mal changeEvent.
- Unterschied zu langMenu->addAction(langAct) und langAct->setMenu(langMenu)

Neu hinzugekommen: wonach geht das bei Qt, ob setText, setTitel, setWindowTitel und was-weiss-der-geier-noch??

CU Olaf
patrik08
Beiträge: 746
Registriert: 27. Februar 2006 10:48
Wohnort: DE Freiburg

Beitrag von patrik08 »

In der main sprachen umschalten... habe ich bereist gemacht...
das **.qm file ist einfach immer im userdir .name/default.qm
beim umschalten kommt einfach die de oder en draufkopiert... beim start...
vor load*** ... der nachteil .. das programm muss geschlossen werden ... und dann wieder aufmachen... :D da qt den geloadeten file nicht freigibt... auch loeschen geht nicht.... wen ein close & start der applikation machbar ist dann geht es...
QtBerserker
Beiträge: 71
Registriert: 15. Mai 2006 09:07

Beitrag von QtBerserker »

ja, das ist die Standardlösung, diese hatte ich bei meinem ersten Versuch (Seite 1) auch probiert und wird von den Trolls per Example propagiert. Für dynamisches Language switching mittel Qt4 - da werden die bsp. dünn und da hänge ich z.Zt.
macman
Beiträge: 1738
Registriert: 15. Juni 2005 13:33
Wohnort: Gütersloh
Kontaktdaten:

Beitrag von macman »

patrik08 hat geschrieben:der nachteil .. das programm muss geschlossen werden ... und dann wieder aufmachen... :D
Es geht auch ohne, ist allerdings etwas tricky, da man die Übersetzung selbst machen muss. Also das ersetzen der Texte, da sie vom retranslateUi nicht erfasst werden. Ob das den Aufwand wert ist, muss jeder selbst entscheiden.
Antworten