How to switch input language in Qt application? - qt

I'm writing a simple Qt application for Windows platform. I need to set input language for QPlainTextEdit for it to be non-English by default. How can I do that?
All I could find so far is non-working example:
QApplication Application(argc, argv);
QLocale::setDefault(QLocale::German);
QLocale l;
qDebug() << l.language();
Application.inputMethod()->locale().setDefault(QLocale::German);
qDebug() << Application.inputMethod()->locale().language();

Related

Why does my Qt app ignore the setting of applicationDisplayName?

I am running a small app on KDE Plasma 5 created with Qt and the KDE framework. Almost everything works like a charm, just one part doesn't work. I just cannot set the application display name. I have the following code:
int main(int argc, char **argv) {
QApplication application(argc, argv);
KLocalizedString::setApplicationDomain("blender-render-control");
KCrash::initialize();
KAboutData aboutData(QStringLiteral("blender-render-control-center"),
i18n("Blender Render Control Center"),
QStringLiteral("1.0"),
i18n("A simple application to control the blender render control server"),
KAboutLicense::Custom,
i18n("Copyright 2019, Knerd "));
aboutData.addAuthor(i18n("Knerd"), i18n("Author"), QStringLiteral("knerd#knerd.knerd"));
aboutData.setOrganizationDomain("knerd.knerd");
aboutData.setDesktopFileName(QStringLiteral("knerd.knerd.blender-render-control"));
KAboutData::setApplicationData(aboutData);
QApplication::setWindowIcon(QIcon::fromTheme(QStringLiteral("knerd.knerd.blender-render-control")));
application.setApplicationDisplayName(i18n("Blender Render Control Center"));
application.setApplicationName(i18n("Blender Render Control Center"));
QCommandLineParser parser;
aboutData.setupCommandLine(&parser);
parser.process(application);
aboutData.processCommandLine(&parser);
auto *window = new MainWindow();
window->show();
return QApplication::exec();
}
From reading the docs and checking some examples, this should set the application title in my KDE environment. But it doesn't, the application name is the name of the executable.
Is this a bug in KDE or am I doing something wrong?
The docs are a bit confusing on what the applicationName and displayApplicationName are actually used for, there has been some bug reports about it, and behavior has changed between versions if I remember correcly.
If you want a window-title, I think you can do.
window->setWindowTitle( QCoreApplication::applicationName() );

Svg to pdf converter for Qt project

I have multiple svg files and I wish to convert them in the PDF format. The problem is that I need to work with multiple text fonts and a simple QSvgRenderer is not enough.
For example:
My problem is that I need to integrate a library in my project that does not use external dependencies (just a library that can be used as a standalone entity).
The only library that can partially suit my needs is librsvg but I have no experience and I can not find a method to integrate it in a Qt project.
Can someone give me a few tips or can point me in the right direction?
EDIT
With something basic there is not a single font that made it to the right using QSvgRenderer:
QSvgRenderer renderer;
renderer.load((QString)"E:/TEXT4.svg");
QPrinter printer;
printer.setOutputFormat(QPrinter::PdfFormat);
printer.setOutputFileName("E:/TEXT4.pdf");
QPainter painter(&printer);
renderer.render(&painter);
painter.end();
Maybe a bit late, but had the same problem and found a solution using Qt only.
The problem in your case is you need to install the fonts manually and need a QApplication.
E.g.:
int main(int argc, char** argv)
{
// A QApplication instance is necessary if fonts are used in the SVG
QApplication app(argc, argv);
int id = QFontDatabase::addApplicationFont(":/DejaVuSans.ttf");
if (id != -1)
{
QStringList font_families = QFontDatabase::applicationFontFamilies(id);
// This prints: DejaVu Sans
for (const auto& item : font_families)
{
std::cout << item.toStdString() << std::endl;
}
}
// Load your SVG
QSvgRenderer renderer(QString("myimage.svg"));
QPdfWriter pdfWriter(QString("mydoc.pdf"));
pdfWriter.setPageSize(QPageSize(QPageSize::A4));
QPainter painter(&pdfWriter);
renderer.render(&painter);
}
Also tested with multiple different font families and it worked.
Note: As far as I know, you cannot change the font name in Qt, so in the SVG font-family must match exactly the added font name. In this example, font-family:DejaVu Sans.

Is Qt forcing the system locale?

