I am developing one BB 10 app in which I have coded first page (with NavigationPane) in C++. Now I want to push another qml page in NavigationPane on button click. I have tried following code with no luck
QmlDocument *qml = QmlDocument::create("asset:///main.qml").parent(this);
if (!qml->hasErrors()) {
Page *page = qml->createRootObject<Page>();
mRoot->push(page);
}
How can I achieve this?
Here is how can you push page using NavigationPane in C++:
Source file:
#include <bb/cascades/Application>
#include <bb/cascades/Button>
#include <bb/cascades/Label>
#include <bb/cascades/ActionItem>
#include <bb/cascades/Container>
#include <bb/cascades/DockLayout>
#include <bb/cascades/TitleBar>
#include <bb/cascades/NavigationPaneProperties>
#include "Sandoxproject.hpp"
using namespace bb::cascades;
SandboxApp::SandboxApp(bb::cascades::Application *app)
: QObject(app)
{
_navPane.reset(NavigationPane::create());
Page* firstPage = createFirstPage();
_navPane ->push(firstPage);
_secondPage.reset(createSecondPage());
app->setScene(_navPane.data());
}
bb::cascades::Page* SandboxApp::createFirstPage() {
Page* page = new Page();
Container* content = new Container();
TitleBar* titleBar = TitleBar::create().visibility(ChromeVisibility::Visible).title("First Page");
page->setTitleBar(titleBar);
content->setLayout(DockLayout::create());
Button* button = Button::create().text("Go to another page").horizontal(HorizontalAlignment::Center).vertical(VerticalAlignment::Center);
connect(button, SIGNAL(clicked()), this, SLOT(pushPage()));
content->add(button);
page->setContent(content);
return page;
}
bb::cascades::Page* SandboxApp::createSecondPage() {
Page* page = new Page();
TitleBar* titleBar = TitleBar::create().visibility(ChromeVisibility::Visible).title("Second Page");
page->setTitleBar(titleBar);
ActionItem* backAction = ActionItem::create();
connect(backAction, SIGNAL(triggered()), _navPane.data(), SLOT(pop()));
page->setPaneProperties(NavigationPaneProperties::create().backButton(backAction));
Container* content = new Container();
content->setLayout(DockLayout::create());
content->add(Label::create().text("This is the second page").horizontal(HorizontalAlignment::Center).vertical(VerticalAlignment::Center));
page->setContent(content);
return page;
}
void SandboxApp::pushPage() {
qDebug("pushing another page...");
_navPane->push(_secondPage.data());
}
Header file:
#ifndef Sandoxproject_HPP_
#define Sandoxproject_HPP_
#include <bb/cascades/NavigationPane>
#include <bb/cascades/Page>
#include <QObject>
namespace bb { namespace cascades { class Application; }}
class SandboxApp : public QObject
{
Q_OBJECT
public:
SandboxApp(bb::cascades::Application *app);
virtual ~SandboxApp() {}
private slots:
void pushPage();
private:
bb::cascades::Page* createFirstPage();
bb::cascades::Page* createSecondPage();
QScopedPointer<bb::cascades::NavigationPane> _navPane;
QScopedPointer<bb::cascades::Page> _secondPage;
Q_DISABLE_COPY(SandboxApp);
};
#endif /* Sandoxproject_HPP_ */
Related
my code is like this
in A.cpp
#include "rclcpp_lifecycle/rclcpp_lifecycle.hpp"
#include "B.hpp"
#include "D.hpp"
class A : public B, public rclcpp_lifecycle::LifecycleNode
{
A();
virtual ~A();
on_configure(...)
{
func_A()
}
func_A()
{
D::func_D(B::shared_from_this());
}
};
in D.cpp
class D
{
D();
~D();
static func_D(shared_ptr<B>){}
};
in main.cpp
#include "A.hpp"
int main()
{
std::shared_ptr<A> node = make_shared<A>("a");
rclcpp::spin(node);
}
then, in func_A, throw bad_weak_ptr
I think that rclcpp::spin keeps the shared_ptr of A, but it doesn't
what am i missing?
Sorry my bad English first of all.
I just want to use a class globally in my project but i receive some error.
I researched and tried similar titles but didnt work. Maybe i could not do.
code.h
#ifndef CODE_H_
#define CODE_H_
class sinif
{
public: void doSomeThing()
{
/*
...
*/
}
private:
};
sinif A;
#endif
Form1.h
//that is main form
#include "code.h"
#include "b.h"
namespace project
{
/*
...
A.doSomeThing(); // it works
*/
}
b.h
//that is second mini form
#include "code.h"
extern sinif A;
namespace project
{
/*
...
A.doSomeThing(); //it didn't work
*/
}
I have a project where I am expanding existing native C++ compatible code functionality for a customer-facing library by integrating a driver from a managed DLL, which seems like the opposite direction for most marshaling questions. Since there can be multiple devices using this one driver, each device needs to be its own object, with its own callback methods. This integration will take the form of a native wrapper DLL that exposes the native class interface to the customer-facing library, which will pass an instance of a member method callback function pointer to the DLL. I need to pass a native method member instance (non-static) as a delegate to the managed wrapper class. The managed wrapper class uses GetDelegateForFunctionPointer, which works to marshal static native pointers to a delegate, but I can't find any information if it works with instances. GetDelegateForFunctionPointer also takes a System::IntPtr argument for the function pointer, but I'm also not sure if System::IntPtr works for instances, and when compiling in VC++2008 I'm being presented an error C3867 for attempting this.
Managed wrapper header:
//somemanagedclass.hpp
#pragma once
using namespace System;
using namespace ExternalManagedLibrary;
namespace SomeNameSpace
{
public ref class SomeManagedClass
{
public:
SomeManagedClass();
~SomeManagedClass();
delegate void CallbackHandler(const wchar_t*, int);
CallbackHandler^ CallbackEvent;
void RegisterCallback(IntPtr callbackEvent);
private:
ExternalManagedClass^ externalManagedClass;
void OnCallback(Object^ sender, ValueEventArgs<String^>^ e);
};
}
Managed wrapper source:
//somemanagedclass.cpp
#include "somemanagedclass.hpp"
#include <vcclr.h>
using namespace System;
using namespace Runtime::InteropServices;
namespace SomeNameSpace
{
SomeManagedClass::SomeManagedClass()
{
externalManagedClass = gcnew ExternalManagedClass();
externalManagedClass->CallbackEvent += gcnew EventHandler<ValueEventArgs<String^>^>(this, &SomeManagedClass::OnCallback);
}
SomeManagedClass::~SomeManagedClass()
{
externalManagedClass->CallbackEvent -= gcnew EventHandler<ValueEventArgs<String^>^>(this, &SomeManagedClass::OnCallback);
}
void SomeManagedClass::OnCallback(Object^ sender, ValueEventArgs<String^>^ e)
{
String^ some_string = String::Copy(e->Value);
cli::pin_ptr<const wchar_t> pinned_string = &PtrToStringChars(some_string)[0];
const wchar_t* p = pinned_string;
CallbackEvent(pinned_string, some_string->Length);
}
void SomeManagedClass::RegisterCallback(IntPtr callbackEvent)
{
CallbackEvent = (CallbackHandler^)(Marshal::GetDelegateForFunctionPointer(callbackEvent, CallbackHandler::typeid));
}
}
Native wrapper interface:
//somenativeinterface.hpp
#ifdef DLL_EXPORT
#define IMPORT_EXPORT __declspec(dllexport)
#else
#define IMPORT_EXPORT __declspec(dllimport)
#endif //DLL_EXPORT
typedef void (*NativeCallback)(const unsigned char*, unsigned long);
class IMPORT_EXPORT SomeNativeInterface
{
public:
//class factory
static SomeNativeInterface* Create(void);
static void Destroy(SomeNativeInterface* clInterface);
virtual void CallbackInit(NativeCallback fnNativeCallbackInit);
};
Native wrapper header:
//somenativeclass.hpp
#pragma once
#include "somenativeinterface.hpp"
#include "somemanagedclass.hpp"
#include <vcclr.h>
using namespace SomeNameSpace;
class IMPORT_EXPORT SomeNativeClass : public SomeNativeInterface
{
public:
SomeNativeClass();
~SomeNativeClass();
void CallbackInit(NativeCallback fnNativeCallbackInit); //can this take an instance?
private:
NativeCallback fnNativeCallback;
void OnNativeCallback(const wchar_t* cString, int iSize);
gcroot<SomeManagedClass^> wrapper; //warning C4251
};
Native wrapper source:
//somenativeclass.cpp
#include "somenativeclass.hpp"
#include <vcclr.h>
#include <string.h>
using namespace System;
using namespace Runtime::InteropServices;
SomeNativeInterface* SomeNativeInterface::Create()
{
return ((SomeNativeInterface*) new SomeNativeClass());
}
void SomeNativeInterface::Destroy(SomeNativeInterface* instance)
{
delete instance;
}
SomeNativeClass::SomeNativeClass()
{
wrapper = gcnew SomeManagedClass();
}
SomeNativeClass::OnNativeCallback(const wchar_t* cString, int iSize)
{
std::auto_ptr<char> pcConvertedString(new char[iSize+1]);
size_t iCharsConverted;
if (wcstombs_s(&iCharsConverted, (char*)*pcConvertedString, iSize+1, cString, iSize) == 0)
{
if (iCharsConverted > 0xFFFFFFFF)
iCharsConverted = 0xFFFFFFFF; //truncate
fnNativeCallback((const unsigned char*)*pcConvertedString, (unsigned long)(iCharsConverted));
}
}
SomeNativeClass::CallbackInit(NativeCallback fnNativeCallbackInit)
{
fnNativeCallback = fnNativeCallbackInit;
wrapper->RegisterCallback(System::IntPtr(this->OnNativeCallback)); //error C3867
}
I have a form created in this way (the .h file of form is named Example):
This is a default code from a form:
namespace ExampleNamespace{
public ref class Example : public System::Windows::Forms::Form
{
public:
void DoSomething()
{
// code here
}
};
}
I can to this ?
Creating a new .cpp file and named Example.cpp am put here all the code from the form in .cpp ? In this way don't work.
namespace ExampleNamespace{
public ref class Example : public System::Windows::Forms::Form
{
public:
void DoSomething(); //if i try in this way I will have the error from above
};
}
and in Example.cpp
#include "Example.h"
void Example::DoSomething()
{
//code here
}
If I try to add public: void DoSomething(); in form i have this error:
error LNK2020: unresolved token (060000BB) ExampleNamespace.Example::DoSomething
I got the answer, you need to include the namespace after include the .h file like this in the .cpp file:
#include "Example.h"
using namespace ExampleNamespace;
And in *.h file you need to put this code:
#ifndef _EXAMPLE_H_
#define _EXAMPLE_H_
and
#endif
like this:
#ifndef _EXAMPLE_H_
#define _EXAMPLE_H_
namespace ExampleNamespace{
public ref class Example : public System::Windows::Forms::Form
{
public:
void DoSomething()
{
// code here
}
};
}
#endif
I'm using Qt 5.1.0 and QtQuick 2.0.
I've just learned how to exchange data and method between qml and C++. In detail, I want to expose a (nested) structure, so I created classes which contains the required properties and methods.
It works, but I cannot share the very same instance between C++ and qml. Changing something from C++ side leads to no changes in qml side.
A short example:
main.cpp
#include <QtGui/QGuiApplication>
#include <QtQml>
#include "qtquick2applicationviewer.h"
#include "myclass.h"
int main(int argc, char *argv[]) {
QGuiApplication app(argc, argv);
qmlRegisterType<MyClass>("MyLibrary", 1, 0, "MyClass");
MyClass *myclass = new MyClass();
Category *cat = new Category();
cat->setName("foo");
myclass->append(cat);
qDebug() << myclass->categoriesCount(); // returns 1 OK!
QtQuick2ApplicationViewer viewer;
viewer.setMainQmlFile(QStringLiteral("qml/main.qml"));
viewer.show();
return app.exec();
}
myclass.h
#include <QObject>
class Category : public QObject {
Q_OBJECT
Q_PROPERTY(QString name READ name WRITE setName)
public:
Category() {}
QString name() const { return m_name; }
void setName(QString name) { m_name = name; }
private:
QString m_name;
};
class MyClass : public QObject {
Q_OBJECT
Q_PROPERTY(QList<QObject*> categories READ categories NOTIFY categoriesChanged)
Q_PROPERTY(int categoriesCount READ categoriesCount)
public:
QList<QObject*> categories() const { return m_categories; }
void clear() { m_categories.clear(); }
void append(Category *category) { m_categories.append(category); }
int categoriesCount() const { return m_categories.count(); }
private:
QList<QObject*> m_categories;
signals:
void categoriesChanged();
};
main.qml
import QtQuick 2.0
import MyLibrary 1.0
Item {
id: root
width: 360
height: 360
Text {
id: foo
text: myclass.categoriesCount // writes 0 -> should be 1
}
MyClass {
id: myclass
}
}
I'm afraid the qml engine accesses to a different instance of the class myclass created in the main file.