PDA

View Full Version : QSettings with translation



franco.amato
21st October 2010, 19:06
Hi to all,
I would know how set the settings of my application to manage translation.
For example if I choose english, when I restart the application I would have english as language.

Best Regards

wysota
21st October 2010, 20:58
What have you already done to try and solve your problem?

franco.amato
21st October 2010, 21:09
What have you already done to try and solve your problem?

pass a file path, set a QString, but I would know if there is a specific setting

wysota
21st October 2010, 21:11
So does it work or not? If not, what doesn't work?

franco.amato
21st October 2010, 21:22
So does it work or not? If not, what doesn't work?

Doesn't work! If I change language it always load the same.
So I ask again: is there a specific setting for language translation?

wysota
21st October 2010, 21:27
So how exactly do you store the setting?

franco.amato
21st October 2010, 21:38
So how exactly do you store the setting?


void MainWindow::closeEvent(QCloseEvent *ce )
{
Q_UNUSED(ce);
writeSettings();
}

and



void MainWindow::writeSettings()
{
QSettings settings("config.ini", QSettings::IniFormat);
/* language group */
settings.beginGroup("language");
settings.setValue("lang", m_language);
settings.endGroup();
/* paths group */
settings.beginGroup("paths");
settings.setValue("w1_source", m_w1SourceDir);
settings.setValue("w2_source", m_w2SourceDir);
settings.setValue("w1_output", m_w1OutputDir);
settings.setValue("w2_output", m_w2OutputDir);
settings.endGroup();
/* colors group */
settings.beginGroup("colors");
settings.setValue("background", m_bgColor);
settings.setValue("waveform", m_wfColor);
settings.setValue("timeline", m_tlColor);
settings.setValue("markers" , m_mkColor);
settings.setValue("selection", m_slColor);
settings.endGroup();
/* background */
settings.beginGroup("background");
settings.setValue("file", m_bgFile);
settings.setValue("loop_interval", m_loopInterval);
settings.setValue("loop_mode", m_loopMode);
settings.endGroup();
/* steps */
settings.beginGroup("steps");
settings.setValue("sec", m_sstep);
settings.setValue("min", m_mstep);
settings.endGroup();
}

wysota
21st October 2010, 21:45
I'm not sure that storing the settings in the current working directory is a good idea. Anyway, how does the reading part look like? Also does the configuration file get created? Does it have proper contents?

franco.amato
21st October 2010, 21:53
I'm not sure that storing the settings in the current working directory is a good idea.
So how must I do?

Anyway, how does the reading part look like?

It works for all settings except for the language


Also does the configuration file get created? Does it have proper contents?

Yes the content of the ini file is correct

wysota
21st October 2010, 22:03
So how must I do?
Either store the settings in a "well known location" like the user's home directory or use the application binary directory or let Qt choose the proper location.


It works for all settings except for the language
Please provide enough information for us to see how you try to apply the language change using your settings. I'm tired of having to drag every piece of information out of you. If you want help, provide enough information to see where the problem might be. And do it always, not only in this thread, you have already over 400 posts on this forum, for God's sake! Every thread of yours is at least 5 times longer than questions asked by others. If you have problem with specifying your problem, maybe you should take a look at how others do it.

squidge
21st October 2010, 22:04
and you read your settings file how?

franco.amato
21st October 2010, 22:13
Either store the settings in a "well known location" like the user's home directory or use the application binary directory or let Qt choose the proper location.
How can I let Qt decide where? Can I speak with Qt and ask where it would store the configuration file?



Please provide enough information for us to see how you try to apply the language change using your settings. I'm tired of having to drag every piece of information out of you. If you want help, provide enough information to see where the problem might be. And do it always, not only in this thread, you have already over 400 posts on this forum, for God's sake! Every thread of yours is at least 5 times longer than questions asked by others. If you have problem with specifying your problem, maybe you should take a look at how others do it.

Please wysota give a look at your replies. They are also written with Morse code, and I always have to ask 'please can you be more clear' or I always have to beg for 2 lines of clarifing code of example as in the above statement ( let Qt decide where ).
I'm sure I'm not the only person thinking that.
I stopped to post questions in the 'Programming' sections hoping to have more clear replies (to improve my Qt level) but is not so.

franco.amato
21st October 2010, 22:22
and you read your settings file how?

This is my routine to read settings:


