QFileDialog dynamic translation - c++

This question has unfortunately been asked before but I'm going insane here.
In my Qt Application the user is able to dynamically change the language which works perfect for all my own translations. It does not work for my calls to QFileDialog. The respective code:
void myapp::change_language(std::string& lang_str){
// my own translations works
qApp->removeTranslator(&this->app_lang);
this->app_lang.load(QString::fromStdString(lang_str));
qApp->installTranslator(&this->app_lang);
// system translations, works not for qfiledialog
qApp->removeTranslator(&this->app_lang_qt);
bool test = this->app_lang_qt.load("qt_fr.qm"); // returns true
qApp->installTranslator(&this->app_lang_qt);
}
And
void myapp::changeEvent(QEvent* event){
if(event->type() == QEvent::LanguageChange){
this->ui.retranslateUi(this);
}
QMainWindow::changeEvent(event);
}
With
QTranslator app_lang;
QTranslator app_lang_qt;
The fixed string "qt_fr.qm" is just for testing purpose because french is easily detectable.
What I want is to change the language in static calls to QFileDialog and QMessageBox but the language is only changed in QMessageBox, not in QFileDialog. For both classes I'm only calling the static members to that can't be the issue. I also tried to install this translator in the main.cpp with the same results.

By default, QFileDialog will use the native file browser rather than a custom Qt-based dialog. The native file browser is will be using the OS language, rather than the Qt language, and will not have Qt translations applied to it. You can override this behaviour using the DontUseNativeDialog option for QFileDialog.

Related

Why do I need a QTranslator for localized button texts in a QMessageBox on Windows?

I'm developing a Qt application that runs on Linux and Windows. I'm on a German locale.
When building it on Linux, I get the correct translations for the standard buttons displayed by e. g. a QMessageBox::question with QMessageBox::Yes | QMessageBox::No | QMessageBox::Cancel buttons set ("Ja", "Nein" and "Abbrechen" in my case).
If I build the code on Windows however, I only get the C locale (English) texts for those buttons ("Yes", "No" and "Cancel").
After some searching, I found a globally working solution by adding
#include <QTranslator>
#include <QLibraryInfo>
and
QTranslator qtTranslator;
if (qtTranslator.load(QLocale::system(), QString::fromUtf8("qt"), QString::fromUtf8("_"),
QLibraryInfo::location(QLibraryInfo::TranslationsPath))) {
app.installTranslator(&qtTranslator);
}
to my main.cpp.
Using this, I also get the translated strings on Windows. On Linux however, the qtTranslator.load call fails and thus, nothing happens to the state I had before, so I ended up putting that code inside an #ifdef Q_OS_WIN block.
This works, but seems a bit hacky to me. Plus, I don't understand why I get the translated strings on Linux by default and not on Windows.
Is the way I do it the correct solution? And if so, why do I need that additional code on Windows?
Try to replace your code on this and tested.
static QTranslator qtTr;
qtTr.load("qt_" + QLocale::system().name(), QLibraryInfo::location(QLibraryInfo::TranslationsPath));
installTranslator(&qtTr);

QT Creator Main.cpp MainWindow.cpp

