Miscellaneous and Advanced Concepts

Miscellaneous and Advanced Concepts

11 Miscellaneous and Advanced Concepts In this chapter we will present you with some additional topics that didn't fit into the main part of the book. First we'll have a look at teaching your programs to communicate with the user in different languages. Then we will see how to establish communication channels between processes. Next it will be explained how to make your applications multithreaded to leverage the growing numbers of computing cores in modern machines. The next section of this chapter will explain how to use hardware sensors present on many devices, especially in the mobile section of the market to make your game on mobile devices a richer experience. Then we will have a look at how you can track a device with the help of GPS and how you can connect multiple devices via Bluetooth or NFC. Handling media data is also an important topic. Thus, we will try to show you the basics of using multimedia with Qt in the following sections of the chapter. Finally, we will look into debugging and testing. This will cover how to print simple debug messages as well as how GDB or CDB are integrated into Qt Creator and made usable through this IDE. In the end Qt Test will be introduced to show you how you can realize unit tests with Qt. By the end of this chapter you will have a broader perspective of technologies available as a part of Qt. You will be able to use a wider range of tools and technologies in your games making them better and richer in features. Utility frameworks In this section we will show you a couple of frameworks or other solutions you can use to make your games more versatile. This includes showing messages to the users in their own language, multithreading and multiprocess communication, as well as a framework for using multimedia such as video and sound in your games. [ 1 ] Miscellaneous and Advanced Concepts Internationalization Qt is an application programming framework used all over the world. Just as it can handle many text encodings, it also supports many languages. With Qt you can easily teach your application to communicate to the user using his native language. The font engine used by Qt can render fonts that use a variety of different writing systems and all standard text widgets can accept input in any language, and Qt's text drawing routines try to take into consideration text rendering rules present in particular languages. Still, you as the application programmer have to perform some additional work to make sure your application is correctly internationalized and localized. Since QString is based on Unicode, it can hold and express text in virtually any language in the world. Thus it is important that you use QString for every user-visible text in your program. However, other text data that the user can't see (for example, object names, debug messages, text format definitions) can still be held using the traditional const char * and char types. Marking text for translation Each user-visible text should be translated into the language that the user expects. Text substitution is performed using the QCoreApplication::translate() method. Usually, you don't need to call it yourself. The regular approach is to surround all your bare string literals in calls to QObject::tr() that will then call translate() for you. Thus everywhere where you'd normally use QStringLiteral, you can instead use tr(): QLabel *label = new QLabel; label->setText(tr("This is my internationalized label text")); Apart from translating the text within, this call serves another purpose—it marks the text that is to be extracted by a special harvesting tool that will assemble message catalogs for your project. It is important that tr() marks only the string literals and not variables. The following code will not work: const char* labelTexts[] = { "Name", "Age", "Address" }; for(int i=0; i<3; ++i) { QLabel *label = new QLabel; label->setText(tr(txt[i])); doSomethingWith(label, i); } [ 2 ] Chapter 11 This is because txt[i] is a variable that cannot be translated. You would have to wrap items in labelTexts in calls to tr() but C++ forbids that. To overcome this problem Qt offers QT_TR_NOOP and QT_TRANSLATE_NOOP macros that mark texts for translation without translating anything. Then the effective code becomes as shown: const char* labelTexts[] = { QT_TR_NOOP("Name"), QT_TR_NOOP("Age"), QT_TR_NOOP("Address") }; for(int i=0; i<3; ++i) { QLabel *label = new QLabel; label->setText(tr(txt[i])); doSomethingWith(label, i); } The difference betweenQT_TR_NOOP and QT_TRANSLATE_NOOP is that when using the latter you can provide a so called context of the translation, which is by default the class name where the translation occurs. This context allows identifying similar messages that were defined in different places. There is also QT_TRANSLATE_NOOP3, which has an additional argument where the author can provide a comment to the message being translated— for example, when translating a copy, the author can leave some information for the translator whether the word means a verb (to copy something) or a noun (a copy of something). Producing translations Once the source code is complete, the next step is to extract all messages and produce message catalogs. This is done by declaring translations in the project file. To declare translations, you need to fill the TRANSLATIONS variable with paths to catalogs that need to be maintained by the project: TRANSLATIONS += translations/myapp_en.ts \ translations/myapp_fr.ts \ translations/myapp_pl.ts The convention is to name the files with your application name followed by an underscore and international symbol of the language (for example, en for English, fr for French, pl for Polish, and so on) and a .ts file extension. If a language is used in more than one country, you can follow the language name with a country symbol forming the full language variant (for example, en_us or en_au). [ 3 ] Miscellaneous and Advanced Concepts When the list is ready, you should run the lupdate tool on the project file. You can either do this manually or from Qt Creator by opening the Tools menu, going to External and then Linguist and finally choosing Update translations (lupdate). This will produce files declared in the TRANSLATIONS variable that contain all the messages from your project. Whenever you change your source code you can run lupdate again to update message catalogs without overwriting already present translations. The next step is to give those files to people who can act as translators for the application. Qt contains a dedicated tool called Linguist that can help with the task. You can see it in the following screenshot: The Linguist tool is very easy to use so we will not discuss it in detail here. Two important things to note are to set language details for the catalog as you start working with a file by opening the Edit menu and choosing Translation File Settings. The other important thing to remember is to mark your translations as "done" if you want them to be used. This is done with the Ctrl + Return keyboard shortcut (or by choosing Done and Next from Translation menu) so that a green tick appears next to the source text in the list of strings. [ 4 ] Chapter 11 When translations are ready, you can call the lrelease tool (either from Qt Creator or from Qt Linguist) to produce compressed message catalogs (with .qm file extension). Applying translation The final step is to enable translation process for your application. This is done by creating an instance of QTranslator, loading a message catalog into it, and passing the translator object pointer to the QCoreApplication::installTranslator() method. From now on all calls to QObject::tr() will result in substituting original texts with their translated versions. If translation for any message cannot be found, the translator uses the original text as a fallback. Time for action – translating a list of strings application Create a new Qt Widgets Application in Creator. Choose to create a MainWindow form and widget class for it. After the skeleton code is created, openmainwindow.ui and drag a Combo Box widget to the form. Apply a horizontal layout so that the combo box snaps into place. Click on the combo box, find its objectName property in the property editor and note it down—it should be called comboBox. Save the form and open the mainwindow.cpp file. Position the cursor just below the include lines and add a code that creates a static array of string literals (make sure to wrap all literals into the QT_TRANSLATE_NOOP macros): static const char *countries[] = { QT_TRANSLATE_NOOP("MainWindow", "Canada"), QT_TRANSLATE_NOOP("MainWindow", "Germany"), QT_TRANSLATE_NOOP("MainWindow", "Norway"), QT_TRANSLATE_NOOP("MainWindow", "Poland"), QT_TRANSLATE_NOOP("MainWindow", "United Kingdom") }; Now go to the class constructor and add the following code to it: for(int i=0; i<5; ++i) { ui->comboBox->addItem(tr(countries[i])); } setWindowTitle(tr("Country Selection")); Essentially we add all country names to the combo box at the same time trying to translate them by wrapping them into calls to tr(). Finally, we set the window title toCountry Selection. [ 5 ] Miscellaneous and Advanced Concepts Now open main.cpp and modify the main() function to install a translator on the application based on the user's system locale: int main(int argc, char **argv) { QApplication app(argc, argv); QTranslator translator; translator.load(QLocale::system(), "countryselection", "_"); app.installTranslator(&translator); MainWindow w; w.show(); return app.exec(); } Next, open the project file (the one having a .pro suffix) and add an entry to it that defines translation catalogs: TRANSLATIONS = countryselection_en.ts countryselection_pl.ts You can also add a translation file for your native language if it is other than English or Polish which is my native language.

View Full Text

Details

  • File Type
    pdf
  • Upload Time
    -
  • Content Languages
    English
  • Upload User
    Anonymous/Not logged-in
  • File Pages
    66 Page
  • File Size
    -

Download

Channel Download Status
Express Download Enable

Copyright

We respect the copyrights and intellectual property rights of all users. All uploaded documents are either original works of the uploader or authorized works of the rightful owners.

  • Not to be reproduced or distributed without explicit permission.
  • Not used for commercial purposes outside of approved use cases.
  • Not used to infringe on the rights of the original creators.
  • If you believe any content infringes your copyright, please contact us immediately.

Support

For help with questions, suggestions, or problems, please contact us