void MainWindow::readSettings()
{
QSettings settings("config.ini", QSettings::IniFormat);
/* language group */
settings.beginGroup("language");
m_language = settings.value("lang", "en").toString();
settings.endGroup();
/* paths group */
settings.beginGroup("paths");
m_w1SourceDir = settings.value("w1_source", "C:").toString();
m_w2SourceDir = settings.value("w2_source", "C:").toString();
m_w1OutputDir = settings.value("w1_output", "C:").toString();
m_w2OutputDir = settings.value("w2_output", "C:").toString();
settings.endGroup();
/* background file */
settings.beginGroup("background");
m_bgFile = settings.value("file", "./audio de fondo/Grabacion_marca de agua_cruz report - MONO.mp3").toString();
m_loopMode = settings.value("loop_mode", "loop").toString();
m_loopInterval = settings.value("loop_interval", 5).toInt();
settings.endGroup();
/* steps */
settings.beginGroup("steps");
m_sstep = settings.value("sec", 1).toInt();
m_mstep = settings.value("min", 1).toInt();
settings.endGroup();
/* colors group */
settings.beginGroup("colors");
QColor defColor = Qt::white;
QVariant colVariant = defColor;
m_bgColor = settings.value( "background", colVariant ).value<QColor>();
m_wfColor = settings.value( "waveform", Qt::darkBlue ).value<QColor>();
m_tlColor = settings.value( "timeline", Qt::darkRed ).value<QColor>();
m_mkColor = settings.value( "markers", Qt::yellow ).value<QColor>();
m_slColor = settings.value( "selection", Qt::red ).value<QColor>();
settings.endGroup();
}

I installed 2 translation files in the main.cpp so:


QApplication app(argc, argv);

QTranslator enTranslator;
enTranslator.load( "ecpstudio_en");
app.installTranslator( &enTranslator );

QTranslator esTranslator;
esTranslator.load( "ecpstudio_es");
app.installTranslator( &esTranslator );

then I perform a test on the m_language variable ( after read the configuration file )


if ( QString::compare(m_language, "en", Qt::CaseInsensitive) == 0 )
// here I would do effective the english translation file
else
// here I would do effective the spanish translation file

squidge
21st October 2010, 23:00
Why multiple installTranslator? Just call it once depending on which language you want and use QObject::tr() for translations.

franco.amato
21st October 2010, 23:04
Why multiple installTranslator? Just call it once depending on which language you want and use QObject::tr() for translations.

So I only load them and then I'll install one or the other depending on the value of the variable?
Can I do it in every point of the code?

SixDegrees
21st October 2010, 23:24
So I only load them and then I'll install one or the other depending on the value of the variable?
Can I do it in every point of the code?

Please - for once - go and read the documentation provided with Qt on internationalization. Qt's system isn't the best I've seen, but it works and it's relatively simple. It does, however, require the person using it to make the small effort required to learn how it is used. There are extensive tutorials, documentation and sample code that describe all of the small number of details it possesses.

wysota
21st October 2010, 23:25
How can I let Qt decide where?
If you pass a file path using a constructor then the logical assumption would be to look at other constructors.


Can I speak with Qt and ask where it would store the configuration file?
If you want to "ask Qt" about something, you can read the reference manual.


Please wysota give a look at your replies. They are also written with Morse code, and I always have to ask 'please can you be more clear' or I always have to beg for 2 lines of clarifing code of example as in the above statement ( let Qt decide where ).
I'm expecting you to posses some knowledge. I won't tell you how to turn on your computer or login to your account. I expect you to know that. I also expect you to know how to do some basic things in Qt and if you are lazy enough not to find information about it yourself then I expect you to ask specific questions about problems you have. I expect to be talking not to a brainless brick but to an intelligent human being.


I stopped to post questions in the 'Programming' sections hoping to have more clear replies (to improve my Qt level) but is not so.
You won't improve yourself by asking questions. Learn by doing and trying to solve your problems first before you go somewhere and ask for help.

franco.amato
21st October 2010, 23:42
Please - for once - go and read the documentation provided with Qt on internationalization. Qt's system isn't the best I've seen, but it works and it's relatively simple. It does, however, require the person using it to make the small effort required to learn how it is used. There are extensive tutorials, documentation and sample code that describe all of the small number of details it possesses.

I already did.

I modified my code removing the QTranslation instance from main.cpp and adding it to my MainWindow.cpp ctor so:



MainWindow::MainWindow( QWidget *parent, Qt::WindowFlags flags )
: QMainWindow(parent, flags),
m_track1(""),
m_track2(""),
m_w1SourceDir(""),
m_w2SourceDir(""),
m_w1OutputDir(""),
m_w2OutputDir(""),
m_fileOneLoaded(false),
m_fileTwoLoaded(false),
m_trackListDlg(NULL)
{
setObjectName("MainWindow");

/* set window title */
setWindowTitle("ECP Studio");
//setMinimumSize(800, 400);

/* creo il menu e la status bar */
createActions();
createMenus();
createToolBar();
createStatusBar();

readSettings(); // here I fill the m_language variable

if( QString::compare(m_language,"es") == 0 )
{
QTranslator esTranslator;
esTranslator.load("ecpstudio_es");
QCoreApplication::instance()->installTranslator(&esTranslator);
}

/* set the central widget */
m_centralWidget = new CentralWidget( m_bgColor, m_wfColor, m_w1OutputDir, m_w2OutputDir, m_bgFile, m_mstep, m_sstep, m_loopInterval, this );
setCentralWidget( m_centralWidget );

enableGlobalCommands( false );

connect( check, SIGNAL( stateChanged( int ) ), this, SLOT( uniqueFileChanged( int ) ) );
connect( this, SIGNAL( synchSignal() ), m_centralWidget, SLOT( synchSlot()));
connect( this, SIGNAL( globalPlaySignal() ), m_centralWidget, SLOT( globalPlaySlot()));
connect( this, SIGNAL( globalStopSignal() ), m_centralWidget, SLOT( globalStopSlot()));
connect( this, SIGNAL( globalASecondiSignal() ), m_centralWidget, SLOT( globalASecondiSlot()) );
connect( this, SIGNAL( globalAMinutiSignal() ), m_centralWidget, SLOT( globalAMinutiSlot() ) );
connect( this, SIGNAL( globalIMinutiSignal() ), m_centralWidget, SLOT( globalIMinutiSlot()) );
connect( this, SIGNAL( globalISecondiSignal() ), m_centralWidget, SLOT( globalISecondiSlot()) );
}

and it has no effect, language is always english ( instead of spanish as it should be - because I set 'es' in the configuration file ).

Regards

Lykurg
22nd October 2010, 07:21
After 18 posts we have the full source code to answer your question. Great! But still we are missing some debug informations:
Is the if block entered?
Is load really returns true?
And you might want to move the translator installation to the top, since you don't support dynamic language switching. So all actions and menus wont get retranslated. But that all stands in the documentation as well.

wysota
22nd October 2010, 10:13
Franco, tell me, what is the value of "x" in the place marked with /* ??? */ in the following code? Could you explain why? As a hint - you can write a little program to test it:


if(true){
int x = 7;
}
/* ??? */

Lykurg
22nd October 2010, 10:44
Ahh, I am going crazy!:mad: First I thought the same, wysota, but before replying I had a quick look at the i18n example of the docs where they have the function
void LanguageChooser::checkBoxToggled()
{
QCheckBox *checkBox = qobject_cast<QCheckBox *>(sender());
MainWindow *window = mainWindowForCheckBoxMap[checkBox];
if (!window) {
QTranslator translator;
translator.load(qmFileForCheckBoxMap[checkBox]);
qApp->installTranslator(&translator);

window = new MainWindow;
window->setPalette(colorForLanguage(checkBox->text()));

window->installEventFilter(this);
mainWindowForCheckBoxMap.insert(checkBox, window);
}
window->setVisible(checkBox->isChecked());
}and thought (puzzled) that it would be possible. Now after having a closer look I understand the documentations code full and it isn't possible. Off course! Sometimes the examples are very trappy.

Edit: Nice question style with the /* ??? */ comment and you haven't forgot to place it inside the code :D

franco.amato
22nd October 2010, 17:12
Franco, tell me, what is the value of "x" in the place marked with /* ??? */ in the following code? Could you explain why? As a hint - you can write a little program to test it:


if(true){
int x = 7;
}
/* ??? */

OK I understood, it was a 'out of scope' problem.
Thank you

Added after 8 minutes:


Ahh, I am going crazy!:mad: First I thought the same, wysota, but before replying I had a quick look at the i18n example of the docs where they have the function
void LanguageChooser::checkBoxToggled()
{
QCheckBox *checkBox = qobject_cast<QCheckBox *>(sender());
MainWindow *window = mainWindowForCheckBoxMap[checkBox];
if (!window) {
QTranslator translator;
translator.load(qmFileForCheckBoxMap[checkBox]);
qApp->installTranslator(&translator);

window = new MainWindow;
window->setPalette(colorForLanguage(checkBox->text()));

window->installEventFilter(this);
mainWindowForCheckBoxMap.insert(checkBox, window);
}
window->setVisible(checkBox->isChecked());
}and thought (puzzled) that it would be possible. Now after having a closer look I understand the documentations code full and it isn't possible. Off course! Sometimes the examples are very trappy.

Edit: Nice question style with the /* ??? */ comment and you haven't forgot to place it inside the code :D

So why you (or the Qt developers ) offer example code containing errors?

wysota
22nd October 2010, 18:09
Can you point to the example containing errors?

franco.amato
22nd October 2010, 18:13
Can you point to the example containing errors?

Wysota the example posted by Lykurg contains similar code to what I posted yestarday and you commented with the little example

wysota
22nd October 2010, 18:20
Wysota the example posted by Lykurg contains similar code
As I understand what Lykurg posted was to show a non-working example. Now you claim that we or Qt devs give bad examples so please point me to the bad example in Qt so that we may together see if it really is an incorrect example.

