QQuickWindow in shared lib auto close when show in QApplication - c++

I develop a generic interface library with qt. I have trouble with pressed effect on QPushbutton when I click with a touch screen (this effect appears one time on 10 click).
So I create a basic qml application with one button and pressed effect appear all time. I incude the qml part into my library and load it in QQuickWidget and I have same problem with pressed effect.
So I want to use only qml. My principal application is a QApplication and I load my library in it in which I load qml file with QQmlApplication Engine. Then I show it by QQuickWindow.
When I launch my application I saw the window open but it is automatically close. I think my QApplication don't detect QML and the renderer loop is not start.
I'm on windows with QT5.5.1 (MSVC2013, 32bit)
pro file of main application
QT += core xml widgets qml quick
TARGET = COM_INT
CONFIG += console
CONFIG -= app_bundle
TEMPLATE = app
SOURCES += main.cpp \
comint.cpp
HEADERS += \
comint.h \
INCLUDEPATH += "$$(My_Workspace)/Modules_Generique/IHM_Soft"
Release{
LIBS += "$$(My_Workspace_build)/IHM_Soft/release/IHM_Soft.lib"
}
Debug{
LIBS += "$$(My_Workspace_build)/IHM_Soft/debug/IHM_Soft.lib"
}
Main application (exe) main.cpp
#include <QApplication>
#include <QQmlApplicationEngine>
#include "comint.h"
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
ComInt com;
com.initialize();
return a.exec();
}
ComInt class:
Source file comint.cpp
#include "comint.h"
#include "ihmsoft.h"
ComInt::ComInt()
{
}
void ComInt::initialize()
{
this->m_pIHMSoft = new IHMSoft();
}
header file comint.h
#ifndef COMINT_H
#define COMINT_H
class IHMSoft;
class ComInt
{
public:
ComInt();
void initialize();
private:
IHMSoft *m_pIHMSoft;
};
#endif // COMINT_H
pro file of shared lib
QT += xml widgets core qml quick quickwidgets
CONFIG += c++11
TARGET = IHM_Soft
TEMPLATE = lib
DEFINES += IHM_SOFT_LIBRARY
SOURCES += ihmsoft.cpp
HEADERS += ihmsoft.h\
ihm_soft_global.h
RESOURCES += \
rsc.qrc
Shared library: source file ihm_soft.cpp
#include "ihmsoft.h"
#include <QQmlApplicationEngine>
#include <QQuickWindow>
IHMSoft::IHMSoft(){
qputenv("QT_QUICK_CONTROLS_STYLE", "Base");
QQmlApplicationEngine engine;
engine.load(QUrl(QStringLiteral("qrc:/IHM_Soft.qml")));
QList<QObject*> root = engine.rootObjects();
QQuickWindow *window = qobject_cast<QQuickWindow*>(root.at(0));
window->show();
}
header file ihm_soft.h
#ifndef IHM_SOFT_H
#define IHM_SOFT_H
#include "ihm_soft_global.h"
class IHM_SOFT_SHARED_EXPORT IHM_Soft
{
public:
IHM_Soft();
};
#endif // IHM_SOFT_H
Global file ihm_soft_global.h
#ifndef IHM_SOFT_GLOBAL_H
#define IHM_SOFT_GLOBAL_H
#include <QtCore/qglobal.h>
#if defined(IHM_SOFT_LIBRARY)
# define IHM_SOFT_SHARED_EXPORT Q_DECL_EXPORT
#else
# define IHM_SOFT_SHARED_EXPORT Q_DECL_IMPORT
#endif
#endif // IHM_SOFT_GLOBAL_H
Qml file
import QtQuick 2.0
import QtQuick.Controls 1.4
import QtQuick.Window 2.0
ApplicationWindow {
visible: true
width: 500
height: 500
Button {
visible: true
iconSource: "resources/t_on_off.png"
}
}
Edit: Sorry the code of the main application was a test application which do not include lib.

A variable is deleted when its scope ends, in your case engine is a local variable that is deleted when IHMSoft finishes being built, so you see that the window closes. The solution is to make it a member of the class:
*.h
#ifndef IHM_SOFT_H
#define IHM_SOFT_H
#include "ihm_soft_global.h"
#include <QQmlApplicationEngine>
class IHM_SOFT_SHARED_EXPORT IHM_Soft
{
public:
IHM_Soft();
private:
QQmlApplicationEngine engine; // member
};
#endif // IHM_SOFT_H
*.cpp
#include "ihmsoft.h"
IHMSoft::IHMSoft(){
qputenv("QT_QUICK_CONTROLS_STYLE", "Base");
engine.load(QUrl(QStringLiteral("qrc:/IHM_Soft.qml")));
}

Related

Can I make QSettings settings for 2 or more applications?

