vc++ + QT translation of UI is not working - c++

I have a project with QT in vc++ and I need to locate the string in the UI to different languages. I created a UI through the QTdesigner in the visual studio add in of visual studio 2012 and also I have installed the QT plugin to use the Qt features as well.
I have created a .pro file and added:
SOURCES += main.cpp
TRANSLATIONS += languagefileqt_es.ts
After I generate a linguist file SOURCES emminensmultiportqt_es.ts and it detected correctly all the strings in my IU. After that, I generate the .qm file using the release function of Qtlinguist.
My resources file is:
<RCC>
<qresource prefix="MyAppQT">
<file>languagefileqt_es.qm</file>
</qresource>
</RCC>
Then I have added this to my main.cpp:
QTranslator translator;
bool loaded = translator.load("languagefileqt_es");
qDebug() << "loaded " << loaded;
a.installTranslator(&translator);
And loaded returns true in all the cases. My problem is that the UI is not translated when the application is executed. It is weird because it has no effect.
Any clue about what I am missing or what could I check out?
Thanks a lot

Are you sure, that "languagefileqt_es" is the correct name of your language file? I would expect "languagefileqt_es.qm" instead.
Are you sure that you are loading from the correct directory? Unless you are loading from an internal compiled-in resource (:/languagefileqt_es.qm) you should refer to an absolute path to make sure, that you load the correct thing.

I discovered what was the problem. thanks #Jens for try to help.
I think I commit a mistake of not knowing how the translating mechanism was working. In my main.cpp I had:
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindowQT w;
QTranslator translator;
bool loaded = translator.load("languagefileqt_es");
qDebug() << "loaded " << loaded;
a.installTranslator(&translator);
w.show();
return a.exec();
}
But I realized that if I execute
qDebug() << QApplication::translate("MainWindowQTClass", "...BOARDING", 0);
after the loading process it will return the string translated correctly. So I change the definition of my UI after the internationalization and it worked. Apparently, translation is done in a function called retranslateUi() which is called in the constructor.
The correct main.cpp should be:
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QTranslator translator;
bool loaded = translator.load("languagefileqt_es");
qDebug() << "loaded " << loaded;
a.installTranslator(&translator);
MainWindowQT w;
w.show();
return a.exec();
}

Related

how to translate key shortcut

I cannot force QKeySequence::toString() to return translated shortcut representation despite the fact that it documentation suggests it should work. The docs say: "The strings, "Ctrl", "Shift", etc. are translated using QObject::tr() in the "QShortcut" context." but I am not completely sure what it means by shortcut context. I am probably doing something wrong...
Here is my example. To make it work, I need to copy qtbase_es.qm from Qt installation directory to my project build directory. When the translation is correctly loaded, the action in the menu correctly shows "Action Control+Intro" which is Spanish translation of the shortcut for "Action Ctrl+Enter". But the tooltip on the main window is still "Action (Ctrl+Enter)". I would expect it to be "Action (Control+Intro)", like in the menu. What am I doing wrong?
#include <QAction>
#include <QApplication>
#include <QDebug>
#include <QMainWindow>
#include <QMenuBar>
#include <QTranslator>
int main(int argc, char *argv[])
{
QTranslator spanish;
qDebug() << spanish.load("qtbase_es.qm"); // should return true if correctly loaded
QApplication a(argc, argv);
QApplication::installTranslator(&spanish);
QMainWindow w;
auto menu = new QMenu("Menu");
auto action = menu->addAction("Action");
action->setShortcutContext(Qt::ApplicationShortcut);
action->setShortcut(Qt::CTRL | Qt::Key_Enter);
w.menuBar()->addMenu(menu);
w.show();
QApplication::processEvents(); // I also tried this line but it is useless...
w.setToolTip(QString("%1 (%2)").arg(action->text(), action->shortcut().toString()));
qDebug() << action->shortcut().toString(); // WRONG: returns Ctrl+Enter but I expect Control+Intro
return a.exec();
}
The QShortcut::toString has a SequenceFormat parameter, defaulted to ProtableText. The documentation of the format states, that portable format is intended for e.g. writing to a file.
The native format is intended for displaying to the user, and only this format performs translations.
Try:
qDebug() << action->shortcut().toString(QKeySequence::NativeText);

Qt - Use builtin translations