The following example seems to show a bug in Qt. Or am i mistaken ?
std::cout << atof("0.456") << std::endl; // OK prints 0.456
QApplication app (argc, argv);
//QLocale::setDefault(QLocale::C); // No effect at all.
std::cout << atof("0.456") << std::endl; // do not work on on fr_FR.UTF-8, print 0.
When using a non standard locale, in my example fr_FR.UTF-8, creating the QApplication seems to change the system locale, as it is used by atof to do the conversion.
To me it looks like the creation of the QApplication will pull the system locale and call a setenv with it.
From Qt documentation
Locale Settings
On Unix/Linux Qt is configured to use the system locale settings by default.
This can cause a conflict when using POSIX functions, for instance,
when converting between data types such as floats and strings, since the notation may differ between locales.
To get around this problem, call the POSIX function setlocale(LC_NUMERIC,"C")
right after initializing QApplication or QCoreApplication to reset the locale that is used for number formatting to "C"-locale.
To me it looks like the creation of the QApplication will pull the system locale and call a setenv with it.
No, it will call setlocale:
void QCoreApplicationPrivate::initLocale()
{
if (qt_locale_initialized)
return;
qt_locale_initialized = true;
#if defined(Q_OS_UNIX) && !defined(QT_BOOTSTRAPPED)
setlocale(LC_ALL, "");
#endif
}
Which in turn fetches the locale from the environment variables, as the empty string stands for the user-preferred locale. Otherwise you'd be using the C locale.

Hourglass over Qt Creator breakpoint, program not breaking

I have created a very simple Qt Creator console application, with defaults for everything except for the main.cpp file, which I have edited as follows:
#include <QCoreApplication>
#include <iostream>
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
std::cout << "hello" << std::endl;
std::cout << "world" << std::endl;
return a.exec();
}
I have also added two breakpoints; one for each of the std::cout lines, by left-clicking on the margin to the left of the line number. This creates a red circle in the margin, with a small purple hourglass over the circle. When I build and run the application, the output is:
hello
world
and the program does not break at these lines in the IDE. Why not?
Have you try to click on "Start Debugging" (F5) instead of click on "Run" (Ctrl + R)?
#Trilarion: Antonio Borondo's question is justified. It appears as if the author of the original question actually hit the Run button (or pressed Ctrl-R, or ...) instead of hitting the Debug button (or F5, or ...). Getting a clarification on what he did is important to answer the original question.
As you noticed, commenting is not available to everybody, so asking in an "answer" is the only way forward.
In case anyone else still has this issue, this is most likely caused by the build not being set to Debug.
In Qt Creator 4.5.x, you can set the build type in the lower left hand corner, you will see an icon of a monitor, when you click on it, you will have a choice of Debug, Profile, or Release. When you set the build to Debug, you will no longer have hourglass icons on your breakpoints, and the program will break on these lines.

Getting font metrics without GUI (console mode)

Let's say some images have to be generated by a Qt console program and that font metrics are needed by internal algorithms (they use the text width/height as input to compute the position where the drawing should occur). This program has to be runable on a Linux without any GUI (runlevel-3, basically a cluster without any display server).
Problem: QFontMetrics are only available when running a Qt application in GUI mode.
Any workaround to get string metrics without any display server ?
Ok after additional comments I think I understand your problem.
Just do it like that:
include <QApplication>
int main(int argv, char **args)
{
QApplication app(argv, args);
QApplication::processEvents(); // this should allow `QApplication` to complete its initialization
// do here whatever you need
return 0; // or some other value to report errors
}
You can also try use QGuiApplication this version doesn't require (doesn't use) widgets.
See also example in documentation how to handle none gui cases.
This code works perfectly on my Ubnutu with Qt 5.3
#include <QGuiApplication>
#include <QFontMetrics>
#include <QDebug>
int main(int argc, char *argv[])
{
QGuiApplication a(argc, argv);
QFont font("Times", 10, QFont::Bold);
qDebug() << font;
QFontMetrics metrics(font);
qDebug() << metrics.boundingRect("test");
return 0;
}
It also works with Qt 4.8 when QApplication is used.
Project file was quite simple
QT += core
TARGET = MetricsNoGui
TEMPLATE = app
SOURCES += main.cpp
Qt 4.8 has such QApplication constructor, whose 3rd parameter can help to solve the issue. Simple provide false as 3rd argument and enjoy using QFontMetrics in Qt console application. There will be no crashes if one starts app on systems without X server.
I didn't find a way to use QFont or QPrinter with QCoreApplication :( However, if you are able to install Xvfb, then your QApplication will be runnable also on a server without any display. I'm using this setup on a headless Raspberry Pi Zero.
Xvfb :1 -screen 0 1024x768x16 &
export DISPLAY=:1.0
./YourQApplication
This isn't the most elegant solution, but after hours of desperate searching, it's the only one I found.

Resources