QML import QtCharts module error - qt

When I try to import the QtCharts module to my QML files y always get the same warning message:
"found not working imports: file: C:/.... module "QtCharts" is not
installed"
I'm using OpenSource QtCreator 4.0.3 with Qt 5.7.0.
I have the folder QtCharts in the path: C:\Qt\5.7\mingw53_32\qml
I've also included the folder path using the property in the .pro file:
QML2_IMPORT_PATH: C:\Qt\5.7\mingw53_32\qml
What am I missing?
Here is a simple test code:
// QtChartsTest.pro
TEMPLATE = app
QT += qml quick
QT += charts
CONFIG += c++11
SOURCES += main.cpp
RESOURCES += qml.qrc
# Additional import path used to resolve QML modules in Qt Creator's code model
QML2_IMPORT_PATH = C:\Qt\5.7\mingw53_32\qml
# Default rules for deployment.
include(deployment.pri)
// 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")));
return app.exec();
}
// Main.qml
import QtQuick 2.7
import QtQuick.Window 2.2
import QtCharts 2.1
Window {
visible: true
width: 640
height: 480
title: qsTr("Hello World")
Text {
text: qsTr("Hello World")
anchors.centerIn: parent
}
}

I was stuck on a similar issue and was frustrated by Qt's documentation on the subject, so I'll put my method of solving my own issues here for posterity.
I'm not sure of the exact cause of your issue, but I can offer you a suggestion to try and troubleshoot it.
In your main.cpp add the following line.
qDebug()<<engine.importPathList();
So your main will be
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QDebug>
int main(int argc, char *argv[])
{
QGuiApplication app(argc, argv);
QQmlApplicationEngine engine;
qDebug()<<engine.importPathList();
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
return app.exec();
}
This will include the complete list of include paths. If you do not see the include path listed there you can add it by adding the following line:
engine.addImportPath(directory);
where "directory" is a QString to the include directory.
My understanding is that the QML2_IMPORT_PATH variable only applies at run time, and not at compile time, which means that QtCreator does not see the path when it compiles. engine.addImportPath(directory); on the other hand adds the path prior to starting the qml engine, (and thus the first qml import statements)
I am not saying this is the best way to solve your issue, but it did help me solve my issue.

int main(int argc, char *argv[])
{
// Qt Charts uses Qt Graphics View Framework for drawing, therefore QApplication must be used.
QApplication app(argc, argv);
QQuickView viewer;
// The following are needed to make examples run without having to install the module
// in desktop environments.
#ifdef Q_OS_WIN
QString extraImportPath(QStringLiteral("%1/../../../../%2"));
#else
QString extraImportPath(QStringLiteral("%1/../../../%2"));
#endif
viewer.engine()->addImportPath(extraImportPath.arg(QGuiApplication::applicationDirPath(),
QString::fromLatin1("qml")));
//***** [Solve] FORCE THE MODULE TO BE IMPORTED.
QObject::connect(viewer.engine(), &QQmlEngine::quit, &viewer, &QWindow::close);
qDebug() << viewer.engine()->importPathList();
viewer.setTitle(QStringLiteral("QML Axes"));
viewer.setSource(QUrl("qrc:/qml/qmlaxes/main.qml"));
viewer.setResizeMode(QQuickView::SizeRootObjectToView);
viewer.show();
return app.exec();
}
[Output through qDebug()]
("/home/snjee/workspace_qt/maxelecPrjs/build-maxCoffeeTdsMeterApp-Desktop_Qt_5_15_2_GCC_64bit-Debug", "qrc:/qt-project.org/imports", "/opt/Qt/5.15.2/gcc_64/qml")
You can find the answer in the built-in "QML Axes" example source.

Related

how to import a QML Component resource in a QML file

I have the following directory structure:
ui/
|- resources.qrc
|- qml/
|- main_window_presenter.qml
|- MyPresenter.qml
resources.qrc contents:
<RCC>
<qresource prefix="/">
<file>qml/MyPresenter.qml</file>
<file>qml/main_window_presenter.qml</file>
</qresource>
</RCC>
MyPresenter.qml contents:
import QtQuick 2.11
FocusScope {
id: root
property Item view
property QtObject model
Component.onCompleted: {
root.view.anchors.fill = root
root.view.focus = true
}
}
main_window_presenter.qml contents:
import "."
MyPresenter {
id: root
}
main.cpp contents:
#include <QGuiApplication>
#include <QQmlApplicationEngine>
int main(int argc, char **argv)
{
QGuiApplication app(argc, argv);
QQmlApplicationEngine engine;
engine.load(":/qml/main_window_presenter.qml");
return app.exec();
}
When I run the application I get
QQmlApplicationEngine failed to load component
file::/qml/main_window_presenter.qml:1 import "." has no qmldir and no namespace
If I delete import "." at main_window_presenter.qml I get
QQmlApplicationEngine failed to load component
file::/qml/main_window_presenter.qml:3 MyPresenter is not a type
I think I shouldn't need an import statement because they are in the same directory. I am using meson build system with this relevant part in meson.build(exe_moc_headers are defined before):
qt5_module = import('qt5')
exe_processed = qt5_module.preprocess(moc_headers : exe_moc_headers, qresources : 'ui/resources.qrc')
As #eyllanesc suggested QQuickView works instead of QQmlApplicationEngine:
#include <QGuiApplication>
#include <QQuickView>
int main(int argc, char **argv)
{
QGuiApplication app(argc, argv);
QQuickView* view{new QQuickView};
view->setSource(QUrl("qrc:///qml/main_window_presenter.qml"));
view->show();
return app.exec();
}
I might have figured it myself if the error message wasn't indicating that type is not found by saying "MyPresenter is not a type". This led me to believe that its a referencing issue.

