09-07-2012 09:05 AM
Hi,
I am doing a simple application in which I have created qmlDocument object by loading main.qml file in app.cpp file.Now i want to use the object created in app.cpp file in another class .I tried this by including this App class in another class declaration.But if i am using the object created in app,cpp file in another class it is showing error.And i tried like this creating the qmldocument object by loading the same qml file in another class.But it is also not working.Please provide the solution.
Regards,
NareshKodumuri.
09-07-2012 11:11 AM
This is a C++ question; ignore cascades for the moment.
Usually you'll want a method in the main app, or even a standalone function in a namespace, that fetches the data once then returns it. Then this is called from your main code and from the other code.
You can be fancier, but basically, one place creates the variable and manages its lifetime, and other places can ask for it. You can use Qt smart pointer classes to manage the memory and keep references around, or sometimes you know the object will live for longer than the other callers will want it.
Now for your specific situation:
If you think you are already doing this, the next step is to look at the exact error you are getting, and maybe use the debugger. Can you provide more details? Is it a compile error or runtime error? If you are using pointers, did you make sure that the pointer is 0 rather than some arbitrary value before you load it?
Stuart
09-10-2012 07:46 AM
Hi,
Thanks for ur reply.Here is the code where i am getting problem.
app.cpp
----------------
#include "app.hpp"
#include "DateBox.hpp"
#include <bb/cascades/Button>
#include <bb/cascades/Application>
#include <bb/cascades/QmlDocument>
#include <bb/cascades/AbstractPane>
#include <bb/cascades/Container>
#include <bb/cascades/Color>
#include <bb/cascades/Page>
#include <bb/cascades/Label>
#include <bb/cascades/AbsoluteLayoutProperties>
#include <bb/cascades/DockLayoutProperties>
#include <bb/cascades/DockLayout>
#include <bb/cascades/ImagePaint>
#include <QDateTime>
using namespace bb::cascades;
//global variables
QString monArray[12] = { "Jan", "Feb", "Mar", "Apr", "May", "June", "July",
"Aug", "Sep", "Oct", "Nov", "Dec" };
QDate date;
int x;
int y;
int cols;
int year;
int month;
int day;
QVariant currentDay;
bool row_inserted;
Container *btnContainer;
Button *nextMon, *prevMon;
Label *lbl;
int i, firstDay, daycount = 0, totalNoOfDaysInMonth = 0,j;
static int monIndex;
static int yearIndex;
static int dow;
QString timeString;
Label *curDateLabel;
App::App() {
date = QDate::currentDate();
QString curdate = QDate::currentDate().toString("dd-MM-yyyy");
year = date.year();
yearIndex=date.year();
month = date.month();
monIndex=date.month();
day = date.day();
qmlRegisterType<DateBox>("my.datebox", 1, 0, "DateBox");
//created a qml document object.I need to use this object in DateBox class
qml = QmlDocument::create("main.qml");
//setting context property
qml->setContextProperty("add_dates", this);
page = qml->createRootNode<Page>();
//finding the container for changing background
cont_cal = page->findChild<Container *>("cont_calendar");
curDateLabel=page->findChild<Label *>("curdate");
firstDay = firstDayOfMonth(month, year);
totalNoOfDaysInMonth = totalNoOfDays(month, year);
Application::setScene(page);
}
void App::addContainers() {
if(cont_cal->count()>0)
cont_cal->removeAll();
x = 3;
y = 3;
cols = 0;
currentDay = 0;
row_inserted = false;
j = 1;
for (int i = 0; i < 49; i++) {
if (cols == 7) {
row_inserted = true;
cols = 0;
y += 98;
}
if (row_inserted) {
x = 3;
row_inserted = false;
}
QString curDate = "";
if (i >= firstDay) {
if (j <= totalNoOfDaysInMonth) {
currentDay = j;
curDate = currentDay.toString();
j++;
}
}
DateBox *dateBox = new DateBox();
dateBox->setLayoutProperties(AbsoluteLayoutPropert ies::create().position(x, y));
qDebug()<<curDate;
dateBox->setLabelText(curDate);
cont_cal->add(dateBox);
x += 109;
cols++;
}
QVariant yearVal=yearIndex;
QString yearValue=yearVal.toString();
qDebug()<<yearVal;
qDebug()<<yearValue;
curDateLabel->setText(monArray[monIndex-1]+"-"+yea rValue);
}
int App::firstDayOfMonth(int months, int year) {
int mon = months;
int yearNumber = year;
dow = 6;
for (int i = 1583; i < yearNumber; i++)
dow += (checkLeap(i)) ? 2 : 1;
for (int i = 1; i < mon; i++) {
dow += totalNoOfDays(i, year);
}
dow = dow % 7;
return dow;
}
int App::totalNoOfDays(int months, int year) {
switch (months) {
case 1:
return 31;
break;
case 2:
if (checkLeap(year))
return 29;
else
return 28;
break;
case 3:
return 31;
break;
case 4:
return 30;
break;
case 5:
return 31;
break;
case 6:
return 30;
break;
case 7:
return 31;
break;
case 8:
return 31;
break;
case 9:
return 30;
break;
case 10:
return 31;
break;
case 11:
return 30;
break;
case 12:
return 31;
break;
default:
break;
}
return 0;
}
bool App::checkLeap(int year) {
if ((year % 4 == 0) && ((year % 100 != 0) || (year % 400 == 0)))
return true;
else
return false;
}
void App:: btnNextFunction() {
qDebug()<<"btnNextFunction called";
qDebug()<<monArray[monIndex-1];
qDebug()<<monIndex;
monIndex = monIndex + 1;
qDebug()<<monIndex;
//qDebug()<<monIndex;
if (monIndex <= 12)
{
firstDay = firstDayOfMonth(monIndex, yearIndex);
qDebug()<<firstDay;
qDebug()<<yearIndex;
totalNoOfDaysInMonth = totalNoOfDays(monIndex, yearIndex);
}
if (monIndex > 12) {
yearIndex = yearIndex + 1;
monIndex = 1;
firstDay=firstDayOfMonth(monIndex, yearIndex);
qDebug()<<firstDay;
totalNoOfDaysInMonth = totalNoOfDays(monIndex, yearIndex);
}
addContainers();
}
void App:: btnPrevFunction() {
addContainers();
monIndex = monIndex - 1;
if (monIndex > 0)
{
firstDay = firstDayOfMonth(monIndex, yearIndex);
totalNoOfDaysInMonth = totalNoOfDays(monIndex, yearIndex);
}
if (monIndex == 0) {
yearIndex = yearIndex - 1;
monIndex = 12;
firstDay = firstDayOfMonth(monIndex, yearIndex);
totalNoOfDaysInMonth = totalNoOfDays(monIndex, yearIndex);
}
addContainers();
}
app.hpp
-------------
#ifndef APP_H
#define APP_H
#include <QObject>
#include <bb/cascades/Container>
#include <bb/cascades/TouchEvent>
#include <bb/cascades/Label>
#include <bb/cascades/QmlDocument>
#include <bb/cascades/Page>
using namespace bb::cascades;
/*!
* @brief Application GUI object
*/
class App: public QObject {
Q_OBJECT
public:
App();
Q_INVOKABLE void addContainers();
Container *cont_cal;
Label *lbl;
Container *cont;
QmlDocument *qml;
Page *page;
int firstDayOfMonth(int, int);
int totalNoOfDays(int, int);
bool checkLeap(int);
Q_INVOKABLE void btnPrevFunction();
Q_INVOKABLE void btnNextFunction();
};
#endif // ifndef APP_H
DateBox.cpp
--------------------
#include "DateBox.hpp"
#include "App.hpp"
#include <bb/cascades/Container>
#include <bb/cascades/CustomControl>
#include <bb/cascades/DockLayout>
#include <bb/cascades/AbsoluteLayoutProperties>
#include <bb/cascades/DockLayoutProperties>
#include <bb/cascades/TextStyle>
#include <bb/cascades/QmlDocument>
#include <bb/cascades/AbstractPane>
#include <bb/cascades/ImagePaint>
#include <bb/cascades/ImageTracker>
using namespace bb::cascades;
//ImageTracker *imgPaint;
DateBox::DateBox()
{
/* I want to use the objects created in app.cpp file (qmlDocument,root node and container where i need to change the background) in this file*/
// mainQml = QmlDocument::create("main.qml");
// mainPage = mainQml->createRootNode<AbstractPane>();
// cont_cal = mainPage->findChild<Container *>("cont_calendar");
cont = Container::create()
.preferredSize(106, 95)
.leftMargin(3)
.topMargin(3)
.layout(DockLayout::create())
.background(Color::Transparent);
lbl = Label::create()
.layoutProperties(DockLayoutProperties::create()
.horizontal(HorizontalAlignment::Center)
.vertical(VerticalAlignment::Center));
cont->add(lbl);
bool res=QObject::connect(cont,SIGNAL(touch(bb::cascade s::TouchEvent *)),this,SLOT(onTouch()));
Q_ASSERT(res);
Q_UNUSED(res);
setRoot(cont);
}
void DateBox::setLabelText(QString text)
{
lbl->setText(text);
}
QString DateBox::getText()
{
return lbl->text();
}
void DateBox::onTouch()
{
qDebug()<<"method called";
//the text on the label
qDebug()<<getText();
//this is the container where i need to set the background for a container.But this is not
//applying
cont_cal->setBackground(ImagePaint(QUrl("asset:/// images/flower2.png"),RepeatPattern::XY));
}
DateBox.hpp
--------------------
#ifndef DATEBOX_H
#define DATEBOX_H
#include <QObject>
#include <QString>
#include <bb/cascades/CustomControl>
#include <bb/cascades/Container>
#include <bb/cascades/Label>
#include <bb/cascades/QmlDocument>
#include <bb/cascades/AbstractPane>
using namespace bb::cascades;
class DateBox:public bb::cascades::CustomControl,public App
{
Q_OBJECT
Q_PROPERTY(QString text READ getText WRITE setLabelText);
public:
Container *cont/*, *cont_cal*/;
Label *lbl;
/*QmlDocument *mainQml;
AbstractPane *mainPage;*/
DateBox();
void setLabelText(QString);
QString getText();
public slots:
void onTouch();
};
#endif
main.qml
---------------
import bb.cascades 1.0
import my.datebox 1.0
//-- create one page with a label and text
Page {
objectName: "page_calendar"
content: Container {
objectName: "cont_main"
layout: StackLayout {
}
Container {
layout: DockLayout {
}
preferredWidth: 768
Button {
text: "prev"
preferredWidth: 120
layoutProperties: DockLayoutProperties {
horizontalAlignment: HorizontalAlignment.Left
verticalAlignment: VerticalAlignment.Top
}
onClicked: {
add_dates.btnPrevFunction();
}
}
Label {
objectName: "curdate"
id: lbl_calendar
text: ""
layoutProperties: DockLayoutProperties {
verticalAlignment: VerticalAlignment.Center
horizontalAlignment: HorizontalAlignment.Center
}
textStyle {
base: SystemDefaults.TextStyles.TitleText
color: Color.create("#FA5906")
}
}
Button {
text: "next"
preferredWidth: 120
layoutProperties: DockLayoutProperties {
horizontalAlignment: HorizontalAlignment.Right
verticalAlignment: VerticalAlignment.Top
}
onClicked: {
console.debug("clicked");
add_dates.btnNextFunction();
}
}
}
Container {
preferredHeight: 98
preferredWidth: 768
background: Color.Red
layout: StackLayout {
layoutDirection: LayoutDirection.LeftToRight
}
layoutProperties: AbsoluteLayoutProperties {
}
id: cont_weekdays
Label {
text: " SUN"
layoutProperties: StackLayoutProperties {
spaceQuota: 1
verticalAlignment: VerticalAlignment.Center
horizontalAlignment: HorizontalAlignment.Center
}
}
Label {
text: "MON"
layoutProperties: StackLayoutProperties {
spaceQuota: 1
verticalAlignment: VerticalAlignment.Center
horizontalAlignment: HorizontalAlignment.Center
}
}
Label {
text: "TUE"
layoutProperties: StackLayoutProperties {
spaceQuota: 1
horizontalAlignment: HorizontalAlignment.Center
verticalAlignment: VerticalAlignment.Center
}
}
Label {
text: "WED"
layoutProperties: StackLayoutProperties {
spaceQuota: 1
horizontalAlignment: HorizontalAlignment.Center
verticalAlignment: VerticalAlignment.Center
}
}
Label {
text: "THU"
layoutProperties: StackLayoutProperties {
spaceQuota: 1
horizontalAlignment: HorizontalAlignment.Center
verticalAlignment: VerticalAlignment.Center
}
}
Label {
text: "FRI"
layoutProperties: StackLayoutProperties {
spaceQuota: 1
horizontalAlignment: HorizontalAlignment.Center
verticalAlignment: VerticalAlignment.Center
}
}
Label {
text: "SAT"
layoutProperties: StackLayoutProperties {
spaceQuota: 1
horizontalAlignment: HorizontalAlignment.Center
verticalAlignment: VerticalAlignment.Center
}
}
}
Container {
id: cont_cal
objectName: "cont_calendar"
preferredWidth: 768
preferredHeight: 700
layout: AbsoluteLayout {
}
layoutProperties: StackLayoutProperties {
horizontalAlignment: HorizontalAlignment.Center
}
background: back.imagePaint
attachedObjects: [
ImagePaintDefinition {
id: back
repeatPattern: RepeatPattern.XY
imageSource: "asset:///images/flower.jpg"
}
]
}
Button {
text: "Add"
onClicked: {
console.debug("calling add method");
add_dates.addContainers();
}
}
}
}
Please provide me the solution.
Naresh Kodumuri
09-11-2012 01:37 PM
It seems to me that this is a pure C++ design choice.
If you want to access the "qml" attribute of the "App" object in the constructor of "DateBox", then you can choose to
either
implement "App" as a singleton, then, access its attribute in the constructor of tthe "DateBox"
Or
pass the pointer of the "qml" attribute of he "App" object as a parameter of the constructor of "DateBox".