franco.amato
22nd October 2010, 18:26
As I understand what Lykurg posted was to show a non-working example. Now you claim that we or Qt devs give bad examples so please point me to the bad example in Qt so that we may together see if it really is an incorrect example.

The i18n example

wysota
22nd October 2010, 18:33
And what is wrong with it exactly?

franco.amato
22nd October 2010, 19:17
And what is wrong with it exactly?

The LanguageChooser::checkBoxToggled doesn't contain an error?

wysota
22nd October 2010, 19:34
No, it doesn't. Where do you see the error? That the translator object is created on the stack and goes out of scope? This is perfectly fine as it is no longer needed.

franco.amato
22nd October 2010, 19:48
No, it doesn't. Where do you see the error? That the translator object is created on the stack and goes out of scope? This is perfectly fine as it is no longer needed.

So why in my case ( that the same code) it doesn't work?

wysota
22nd October 2010, 19:58
Because you delete the translator before it can do any of its work. Franco, trust me, if you don't go past pasting code from examples into your own programs, you will not make progress. You have to understand how things work before you start using them and not ask to have things explained to you (only) when the code you "borrow" doesn't work as you expect it to. Sometimes I think that the best we could do for you would be to stop answering your questions so that you were forced to do some research yourself. But I'm afraid that if not here then elsewhere you would find someone who would provide a working solution for you again preventing you from learning.

franco.amato
22nd October 2010, 20:05
Wysota sorry but I don't agree with you. I always search before ask here.
So please tell me where is the difference.

Franco code:

if( QString::compare(m_language,"es") == 0 )
{
QTranslator esTranslator;
esTranslator.load("ecpstudio_es");
QCoreApplication::instance()->installTranslator(&esTranslator);
}

Non_franco code:

if (!window)
{
QTranslator translator;
translator.load(qmFileForCheckBoxMap[checkBox]);
qApp->installTranslator(&translator);
//...more code
}

because I really can't see the difference

wysota
22nd October 2010, 20:28
The difference is in what is hidden in "//...more code".

Try to answer yourself this question: Why do you install a translator on an application?

Lykurg
22nd October 2010, 23:35
Ok, since my post starts a new "stage" of discussion and to reply direct on

So why you (or the Qt developers ) offer example code containing errors? some explanations:

After post #18 I thought it is an out of scope problem. To prove that I looked up at the documentation at the i18n example. There I found the posted LanguageChooser::checkBoxToggled() function and due to a too fast and not carefully enough reading I misunderstood the code! I repeat: misunderstood. I thought that there the out of scope problem also have to occur. But it doesn't, so (wrong conclusion) Qt must copy the translator somehow and store it itself. This is the point where I should have dug deeper because I should have become suspicious of such a behavior of Qt. Though, my mind failed me. I took the voodoo-copying-no-out-of-scope-translator for real.

After wysota's reply (#20) I wanted to write:
Haha (in a sound of Nelson from the Simpsons), no it is not a out of scope problem because Qt does a voodoo-copying-no-out-of-scope-translator-thing!But before such a post I wanted to be sure, so I looked up the documentation again. And - surprise - I recognized my mistake while I read the code again. There I was angry at myself for not getting suspicious and for not doing further research. But I also realized that at that point the example is trappy (in the meaning that one could easily misunderstand the code), not wrong.

So I just wanted to say, as a suggestion, that one could make the example code better. (and to say, that I am mad on me because for not reading carefully enough).


- Everything clear now?
- No!
- Ok, but I am happy we have talked about ;)


And: The documentation is great and I love it. 99,99% of it. 0,01% could improved, thats all.

wysota
23rd October 2010, 00:01
As a matter of fact I think there are lots of examples that need improvement, review or throwing them to trash. Like the threaded fortune server example which makes people think they need to have multiple threads in their network servers. But to be honest:
1. you should have looked in the docs for the example of i18n where the "trap" doesn't occur.
2. QTranslator inherits QObject so obviously copying it... you know...

Lykurg
23rd October 2010, 00:47
But to be honest:Yes, you are absolutely right. Call it temporary black out, partial mental disease etc. Damn, it is like it is. *shame*


Anyway. Sometimes this genius mind breaks out and searches for the possibility to express itself in the world of pictures;) After 1,5 years it happens again. This evening! While reading
The difference is in what is hidden in "//...more code". I saw an image in my mind and must paint it. (It took me more than an hour, which is indeed a strong hint of a special kind of mental disease.) And since it does not matter if this thread has 35 or 36 (!) replies here it comes:
5383

wysota
23rd October 2010, 00:56
Ha ha...a good one! Maybe you should be making a "Qt Centre comic book"? ;) "Life of a Qt developer" or something...

franco.amato
24th October 2010, 03:19
Wysota and Lykurg thank you for your patience :)