Load image in QML WebEngineView using QQuickImageProvider

I'm injecting HTML content into a QML WebEngineView using the loadHtml method, and I'm trying to get it to load the images through a QQuickImageProvider.
Up to now, we've been successfully loading images from a Qt resource container (qrc), but this is not flexible enough.
contentimageprovider.cpp
#include "contentimageprovider.h"
#include <QDebug>
ContentImageProvider::ContentImageProvider() : QQuickImageProvider(QQuickAsyncImageProvider::Image)
{
}
QImage ContentImageProvider::requestImage(const QString &id, QSize *size, const QSize &requestedSize)
{
qDebug() << __FUNCTION__ << id;
}
main.cpp
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQmlContext>
#include <QtWebEngine/QtWebEngine>
#include "contentimageprovider.h"
int main(int argc, char *argv[])
{
QGuiApplication app(argc, argv);
QQmlApplicationEngine engine;
QtWebEngine::initialize();
engine.addImageProvider(QLatin1String("content-images"), new ContentImageProvider);
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
return app.exec();
}
main.qml
import QtQuick 2.7
import QtQuick.Window 2.2
import QtWebEngine 1.4
Image {
source: "image://content-images/this-image-is-requested";
}
WebEngineView {
Component.onCompleted: {
loadHtml("<img src='qrc://images/this-image-is-displayed.png' /><img src='image://content-images/this-image-should-also-be-requested' />", "/");
}
}
Expected output
requestImage "this-image-is-requested"
requestImage "this-image-should-also-be-requested"
Actual output
requestImage "this-image-is-requested"
And the image loaded via qrc in the WebEngineView is displayed, and a broken image is shown for the other one.
Has anyone been able to get this to work?
Thanks to #Xplatforms who pointed out the initial error in assuming that the Chromium engine under the QML WebEngineView would interact with the QML Quick engine and trigger the image provider.
The solution was to implement a QWebEngineUrlSchemeHandler:
void ImageRequestHandler::requestStarted(QWebEngineUrlRequestJob *request)
{
// request->requestUrl() is a QUrl
QFile *image = new QFile(QDir::currentPath() + "/storage/content/" + request->requestUrl().path() + ".png");
// makes sure the image deletes itself when closing the file
connect(image, &QIODevice::aboutToClose, image, &QObject::deleteLater);
// close the file when the request job is done
connect(request, &QObject::destroyed, image, &QIODevice::close);
QMimeDatabase mimeDB;
QMimeType mimeType = mimeDB.mimeTypeForFile(image->fileName());
request->reply(mimeType.name().toUtf8(), image);
}
main.cpp
int main(int argc, char *argv[])
{
QGuiApplication app(argc, argv);
QQmlApplicationEngine engine;
// web engine to provide content display
QtWebEngine::initialize();
// intercept requests from the web engine to provide locally loaded content and images
ImageRequestHandler *imageRequestHandler = new ImageRequestHandler();
QQuickWebEngineProfile::defaultProfile()->installUrlSchemeHandler("image", imageRequestHandler);
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
return app.exec();
}

Can't enable debug context for QQmlApplicationEngine