There are 2 applications:
creates a file somewhere, and
should go along some path and pick up the contents of the file.
Can I in the first application specify the path to the file in QSettings, and the second to take this path from the registry and go through it to the file?
Please tell me a simple example.
I cannot suggest a cross-platform method based on registry, but want to show another ways.
Method 1 (based on common ini file)
Store the path in some common ini file, for example in <some_common_path>/settings_common.ini. Both applications shall have access to the file:
App 1 (Writer)
#include <QtCore/QCoreApplication>
#include <QSettings>
#include <QDebug>
#include <QThread>
const QString CommonSettingsFilePath = "c:/temp/settings_common.ini";
const QString CommonKey = "common/path";
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
for(;;)
{
static int it = 0;
QString pathString = QString("path_%1").arg(it++);
QSettings settings(CommonSettingsFilePath, QSettings::IniFormat);
settings.setValue(CommonKey, pathString);
QThread::sleep(1);
}
return a.exec();
}
App 2 (Reader)
#include <QtCore/QCoreApplication>
#include <QSettings>
#include <QDebug>
#include <QThread>
const QString CommonSettingsFilePath = "c:/temp/settings_common.ini";
const QString CommonKey = "common/path";
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
for (;;)
{
QSettings settings(CommonSettingsFilePath, QSettings::IniFormat);
QString pathString = settings.value(CommonKey, "").toString();
qDebug() << "Path read from ini =" << pathString;
QThread::sleep(2);
}
return a.exec();
}
Possible output of the App 2:
Path read from ini = "path_6"
Path read from ini = "path_8"
Path read from ini = "path_9"
Path read from ini = "path_11"
...
Method 2 (based on Inter-process communication)
IPC using Qt Remote Objects API:
App1 is Source, App2 (reader) will be Replica, the path is a property.
Only the main points are shown.
In both App1 and App2 .pro files add remoteobjects module:
QT += core remoteobjects ...
path.rep file:
#include <QtCore>
#include <QString>
class Path
{
PROP(QString path);
};
In App1 pro:
REPC_SOURCE = path.rep
App1 class:
#include "rep_path_source.h"
class CommonPath : public PathSimpleSource
{
Q_OBJECT
};
Then in App1:
CommonPath sourcePath;
QRemoteObjectHost sourceNode(QUrl("local:path")); // create host node
sourceNode.enableRemoting(&sourcePath); // enable remoting/sharing
...
sourcePath.setPath("some_path_aaa");
In App2 pro:
REPC_REPLICA = path.rep
In App2 furthermore:
#include "rep_path_replica.h"
QSharedPointer<PathReplica> replica;
QRemoteObjectNode repNode; // create remote object node
repNode.connectToNode(QUrl("local:path")); // connect with remote host node
replica.reset(repNode.acquire<PathReplica>()); // acquire replica of source from host node
replica->waitForSource();
...
qDebug() << replica->path();
Of course you can distribute all the necessary data in this way, not just the path.

How to get IMEI number in blackberry 10 native

I am trying to get the Default information of Hardware device in blackberry 10 native, So basically i am trying to access IMEI or SERIAL NUMBER of the device.
I havetried using following code
main.cpp
#include "applicationui.hpp"
#include <bb/cascades/Application>
#include <bb/device/HardwareInfo>
#include <QLocale>
#include <QTranslator>
#include <Qt/qdeclarativedebug.h>
using namespace bb::cascades;
Q_DECL_EXPORT int main(int argc, char **argv)
{
qmlRegisterUncreatableType<bb::device::HardwareInfo>("bb.device", 1, 0, "HardwareInfo", "");
Application app(argc, argv);
ApplicationUI appui;
return Application::exec();
}
applicationui.cpp
#include "applicationui.hpp"
#include <bb/cascades/Application>
#include <bb/cascades/QmlDocument>
#include <bb/cascades/AbstractPane>
#include <bb/device/HardwareInfo>
#include <bb/cascades/Label>
using namespace bb::cascades;
using namespace bb::device;
ApplicationUI::ApplicationUI() :
QObject()
{
HardwareInfo hwInfo;
QmlDocument *qml = QmlDocument::create("asset:///main.qml").parent(this);
qml->setContextProperty("_hardware", &hwInfo);
AbstractPane *root = qml->createRootObject<AbstractPane>();
Application::instance()->setScene(root);
}
main.qml
Page {
Container {
Label {
id: showIMEI
}
Button {
text: "Click me"
onClicked: {
showIMEI.text = "IMEI = " + _hardware.serialNumber;
//showIMEI.text = "IMEI = " + _hardware.imei;
}
}
}
}
but when i click a button i am not getting any data either IMEI or SerialNumber instead of imei or serial number. But always i am getting error like
'_hardware' [undefined] is not an object.
Note: i have already added following library in my .PRO
LIBS += -lbbsystem
LIBS += -lbbdevice
LIBS += -lbbdata
and following permission to my XML file.
read_device_identifying_information
I have also researched through many link like,
Link1, Link2, Link3 and i have also read the official document of Blackberry but i am not getting proper way to achieve my task.
Try this,
main.cpp
#include "applicationui.hpp"
#include <bb/cascades/Application>
#include <bb/device/HardwareInfo.hpp>
#include <QLocale>
#include <QTranslator>
#include <Qt/qdeclarativedebug.h>
using namespace bb::cascades;
using namespace bb::device;
Q_DECL_EXPORT int main(int argc, char **argv)
{
qmlRegisterType<HardwareInfo>("bb.device",1,0,"HardwareInfo");
Application app(argc, argv);
// Create the Application UI object, this is where the main.qml file
// is loaded and the application scene is set.
ApplicationUI appui;
// Enter the application main event loop.
return Application::exec();
}
main.qml
import bb.cascades 1.0
import bb.device 1.0
Page {
Container {
Label {
id: label
// Localized text with the dynamic translation and locale updates support
text: qsTr("Hello World") + Retranslate.onLocaleOrLanguageChanged
textStyle.base: SystemDefaults.TextStyles.BigText
multiline: true
}
Button {
onClicked: {
label.text=hardwareinfo.imei
console.debug("imei\t"+hardwareinfo.imei)
console.debug("serialNumber \t"+hardwareinfo.serialNumber)
}
}
}
attachedObjects:[
HardwareInfo {
id: hardwareinfo
}
]
}