I'm using Qt and want to translate the texts "natively" shown by Qt widgets. By "texts natively shown" I'm for instance referring to the ones shown in context menus for text edits (copy, paste, ...).
Here is what I've already done:
#include <QApplication>
#include <QDebug>
#include <QTranslator>
#include <QFile>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QTranslator translator;
if(translator.load("qt_fr.qm", QApplication::applicationDirPath())) {
qDebug() << a.installTranslator(&translator);
}
qDebug() << QFile::exists(QApplication::applicationDirPath() + "/qt_fr.qm"); // just to debug file existence
// MainWindow w; // not related to my question
// w.showMaximized(); // neither is this
return a.exec();
}
The qt_fr.qm file is located at path_to_qt/Qt5.6.2/5.6/mingw49_32/translations for Qt5.6.2 and MinGW users. I copy the said file to the running software directory but the translator always fails to load it. But when I use my own qm file (built from a .ts file using the Qt lupdate and lrelease tools), the qm file is properly loaded and installed.
Is there something I'm missing or doing wrong?
I think the problem may be that you haven't copied the complete message catalog. The following works for me on a Debian system, using the QM files in their standard locations:
#include <QApplication>
#include <QDebug>
#include <QLocale>
#include <QTranslator>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QTranslator translator;
const QString dir = "/usr/share/qt5/translations";
if (translator.load("qt_fr", dir)) {
qDebug() << "first load succeeded:"
<< "'Open' =>" << translator.translate("QShortcut", "Open");
}
if (translator.load(QLocale::French, "qt", "_", dir)) {
qDebug() << "second load succeeded:"
<< "'Open' =>" << translator.translate("QShortcut", "Open");
}
}
Output is
first load succeeded: 'Open' => "Ouvrir"
second load succeeded: 'Open' => "Ouvrir"
(I removed the .qm from the filename, as Qt will try that first, and I've also shown how to compose the filename from a specific locale object).
If we inspect the qt_fr.qm file using lconvert -of ts /usr/share/qt5/translations/qt_fr.qm, we can see it's just a very small file that incorporates other files by reference:
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE TS>
<TS version="2.1" language="fr_FR">
<dependencies>
<dependency catalog="qtbase_fr"/>
<dependency catalog="qtscript_fr"/>
<dependency catalog="qtquick1_fr"/>
<dependency catalog="qtmultimedia_fr"/>
<dependency catalog="qtxmlpatterns_fr"/>
</dependencies>
</TS>
I think that the most likely cause of your symptoms is that one or more of the dependency files could not be loaded. You should ensure that all of those files area available in the same location that you copied qt_fr.qm to - or, if you only need the "base" translations, just copy qtbase_fr.qm, and change your translator.load() call appropriately.

'search' was not declared in this scope

I am trying to learn C++, and I am using the Qt Framework. What I am currently trying to accomplish, is loading a custom font from the resource file. When I run this, File Found is output to the console window. When I uncomment the commented out line I get an error 'search' was not declared in this scope. In the Qt Creator I have objectName set to search. I assumed that I could then access it like how I wrote the commented out line, but I guess I can't. What am I doing wrong?
int main(int argc, char *argv[]){
QApplication a(argc, argv);
Apollo w;
w.show();
int fontID(-1);
QFile res(":/lib/fonts/SourceCodePro-ExtraLight.ttf");
if(res.open(QIODevice::ReadOnly) == true){
fontID = QFontDatabase::addApplicationFontFromData(res.readAll());
if(fontID == -1){
qDebug() << "File Not Found";
}else{
qDebug() << "File Found";
}
}
//search.setFont(QFont("Source Code Pro ExtraLight", 26));
return a.exec();
}
Your object names is "search".
The object is a part of the GUI I guess, so if you want to have acces to it you should do something like that:
ui->search->setFont(...);
Qt creator is quite smart and offer you a kind of auto complement. If it doesn't offer you a proposition for a object of the GUI most of the time that mean you do it wrong.

QPrinter runtime error

EDIT: I managed to get a compiling and non crashing version. The only thing left is to get the desired output, however this particular question (why it crashes) has been answered so I am closing the question. I will post the working code before the broken one.
Good day! I am trying to create a small example that will simply create a pdf document. Everything compiles, however when the program starts it simply crashes. I am using Qt version 5.0.0
---New working code---
int main( int argc, char **argv )
{
QApplication app( argc, argv );
QTextDocument doc;
doc.setHtml( "<p>A QTextDocument can be used to present formatted text "
"in a nice way.</p>"
"<p align=center>It can be <b>formatted</b> "
"<font size=+2>in</font> <i>different</i> ways.</p>"
"<p>The text can be really long and contain many "
"paragraphs. It is properly wrapped and such...</p>" );
QPrinter printer;
printer.setOutputFileName("C:\\Users\\SameTime\\Desktop\\Cutie\\PDFPrintMaybe");
printer.setOutputFormat(QPrinter::PdfFormat);
doc.print(&printer);
printer.newPage();
return 0;
}
Here is the project code:
#-------------------------------------------------
#
# Project created by QtCreator 2013-06-08T10:07:11
#
#-------------------------------------------------
QT += core
QT -= gui
QT += printsupport
TARGET = PDFPrintMaybe
CONFIG += console
CONFIG -= app_bundle
TEMPLATE = app
SOURCES += main.cpp
----Old code with error---
And here is the main cpp:
#include <QCoreApplication>
#include <QTextDocument>
#include <QPrinter>
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
QTextDocument doc;
doc.setHtml("<h1>Testing, testing, is this thing on?!</h1>");
QPrinter printer;
printer.setOutputFileName("C:\\Users\\SameTime\\Desktop\\Cutie\\PDFPrintMaybe");
printer.setOutputFormat(QPrinter::PdfFormat);
doc.print(&printer);
printer.newPage();
return a.exec();
}
I am a bit at a loss since it is compiling but crashing (almost) instantly when ran.
Try to create the objects on the heap otherwise they get automatically deleted when they ran out of scope, then the framework probably tries to delete them again and crashes.
QTextDocument *doc = new QTextDocument();
doc->setHtml("<h1>Testing, testing, is this thing on?!</h1>");
QPrinter* printer = new QPrinter();
printer->setOutputFileName("C:\\Users\\SameTime\\Desktop\\Cutie\\PDFPrintMaybe");
printer->setOutputFormat(QPrinter::PdfFormat);
doc->print(printer);
printer->newPage();