I want to enable OpenGL logging in Qt. My code:
main.cpp:
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QSurfaceFormat>
#include <QOpenGLContext>
#include <QOpenGLDebugLogger>
QSurfaceFormat createSurfaceFormat() {
QSurfaceFormat format;
format.setDepthBufferSize(24);
format.setStencilBufferSize(8);
format.setOption(QSurfaceFormat::DebugContext);
return format;
}
void initGLLogging(QQmlApplicationEngine& engine) {
QOpenGLContext *ctx = QOpenGLContext::currentContext();
QOpenGLDebugLogger *logger = new QOpenGLDebugLogger(&engine);
logger->initialize();
qDebug() << "can gl log? " << ctx->hasExtension(QByteArrayLiteral("GL_KHR_debug"));
QObject::connect(logger, &QOpenGLDebugLogger::messageLogged,
[&](const QOpenGLDebugMessage &debugMessage) {
qDebug() << debugMessage;
}
);
logger->startLogging();
}
int main(int argc, char *argv[])
{
QSurfaceFormat::setDefaultFormat(::createSurfaceFormat());
QGuiApplication app(argc, argv);
QQmlApplicationEngine engine;
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
::initGLLogging(engine);
return app.exec();
}
main.qml:
import QtQuick 2.6
import QtQuick.Window 2.2
Window {
visible: true
width: 640
height: 480
}
The output, after building in debug mode and running in the debugger, is:
QOpenGLDebugLogger::initialize(): the current context is not a debug context:
this means that the GL may not generate any debug output at all.
To avoid this warning, try creating the context with the
QSurfaceFormat::DebugContext surface format option.
can gl log? true
Any idea why it's failing?
Note: I'm using ANGLE-mode in all Qt apps on my system, enabled via an env var, because otherwise they break in all kinds of ways. That's very likely to be related to the problem, but I can't do without this setting.

qt quick 2 printing with console

I can't figure out how to print with console.log inside a qt quick application.
I have this .pro file:
TEMPLATE = app
QT += qml quick
CONFIG += c++11
CONFIG += console
SOURCES += main.cpp
RESOURCES += qml.qrc
# Additional import path used to resolve QML modules in Qt Creator's code model
QML_IMPORT_PATH =
# Default rules for deployment.
include(deployment.pri)
this is 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")));
return app.exec();
}
this is main.qml:
import QtQuick 2.5
import QtQuick.Window 2.0
Window {
visible: true
Text {
anchors.centerIn: parent
text: "Hello World"
}
Component.onCompleted: console.log("foo")
}
Why it doens't print "foo"?
solved it was caused by the fact that Fedora has *.debug=false inside /etc/xdg/QtProject/qtlogging.ini and that prevents the messages to be printed. To "solve" this it's enough to create the file ~/.config/QtProject/qtlogging.ini with this content:
[Rules]
default=true

Using QtCreator 5.3 for Qt Quick UI project, how to link QML button resource to C++ function call

This is my first post on StackOverflow so please excuse any formatting mistakes I might have made.
I'm building a Qt Quick UI project using Qt Quick Controls 1.1 and I have a simple Button in my QML code that I would like to call into my C++ action class. I see a number of examples on this with earlier versions of Qt, but they do not seem to work in 5.3. I chose Qt Quick Controls 1.1 in the project settings. I know this must not be too complicated to do, but I can't seem to find examples using QtCreator 5.3
Here is my main.qml file:
import QtQuick 2.2
import QtQuick.Controls 1.1
import QtQuick.Layouts 1.1
ApplicationWindow {
id: parentWnd
visible: true
width: 640
height: 480
Action {
id: actionSend
onTriggered: console.log("SEND")
}
Button {
id: send
text: "Send Request"
action: actionSend
signal sendSignal()
}
}
Here is my main.cpp:
#include <QApplication>
#include <QQmlApplicationEngine>
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
QQmlApplicationEngine engine;
engine.load(QUrl(QStringLiteral("qrc:///main.qml")));
return app.exec();
}
Here is the action class where I would like the QML button to call "doSend":
#include<QDebug>
#include<QObject>
class Action : public QObject
{
Q_OBJECT
public:
Action();
public slots:
void doSend();
};
Finally here is my project file:
TEMPLATE = app
QT += qml quick widgets
SOURCES += main.cpp \
action.cpp
RESOURCES += qml.qrc
# Additional import path used to resolve QML modules in Qt Creator's code model
QML_IMPORT_PATH =
# Default rules for deployment.
include(deployment.pri)
HEADERS += \
action.h
When I run this, I see the button and I see the logging of "SEND" to the console so I know the QML Action is setup correctly. Any help on how to make the Action call into my action class would be much appreciated!
There are three issues that you're running into here.
The first is that you haven't registered your Action class with QML in main.cpp:
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
qmlRegisterType<Action>("StevesModule", 1, 0, "Action");
QQmlApplicationEngine engine;
engine.load(QUrl(QStringLiteral("qrc:///main.qml")));
return app.exec();
}
The second is that Action is a QML type in the Qt Quick Controls module. It doesn't know anything about your Action class in C++. If you want to use your Action class instead of Qt Quick Controls' Action type, you must import it in your QML file:
import StevesModule 1.0
The third is that you're not calling the doSend() slot anywhere. You can do this in the onClicked handler of Button:
import QtQuick 2.2
import QtQuick.Controls 1.1
import QtQuick.Layouts 1.1
import StevesModule 1.0
ApplicationWindow {
id: parentWnd
visible: true
width: 640
height: 480
Action {
id: actionSend
}
Button {
id: send
text: "Send Request"
onClicked: actionSend.doSend()
}
}

Resources