QtQuick2 does not find .h files with new classes

I'm trying to learn how to connect Qt quick object signals to slots in classes in the c++ code. When I add the class definitions to the "qtquick2applicationviewer.h" file that is created by the system, everything works.
But I can't find a way to add my own .h file (I should do this as indicated in the .h file: "It is recommended not to modify this file, since newer versions of Qt Creator may offer an updated version of it.")
I tried adding the source to the .pro file (HEADERS += classes.h), also tried to add it to the .pri file (HEADERS += $$PWD/../classes.h) but no luck.
The Error I get is a linker error:
LNK2001: unresolved external sybol "public: virtual struct QMetaObject const * __thiscall MyClass::metaObject(void)const " (?metaObject#Myclass##UBEPBUQMetaObject##XZ)
and two more similar.
Any inputs on what I'm doing wrong is highly appreciated :)
Can probably help many others as well as it is a general question bases on the QTQuick tutorial application.
//classes.h
#ifndef CLASSES_H
#define CLASSES_H
#include <QObject>
#include <QVariant>
class MyClass : public QObject
{
Q_OBJECT
public:
MyClass(QObject *QMLObject) : m_QMLObject(QMLObject) {}
public slots:
void handleClick() {
m_QMLObject->setProperty("text", "Qt was here");
}
protected:
QObject *m_QMLObject;
};
#endif // CLASSES_H
//main.cpp
#include <QtGui/QGuiApplication>
#include "qtquick2applicationviewer.h"
#include "classes.h"
#include <QtQuick>
#include <QtDebug>
void MyClassInQtQhfile::cppSlot(const QString &msg) {
qDebug() << "Called the C++ slot with message:" << msg;
}
int main(int argc, char *argv[])
{
QTextStream out(stdout);
QGuiApplication app(argc, argv);
QtQuick2ApplicationViewer viewer;
viewer.setMainQmlFile(QStringLiteral("qml/Transitions/main.qml"));
viewer.showExpanded();
QObject *rectangle = viewer.rootObject()->findChild<QObject*>("rectangle");
QObject *text = viewer.rootObject()->findChild<QObject*>("text");
MyClassInQtQhfile *myClassInQtQhfile = new MyClassInQtQhfile();
MyClass *myclass = new MyClass(text);
QObject::connect(rectangle, SIGNAL(qmlSignal(QString)),
myClassInQtQhfile, SLOT(cppSlot(QString)));
QObject::connect(rectangle, SIGNAL(qmlSignal(QString)),
myclass, SLOT(handleClick()));
//rectangle is the object name, which needs to be define in qml for the component.e.g. objectName: "rectangle"
return app.exec();
}
//QML object sending signal
Rectangle {
objectName: "rectangle"
id: bottomLeftRect
width: 64
height: 64
color: "#00000000"
radius: 6
anchors.left: parent.left
anchors.leftMargin: 10
anchors.bottom: parent.bottom
anchors.bottomMargin: 20
border.color: "#808080"
signal qmlSignal(string msg)
MouseArea {
id: mousearea3
anchors.fill: parent
onClicked:{
bottomLeftRect.qmlSignal("Hello from QML")
onClicked: page.state = 'State2'
}
}
}
Beginning of qtquick2applicationviewer.pri
# checksum 0x21c9 version 0x90005
# This file was generated by the Qt Quick 2 Application wizard of Qt Creator.
# The code below adds the QtQuick2ApplicationViewer to the project and handles
# the activation of QML debugging.
# It is recommended not to modify this file, since newer versions of Qt Creator
# may offer an updated version of it.
QT += qml quick
SOURCES += $$PWD/qtquick2applicationviewer.cpp
HEADERS += $$PWD/qtquick2applicationviewer.h
HEADERS += $$PWD/../classes.h
INCLUDEPATH += $$PWD
...
.pro file
# Add more folders to ship with the application, here
folder_01.source = qml/Transitions
folder_01.target = qml
DEPLOYMENTFOLDERS = folder_01
# Additional import path used to resolve QML modules in Creator's code model
QML_IMPORT_PATH =
# The .cpp file which was generated for your project. Feel free to hack it.
SOURCES += main.cpp
# Installation path
# target.path =
# Please do not modify the following two lines. Required for deployment.
include(qtquick2applicationviewer/qtquick2applicationviewer.pri)
qtcAddDeployment()
HEADERS += \
classes.h

C++: Media Player using Qt

I want to develop a media player using Qt. On the basis of the documentation I have done the following things:
pro file
QT += core gui multimedia
QT += multimediawidgets
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
TARGET = Player
TEMPLATE = app
SOURCES += main.cpp\
mainwindow.cpp
HEADERS += mainwindow.h
FORMS += mainwindow.ui
main.cpp file
#include <QApplication>
#include <QtMultimediaWidgets/QVideoWidget>
#include <QtMultimedia/QMediaPlayer>
#include <QtMultimedia/QMediaPlaylist>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QMediaPlayer *player=new QMediaPlayer;
QVideoWidget *videowidget=new QVideoWidget;
QMediaPlaylist *playlist=new QMediaPlaylist;
playlist->addMedia(QUrl("C:/Users/Administrator/Desktop/VideoLAN/VLC/stram.mp4"));
player->setVideoOutput(videowidget);
playlist->setCurrentIndex(1);
player->setPlaylist(playlist);
player->play();
videowidget->show();
return a.exec();
}
As for the header file I have included mainwindow.h
EDIT
All the erorrs are gone but now the output which is coming is:
Where am I going wrong?
Try add this string to .pro file:
QT += multimediawidgets
for additional info: http://qt-project.org/doc/qt-5/qvideowidget.html