Newbie problem with QT C++ - Qimage dont work?

I am trying to do console application to read pixels from image:
#include <QtCore/QCoreApplication>
#include <QtGui/QImage>
#include <iostream>
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
QImage *img = new QImage("adadad.jpg");
//std::cout << "Type filename:" << std::endl;
img->isNull();
return a.exec();
}
That doesn't work I got: (IT doesn't compile, but anyway file isn't exist yet...)
File not found: tmp/obj/debug_shared/main.o:: In function `main':
What is going on? Is it impossible to use Qimage with console app?!
EDIT:
screen
It is possible to use QImage in a console application, you must make sure that QtGui is configured though. If you chose a console app, your .pro file might contain something like
CONFIG += console
QT -= gui
If that's the case, remove the QT -= gui line.
QImage("adadad.jpg");
Will probably look for a file called adadad.jpg on the current working directory for your application. Check if that file is present. Otherwise, use a fully qualified path.
img->isNull() doesn't do anything on it's own, try this instead:
if(img->isNull())
std::cout << "Image isNull!\n";
else
std::cout << "Image loaded\n";
My guess is that the local directory of the executable is not the same as the location of that image, so Qt can't find the file. Try specifying the complete path.
EDIT: Ahh... didn't realize it was a compilation problem. That looks suspiciously like a moc issue. What build system are you using? and can you confirm that the moc step is executing?
This modification of your code will compile and run as expected if there is a valid image file in the current working directory when you run the app. It will display Image loaded
#include <QtGui/QImage>
#include <iostream>
int main(int argc, char *argv[])
{
QImage *img = new QImage("adadad.jpg");
if(img->isNull())
std::cout << "Image is null";
else
std::cout << "Image loaded";
return 0;
}
You do not need to create an instance of QCoreApplication unless you have subclassed it and put your program code in that subclass.
Update:
Your program does not exit so you are probably getting that compile error because it can't replace the executable because it is still running (and locked). The file locking is more likely to be an issue under Windows.
An important note when you are loading a file using directly "adadad.jpg" in your code. Even if you put the file inside the debug/release folder, QImage will always be null if loaded this way.
I run into this problem yesterday and I fixed it by using the Qt library to get the full path: QCoreApplication::applicationDirPath().
There is two way to achieve that, first one is when you create the img object.
QImage img( QCoreApplication::applicationDirPath() + "adadad.jpg");
if( img.isNull())
{
qDebug() << "Loading Error - file: adadad.jpg.";
return false;
}
or using the load function
QImage img;
if( !img.load(QCoreApplication::applicationDirPath() + "adadad.jpg"))
{
qDebug() << "Loading Error - file: adadad.jpg.";
return false;
}