I'm currently working on my project for my Master thesis in Mechatronics/Robotics. The goal of y project is to read in a .stl-File and calculate the path for an industrial robot.
Till now everything worked fine for me, but now my professor wants me to develop a GUI, because till now I was just using the command window and wrote all parameters manual. Now I'm working with Qt Creator and developed a simple GUI for my project.
In this interface I got a RadioButton for ascii files. In order my functions work I have to determine if the user is entering a ascii file or an binary file. But here's my first problem. In the command window I just check the argv[] for the string "-ascii". If the user enters this, a flag is set to false.
if(0 == strcmp(argv[i], "-ascii")) {
isBinaryFormat = false;
}
Now I just want to do the same int the GUI. If the RadioButton is checked flag is set to false. So I wrote the following in the main.cpp file
if(ui->radioButton->isChecked()) {
isBinaryFormat = false;
}
But ui is unknown in the main function. After searching for help on google I just found tutorials writing the code in the mainwindow.cpp file. But how can I send the information form the mainwindow file to my main function in the main.cpp file.
A second question would be, if I use the QFileDialog::getOpenFilename method, how can I hand the file name to my other functions. The idea is, the user selects a file anywhere on his PC, and the program opens the file and processes it. But here I got the same problem. I can brows for a file, but how can I transfer the information from the mainwindow.cpp to my main.cpp.
I'm thankful for any help I get. Very grateful a lonely coder
First of all you don't write UI Code in the main.cpp.
You write it where the MainWindow Class is so in MainWindow.cpp and MainWindow.h.
Then your ui-> will work because it then has access to that namespace.
I don't see why you would have functions in Main.cpp?
Without seeing more code you're not likely to get an answer to that.
If you want to use external functions in your classes either declare the methods in the class directly or create a new file like global_function.h and .cpp which you can include in your class. ( don't forget the header guards )
Also shouldn't that code look like this:
if(!ui->radioButton->isChecked())
{
isBinaryFormat = false;
}
because of:
If the RadioButton is checked flag is set to false.
QString fileName = QFileDialog::getOpenFileName(this, tr("Open File"),
"/home",
tr("Images (*.png *.xpm *.jpg)"));
getOpenFileName( ) will return a string containing the path and filename of the selected file which you can pass to your functions then.
Please read some more about how to use Qt.
It's not just about the files, there's a class, too. Learn about them. Solution is to add a getter to your MainWindow class that will return whether the radioButton is checked:
class MainWindow : public QMainWindow
{
public:
// optionally, move implementation in the source file
bool isBinaryFormatChecked() const
{
return ui->radioButton->isChecked();
}
// other stuff ...
};
And then you can access it in your main like window.isBinaryFormatChecked() orwindow->isBinaryFormatChecked() depending on whether you have a pointer or not. Another way would be to make ui in your MainWindow public, so you could access the whole user interface, but that breaks proper encapsulation.
I think you need to go through a few of the (excellent in my opinion) examples supplied with Qt before attempting to integrate your already working console code.
Essentially you really don't want to do that check in the main.cpp, but if you must you could have it in a public function of the mainwindow and call that from your main.cpp file. But then that doesn't really make sense as you don't want to check whether the appropriate radio button is set until the user inputs something. You're going to have to read up on event based programming.

QWebEngine: print a page?

The migration from QWebKit to QWebEngine seems to be much more complicated than Qt guys claimed. With QWebKit I could print a webpage easily via
QWebView->print(&printer);
With QWebEngine class QWebEngine view does not provide a method print(). Their browser example uses a class named QWebEngineFrame which offers a method print() - but the whole QWebEngineFrame is not defined anywhere!
So my question: how do I print a page using QWebEngine?
I think the correct way to use QWebEngineView::render method because QWebEngineView is a QWidget. It accepts paint device as a first argument and you may pass QPrinter there for printing.
Update: If you can use the latest version of Qt, in Qt 5.8 a new function for printing page was added:
void QWebEnginePage::print(QPrinter *printer, FunctorOrLambda resultCallback);
Actually it first prints to temp PDF with QPrinter settings.
Here is the link to Qt docs.
You can read about this in our blog also.
I would offer following code (for a while):
QTextEdit *textEdit = new QTextEdit;
ui.myWebView->page()->toHtml([textEdit](const QString &result){ textEdit->setHtml(result); });
textEdit->print(somerinter);
textEdit->deleteLater();
Qt 5.7 includes print support in to pdf files for QWebEngine.
Use printToPdf function to export the current page in a pdf file. Example:
const QString fileName = QFileDialog::getSaveFileName(0,
tr("Save pdf"),
".",
tr("PDF Files (*.pdf)"));
if (fileName.isEmpty()) {
return;
}
ui->webView->page()->printToPdf(fileName);
QWebView->page()->print(&printer, [=](bool){});

Embed QWidget into Other Application

Recently I stumbled upon QMacNativeWidget (src and header) which basically makes it possible to use Qt widgets in native Cocoa applications without having to use QApplication.
Now I was wondering whether it is possible to adapt this technique to embed Qt widgets into other GUI kits, say I want to place QWidget Foo inside CoolUIKit Bar. At a glance this seems pretty straightforward, e.g. the main functionality is to adapt getEmbeddableView correctly:
NSView *getEmbeddableView(QWindow *qtWindow)
{
// Make sure the platform window is created
qtWindow->create();
// Inform the window that it's a subwindow of a non-Qt window. This must be
// done after create() because we need to have a QPlatformWindow instance.
// The corresponding NSWindow will not be shown and can be deleted later.
extern QPlatformNativeInterface::NativeResourceForIntegrationFunction resolvePlatformFunction(const QByteArray &functionName);
typedef void (*SetEmbeddedInForeignViewFunction)(QPlatformWindow *window, bool embedded);
reinterpret_cast<SetEmbeddedInForeignViewFunction>(resolvePlatformFunction("setEmbeddedInForeignView"))(qtWindow->handle(), true);
// Get the Qt content NSView for the QWindow from the Qt platform plugin
QPlatformNativeInterface *platformNativeInterface = QGuiApplication::platformNativeInterface();
NSView *qtView = (NSView *)platformNativeInterface->nativeResourceForWindow("nsview", qtWindow);
return qtView; // qtView is ready for use.
}
But: how do I get from NSView to CoolUIKit? Or is there a completely alternative approach?

Weird behavior when switching view between C++ and QML

I'm currently working on a project using Qt 5.0.2 on an embedded linux (ARM Cortex A9).
The main UI interface is developped in QML but I need to be able to hide this view to show a QWebView directly in C++.
I coded a simple view controller in c++ who hide()/show() the QML view and the many instances of QWebView.
The hiding/showing method work fine but when i show back the QML view, it's very instable. QML object are visible (or not visible :p) when they should not and the focus are buggy too. Object are draw in the wrong position too.
I try several methods :
-Initialize the focus/visible property of the differents objects everytime I show the QML view.
-use .setSource() everytime before showing the view
-try to update() the differents object thank to rootObject() before showing the view.
Did anyone have a tips to make the QML view functionnal again after a switch to a c++ view ?
thank.
there is probably a better way but,
you could probably do something like this (I have not tested this):
note: if the slot implementation is wrong (bad math) it will result in infinite recursion.
//this code could probably be in the constructor
real widthOverHeightRatio = 2;//set this value to what you want, or what it is when user first presses shift depending on the use case.
QObject::connect(this, SIGNAL(widthChange()), this, SLOT(onWidthChanged()));
QObject::connect(this, SIGNAL(heightChanged()), this, SLOT(onHeightChanged()));
//don't forget to define these slots in the header
//implemented slots
void MyClass::onWidthChanged()
{
if(width/height!=widthOverHeightRatio){
height = width/widthOverHeightRatio;
}
}
void MyClass::onHeightChanged()
{
if(width/height!=widthOverHeightRatio){
width = height*widthOverHeightRatio;
}
}