How to catch exceptions with Qt platform independently?

I'm using boost::date_time in my project. When date is not valid it thorws std::out_of_range C++ exception. In Qt's gui application on windows platform it becomes SEH exception, so it doesn't catched with try|catch paradigm and programm dies. How can I catch the exception platform independently?
try{
std::string ts("9999-99-99 99:99:99.999");
ptime t(time_from_string(ts))
}
catch(...)
{
// doesn't work on windows
}
EDITED:
If somebody didn't understand, I wrote another example:
Qt pro file:
TEMPLATE = app
DESTDIR = bin
VERSION = 1.0.0
CONFIG += debug_and_release build_all
TARGET = QExceptExample
SOURCES += exceptexample.cpp \
main.cpp
HEADERS += exceptexample.h
exceptexample.h
#ifndef __EXCEPTEXAMPLE_H__
#define __EXCEPTEXAMPLE_H__
#include <QtGui/QMainWindow>
#include <QtGui/QMessageBox>
#include <QtGui/QPushButton>
#include <stdexcept>
class PushButton;
class QMessageBox;
class ExceptExample : public QMainWindow
{
Q_OBJECT
public:
ExceptExample();
~ExceptExample();
public slots:
void throwExcept();
private:
QPushButton * throwBtn;
};
#endif
exceptexample.cpp
#include "exceptexample.h"
ExceptExample::ExceptExample()
{
throwBtn = new QPushButton(this);
connect(throwBtn, SIGNAL(clicked()), this, SLOT(throwExcept()));
}
ExceptExample::~ExceptExample()
{
}
void ExceptExample::throwExcept()
{
QMessageBox::information(this, "info", "We are in throwExcept()",
QMessageBox::Ok);
try{
throw std::out_of_range("ExceptExample");
}
catch(...){
QMessageBox::information(this, "hidden", "Windows users can't see "
"this message", QMessageBox::Ok);
}
}
main.cpp
#include "exceptexample.h"
#include <QApplication>
int main(int argc, char* argv[])
{
QApplication app(argc, argv);
ExceptExample e;
e.show();
return app.exec();
}
Adding answer from the comments:
aschelper wrote:
Is your Qt library compiled with C++
exception support enabled? Sometimes
they're not, which causes problems.
hoxnox (OP) answered:
#aschelper I reconfigured Qt with
-exceptions option. It fixed situation. If you'll post the answer
I'll mark it as right.