I try to use translation in QML. I opened a new project QtQuick project, I chose QtQuick Componenets for Symbian as a QtQuick Application Type. Qt Creator created a application source tree with all standard files (main.cpp, main.qml, mainpage.qml...)
MainPage.qml is very simple:
import QtQuick 1.1
import com.nokia.symbian 1.1
Page {
id: mainPage
Text {
anchors.centerIn: parent
text: qsTr('Hello world!')
color: platformStyle.colorNormalLight
font.pixelSize: 20
}
}
My main.cpp file looks after implementation of QTranslator like this:
#include "qmlapplicationviewer.h"
#include <QTranslator>
#include <QPushButton>
#include <QDebug>
Q_DECL_EXPORT int main(int argc, char *argv[])
{
QScopedPointer<QApplication> app(createApplication(argc, argv));
QTranslator* translator = new QTranslator;
qDebug()<<"Translating: "<<translator->load(QString("qml/International/inter_en"));
app->installTranslator(translator);
//QPushButton hello(QPushButton::tr("Hello world!"));
// hello.resize(100, 30);
// hello.show();
QScopedPointer<QmlApplicationViewer> viewer(QmlApplicationViewer::create());
viewer->setMainQmlFile(QLatin1String("qml/International/main.qml"));
viewer->showExpanded();
return app->exec();
}
Then I run lupdate mainpage.qml -ts inter_en.ts , I have used linguist to translate the POSIX expression "Hello world!" to something else just test that it is translating. Then I created inter_en.qm file with linguist.
But when I run the application on simulator I dont get "Hello world!" translated, although the translator is loaded successfully (I get "Translating: true" in qDebug).
Translator is working correctly I am sure, because when I deremark part of the code with QPushButton , (again I repeat the lupdate and linguist things for this purpose) , then the "Hello world!" expression in QPushButton is translated correctly.
It is only the QmlApplicationViewer and QML file that is not performing translation correctly.
Any quesses?????
Thanks
UPDATE
I found out the following: MainPage.qml is imported as reusable component into main.qml. If I use qsTr() in main.qml then the text is translated correctly in main.qml. However text in MainPage.qml is not tranlated correcty. I guess due to importing it as reusable component. Any comments? Experiences?
UPDATE2 - SOLUTION
Translation files need to be created case sensitively:
lupdate mainpage.qml -ts myapp_sk.ts is wrong
lupdate MainPage.qml -ts myapp_sk.ts is correct
When the issue is not the translation per se, but changing language during runtime this may help you.
If you load a new QTranslator with app->installTranslator(translator);
it (QApplication) will fire a change event. In your Qt class you have to catch it with
/*!
on the fly translation
*/
void MyQmlView::changeEvent(QEvent *event)
{
if (event->type() == QEvent::LanguageChange)
{
// triggers qml function/slots
emit retranslate();
}
else
{
QWidget::changeEvent(event);
}
}
Somewher after loading your "main.qml":
m_pQmlView->rootContext()->setContextProperty( "_view", this );
QML side:
Component.onCompleted: {
/********************** Connections ***************************/
// connect Qt signal MyView::retranslate() with QML function (slot) retranslate
_view.retranslate.connect(retranslate)
}
// slot!
function retranslate () {
lblHelloWord.text = qsTr("Hello Word")
}
This works very good for MS Windows Platform.
I also use QML files as reusable components and I have no problem with translations at all. So I guess the following can help you as well.
I also guess you don't want to call lupdate manually for every file. So you should use the following lines in .pro file to make it look for all translatable phrases in QML and JS files automatically (correct your paths)...
lupdate_hack{
SOURCES += qml/*.qml \
qml/*.js
}
TRANSLATIONS = \
langs/WakeOnLAN_cs.ts \
langs/WakeOnLAN_pl.ts \
langs/WakeOnLAN_es.ts \
langs/WakeOnLAN_fr.ts \
langs/WakeOnLAN_it.ts \
langs/WakeOnLAN_hu.ts \
langs/WakeOnLAN_fa.ts \
langs/WakeOnLAN_de.ts \
langs/WakeOnLAN_pt.ts
CODECFORTR = UTF-8
It doesn't come from my head, so here is the source (there is also a note about dynamic translation): https://forum.qt.io/topic/30076/is-there-a-way-to-use-linguist-in-global-context
Related
I am using the Stacked Widget in Qt Creator v4.14.2. Right now all of the items for each page reside in the mainwindow.ui file. I do not have a problem switching between pages.
I am wanting to put the items for each Stacked Widget page in a separate ui file for clarity and file size reasons. I understand that there is not a technically reason for this need. I have developed UIs using MVVM and would like to replicate that methodology in Qt (using Qt Creator) if at all possible.
For this project I am working on, I would prefer not do page and/or Widget creation in the C++ code.
You can load as many UI files as you need using QUiLoader. Assuming the files are named page-1.ui, ... page-10.ui you could have something like (untested)...
#include <QStackedWidget>
#include <QUiLoader>
#include <QWidget>
.
.
.
QStackedWidget stack;
QUiLoader loader;
for (int page_no = 1; page_no <= 10; ++page_no) {
QFile f(QString("page-%1.ui").arg(page_no));
if (f.open(QFile::ReadOnly)) {
auto *w = loader.load(&f);
stack.addWidget(w);
} else {
qWarning() << "failed to load UI file.";
}
}
I'm trying to build a super simple dummy web-view with Qt and WebKit to view pages, so that I can better understand the WebKit2 split process model.
Existing examples/questions (like Example code for a simple web page browser using WebKit QT in C++) seem to use the "old" style WebKit, in which rendering and displaying are done in one process. What is the equivalent of that example but done for WebKit2?
Is it so difficult with WebKit2 that there aren't any basic examples out there?
Qt's WebKit2 is available only for QML.
With Qt 5 and Webkit2 the APIs for QtWebKit and Web View are changing significantly. This is because with WebKit2, WebKit and the application run in different processes. The old QWebView widget will only be supported on Qt for desktops and won't use the new WebKit2. Mobile phone platforms typically won't have the QWidgets module installed in Qt 5.
Examples which uses QtWebKit QML API that utilizes the WebKit2 split-process architecture could be found in Qt WebKit documentation There is Flickr View and YouTube View examples
Qt also has WebView module with examples like Minibrowser
And WebEngine module. Examples can be found here
And here is a simplest WebKit2 example which just shows google webpage
Use Qt 5.5.1 to run this example.
Add following to your .pro file: QT += quick qml webkit
main.cpp
#include <QGuiApplication>
#include <QQmlApplicationEngine>
int main(int argc, char *argv[])
{
QGuiApplication app(argc, argv);
QQmlApplicationEngine engine;
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
if (engine.rootObjects().isEmpty())return -1;
return app.exec();
}
main.qml
import QtQuick 2.0
import QtQuick.Window 2.0
import QtWebKit 3.0
Window {
visible: true
width: 967
height: 480
WebView {
id: webView
anchors.fill: parent
opacity: 0
url: "https://google.com"
Behavior on opacity
{
NumberAnimation { duration: 200 }
}
onLoadingChanged:
{
switch (loadRequest.status)
{
case WebView.LoadSucceededStatus:
opacity = 1
break
default:
opacity = 0
break
}
}
onNavigationRequested:
{
request.action = WebView.AcceptRequest
}
}
}
I am trying to learn a bit of qt and qml and I want to make a small application which will monitor a local file for changes and change a Text component when changes happen. I based my code on this answer, but even though I am not getting any warning/error during compilation and running, connecting the fileChanged signal of the QFileSystemWatcher to the qml connections elements, does not work, i.e., the text does not change when watchedFile.txt is modified. How can I check whether the signal is received in the qml code?
Here is my code:
C++:
int main(int argc, char *argv[]) {
QGuiApplication app(argc, argv);
QFileSystemWatcher watcher;
watcher.addPath(QStringLiteral("qrc:/watchedFile.txt"));
QQmlApplicationEngine* engine = new QQmlApplicationEngine;
engine->rootContext()->setContextProperty("cppWatcher", &watcher);
engine->load(QUrl(QStringLiteral("qrc:/main.qml")));
return app.exec();
}
qml:
import QtQuick 2.7
import QtQuick.Controls 2.0
ApplicationWindow {
visible: true
width: 640
height: 480
Text {
id: text
text:"TEXT"
}
Connections {
target: cppWatcher
onFileChanged: {
text.text = "CHANGED"
}
}
}
You should try a file that is on your file system. Files in qrc resources are embedded into the executable, they do not change. Not sure what exactly you expect to happen. Other than this, that is the declarative way you do connections to a CPP object.
As #dtech already noticed,
watcher.addPath(QStringLiteral("qrc:/watchedFile.txt"));
is returning false, because qrc:/ is not recognized by watcher as correct path. And, actually, this path doesn't exist in file system at all, because it's internal resource file embedded in executable.
If you will put the path to the file on the disk, your code works just fine.
Also you definitely should check return result here and do not allow proceed futher, if it returns false.
Something like following will work better here:
if (!watcher.addPath(QStringLiteral("C:/your_path/watchedFile.txt")))
return 1;
The signal fileChanged is emitted when the file path changes, and not its content.
https://doc.qt.io/qt-5/qfilesystemwatcher.html#fileChanged
There is a simple code for translating. It runs in Ubuntu 14.04.
#include <QtGui>
#include <QApplication>
#include <QLabel>
#include <QTextCodec>
int main (int argc,char *argv[])
{
QApplication app(argc,argv);
QTranslator qtr;
qtr.load("hello.qm");
app.installTranslator(&qtr);
//QTextCodec::setCodecForTr(QTextCodec::codecForName("UTF-8"));
QLabel *label=new QLabel(QObject::tr("hello"));
label->show();
retrun app.exec();
}
I had followed the below steps to translate hello to the chinese 你好 by Qt linguist:
add TRANSLATIONS +=hell0.ts to hello.pro and lupdate.
open the Qt linguist and find that the interface is
It is not like the normal Qt linguist interface. This is my first problem. How can i fix it?
Then i print 你好 to translate 'hello', but nothing is displayed in the blank.
I still push the 'done' button.
I use gedit to open the hello.ts and see that it has been tranlated to 你好.
The picture is
(3) I use 'lrelease' command and get the hello.qm
Last, i run the code as aboved. But the result is just to print 'hello' out.
It doesn't translate 'hello' to 你好. This is my second problem.
I also had used other methods like QtTextCodec::setCodecForTr instead of Qt linguist,but it still doesn't work.
Try to call retranslateUI(this) so the Translation will be updated
Noob: How to display an image
I am very new to this, just starting actually. I need to figure out how to display an image on screen.
First I tried:
Source code:
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QGraphicsScene scene;
QGraphicsView view(&scene);
QPixmap qp = QPixmap("../images/tank2.bmp");
if(qp.isNull())
{
printf("Yes its null\n");
}
else
{
QGraphicsPixmapItem item(QPixmap("../images/tank2.bmp"));
scene.addItem(&item);
}
view.show();
return a.exec();
}
from:
Qt jpg image display
it compiles and runs but doesn't show an image. returns 0, etc.
Then I just sorta messed around from there. I'm also curious about something: In Qt editor they show a file structure that doesn't exist on the disk. They have files "Headers", "Sources", and Resources whereas on the systems its just a folder "projectname" with all the files in one folder. Is this just for visual clarity?
The version of QtCreator I'm using is 2.4.1 running Qt 4.7.4 64 bit.
My eventual goal is to make a widget where a picture is a clickable icon where you select that pic and can place it on a larger screen like a tile.
Another Question: Why does Qt have things like "QString" and "QChar"? Is there something wrong with the normal c++ libraries?
If you just want to display a simple image then make a Qlabel the central widget and call setPixmap() passing it your image path
"Another Question: Why does Qt have things like "QString" and "QChar"?
Is there something wrong with the normal c++ libraries?"
Yes there is lots wrong with the normal libraries - at least for std::string.
When Qt was started there wasn't very good cross platform STL support and the standard libraries were very bad at Unicode and support for translations. QString doesthis very well - although I think a combination of modern STL and boost can probably do everything QString can do.
Almost all of the Qt types are automatically reference counted so you can pretty much ignore memory management for them AND pass them around freely. There are also some tricks Qt can do because the extra MOC compile pass means it has Java-like introspection that standard C++ doesn't.
But in general you are free to use standard C++ types (Qt: Qt classes vs. standard C++)
Tested like this, it works. Don't forget to create qrc file.
#include <QtGui/QApplication>
#include <QGraphicsScene>
#include <QGraphicsView>
#include <QGraphicsPixmapItem>
#include "mainwindow.h"
#include <stdio.h>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QGraphicsScene scene;
QGraphicsView view(&scene);
QPixmap qp = QPixmap(":/images/123.bmp");
if(qp.isNull())
{
printf("Yes its null\n");
}
else
{
printf("HAHA");
QGraphicsPixmapItem *item = new QGraphicsPixmapItem(QPixmap(":/images/123.bmp"));
scene.addItem(item);
}
view.show();
return a.exec();
}
Here are qrc file:
<RCC>
<qresource prefix="/">
<file>images/123.bmp</file>
</qresource>
</RCC>
And .pro file
QT += core gui
TARGET = testimage
TEMPLATE = app
SOURCES += main.cpp
RESOURCES += 123.qrc
I think your problem is here:
{
QGraphicsPixmapItem item(QPixmap("../images/tank2.bmp"));
scene.addItem(&item);
}
item goes out of scope before you'll actually use it.
I'm also pretty sure you meant that to use the QPixmap that you loaded earlier at the top-level scope.
Generally speaking, you want to limit your questions on SO to a single question... but to address your last question: QChar and QString allow the Qt libs to make several assumptions about strings. The most obvious of which is that QStrings have a standardized encoding.