How to convert enum to QString? - c++

I am trying to use the Qt reflection for converting enum to QString.
Here is the part of code:
class ModelApple
{
Q_GADGET
Q_ENUMS(AppleType)
public:
enum AppleType {
Big,
Small
}
}
And here is i trying to do:
convertEnumToQString(ModelApple::Big)
Return "Big"
Is this possible?
If you have any idea about convertEnumToQString, please share it

You need to use Q_ENUM macro, which registers an enum type with the meta-object system.
enum AppleType {
Big,
Small
};
Q_ENUM(AppleType)
And now you can use the QMetaEnum class to access meta-data about an enumerator.
QMetaEnum metaEnum = QMetaEnum::fromType<ModelApple::AppleType>();
qDebug() << metaEnum.valueToKey(ModelApple::Big);
Here is a generic template for such utility:
template<typename QEnum>
std::string QtEnumToString (const QEnum value)
{
return std::string(QMetaEnum::fromType<QEnum>().valueToKey(value));
}

Much more elegant way found (Qt 5.9), just one single line, with the help of mighty QVariant.
turns enum into string:
QString theBig = QVariant::fromValue(ModelApple::Big).toString();
Perhaps you don't need QMetaEnum anymore.
Sample code here:
ModelApple (no need to claim Q_DECLARE_METATYE)
class ModelApple : public QObject
{
Q_OBJECT
public:
enum AppleType {
Big,
Small
};
Q_ENUM(AppleType)
explicit ModelApple(QObject *parent = nullptr);
};
And I create a widget application, calling QVaraint function there :
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <modelapple.h>
#include <QDebug>
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
QString s = QVariant::fromValue(ModelApple::Big).toString();
qDebug() << s;
}
MainWindow::~MainWindow()
{
delete ui;
}
You can see that i try to output the string on console , which really did:
And sorry for reverse casting , i tried successfully in some project , but some how this time i met compiling error. So i decide to remove it from my answer.

The following should get you going:
QString convertEnumToQString(ModelApple::AppleType type) {
const QMetaObject metaObject = ModelApple::staticMetaObject;
int enumIndex = metaObject.indexOfEnumerator("AppleType");
if(enumIndex == -1) {
/* The enum does not contain the specified enum */
return "";
}
QMetaEnum en = metaObject.enumerator(enumIndex);
return QString(en.valueToKey(type));
}

For the global Enum declaring use this in any header file:
namespace YourNamespace {
Q_NAMESPACE
enum YourEnum: int {
EnumValue1,
EnumValue2
};
Q_ENUM_NS(YourEnum)
}
and this where you want to get Enum description:
QMetaEnum metaEnum = QMetaEnum::fromType<YourEnum>();
qDebug() << "Enum description: " << metaEnum.name() << "::" << metaEnum.valueToKey(YourEnum::EnumValue2);

How about:
QString convertEnumToQString(ModelApple::AppleType type)
{
const QMetaObject &mo = ModelApple::staticMetaObject;
int index = mo.indexOfEnumerator("AppleType");
QMetaEnum metaEnum = mo.enumerator(index);
return metaEnum.valueToKey(type);
}
UPDATED: For Qt 5.5, see this answer

I faced the same problem and this is how i solved it. This is especially for Qt 4.8
QString string = enumToString(ModelApple::Big);
QString ModelApple::enumToString(AppleType apple)
{
int index = metaObject()->indexOfEnumerator("AppleType");
QMetaEnum metaEnum = metaObject()->enumerator(index);
return metaEnum.valueToKey(apple);
}

Related

QDataStream empty after call of QDataStream::writeRawData

I have a rather odd problem, using QDataStream, or at least it is odd to me, because I don't understand the behavior at all.
Of course my problem is from a big project, but I managed to reproduce that odd behavior with a minimal example, which I'll describe now.
I have two classes
a binary data reader Reader and
a binary data parser Parser.
The Reader reads data via a QTcpSocket, packs each received data chunk into a QByteArray and sends that array via Qt signal to Parser.
The Parser writes all received data chunks to its own QDataStream and shall parse packets from that stream afterwards.
The problem arises, when Parser writes the data from the received QByteArray to its QDataStream. The return value of QDataStream::writeRawData correctly returns the number of bytes written, but then QDataStream::atEnd returns true and QDataStream::device.bytesAvailable returns zero.
Why? Where is the data QDataStream::writeRawData claims to have written?
You can find the code at the and of this post.
Environment: Qt 5.9.1 (MSVC 2015, 32/64 bit) on Windows 7 Enterprise SP1 64 bit
Reader.h
#ifndef READER_H
#define READER_H
#include <QAbstractSocket>
#include <QByteArray>
#include <QDataStream>
#include <QHostAddress>
#include <QObject>
class Reader : public QObject
{
Q_OBJECT
public:
Reader(const QHostAddress ip, quint16 port);
virtual ~Reader();
signals:
void signalNewData(const QByteArray data);
private slots:
void slotOnReadyRead();
private:
QAbstractSocket *mSocket;
QDataStream mStream;
};
#endif // READER_H
Reader.cpp
#include "reader.h"
#include <QTcpSocket>
Reader::Reader(const QHostAddress ip, quint16 port)
: mSocket(new QTcpSocket(this))
, mStream()
{
mStream.setDevice(mSocket);
mStream.setVersion(QDataStream::Qt_5_9);
mStream.setByteOrder(QDataStream::LittleEndian);
connect(mSocket, &QIODevice::readyRead, this, &Reader::slotOnReadyRead);
mSocket->connectToHost(ip, port, QIODevice::ReadOnly);
}
Reader::~Reader()
{
mSocket->disconnectFromHost();
delete mSocket;
mSocket = nullptr;
}
void Reader::slotOnReadyRead()
{
mStream.startTransaction();
quint64 availableBytesForReading = mStream.device()->bytesAvailable();
QByteArray binaryDataBlock;
char *tmp = new char[availableBytesForReading];
mStream.readRawData(tmp, availableBytesForReading);
binaryDataBlock.append(tmp, availableBytesForReading);
delete[] tmp;
tmp = nullptr;
if (mStream.commitTransaction())
{
emit signalNewData(binaryDataBlock);
}
}
Parser.h
#ifndef PARSER_H
#define PARSER_H
#include <QByteArray>
#include <QDataStream>
#include <QObject>
class Parser : public QObject
{
Q_OBJECT
public:
Parser();
public slots:
void slotOnNewData(const QByteArray data);
private:
QDataStream mStream;
};
#endif // PARSER_H
Parser.cpp
#include "parser.h"
#include <QDebug>
Parser::Parser()
: mStream(new QByteArray(), QIODevice::ReadWrite)
{
mStream.setVersion(QDataStream::Qt_5_9);
mStream.setByteOrder(QDataStream::LittleEndian);
}
void Parser::slotOnNewData(const QByteArray data)
{
const char *tmp = data.constData();
int numberOfBytesWritten = mStream.writeRawData(tmp, data.length());
qDebug() << "numberOfBytesWritten:" << numberOfBytesWritten << endl;
qDebug() << "QDataStream::status():" << mStream.status() << endl;
qDebug() << "QDataStream::atEnd():" << mStream.atEnd() << endl;
qDebug() << "QDataStream::device.bytesAvailable():" << mStream.device()->bytesAvailable() << endl;
}
main.cpp
#include <QCoreApplication>
#include "reader.h"
#include "parser.h"
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
Reader *reader = new Reader(QHostAddress("<insert IP>"), <insertPort>);
Parser *parser = new Parser();
QObject::connect(&a, &QCoreApplication::aboutToQuit, reader, &QObject::deleteLater);
QObject::connect(&a, &QCoreApplication::aboutToQuit, parser, &QObject::deleteLater);
QObject::connect(reader, &Reader::signalNewData, parser, &Parser::slotOnNewData);
return a.exec();
}
delete.pro Yes, I called my minimal example project 'delete' :'D
QT += core network
QT -= gui
CONFIG += c++11
TARGET = delete
CONFIG += console
CONFIG -= app_bundle
TEMPLATE = app
SOURCES += main.cpp \
reader.cpp \
parser.cpp
# The following define makes your compiler emit warnings if you use
# any feature of Qt which as been marked deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS
# You can also make your code fail to compile if you use deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
HEADERS += \
reader.h \
parser.h
The problem is not that there is no data but that your current position is at the end of the data. Use device() to retrieve the QBuffer which it used to wrap your QByteArray and reset the position of that object.
mStream.device()->reset()

TeamSpeak SDK in Qt

I'm trying to use the TeamSpeak SDK for a personal project in Qt, when I use this code in the main it works fine
It compiles without problem. The problem is when I use it in Qt Mainwindow:
Mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <teamspeak/public_definitions.h>
#include <teamspeak/public_errors.h>
#include <teamspeak/serverlib_publicdefinitions.h>
#include <teamspeak/serverlib.h>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
private:
Ui::MainWindow *ui;
void onClientConnected(uint64 serverID, anyID clientID, uint64 channelID, unsigned int* removeClientError);
ServerLibFunctions funcs; // it's a struct that have pointer fucntions
};
#endif // MAINWINDOW_H
Mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
funcs.onClientConnected = onClientConnected; // error here
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::onClientConnected(uint64 serverID, anyID clientID, uint64 channelID, unsigned int* removeClientError) {
char* clientName;
unsigned int error;
/* Query client nickname */
if ((error = ts3server_getClientVariableAsString(serverID, clientID, CLIENT_NICKNAME, &clientName)) != ERROR_ok) {
char* errormsg;
if (ts3server_getGlobalErrorMessage(error, &errormsg) == ERROR_ok) {
printf("Error querying client nickname: %s\n", errormsg);
ts3server_freeMemory(errormsg);
}
return;
}
printf("Client '%s' joined channel %llu on virtual server %llu\n", clientName, (unsigned long long) channelID, (unsigned long long)serverID);
/* Example: Kick clients with nickname "BlockMe from server */
if (!strcmp(clientName, "BlockMe")) {
printf("Blocking bad client!\n");
*removeClientError = ERROR_client_not_logged_in; /* Give a reason */
}
}
I've commented on the line I got the error in Mainwindow.cpp
and the error:
cannot convert 'MainWindow::onClientConnected' from type 'void (MainWindow::)(uint64, anyID, uint64, unsigned int*) {aka void (MainWindow::)(long long unsigned int, short unsigned int, long long unsigned int, unsigned int*)}' to type 'void ()(uint64, anyID, uint64, unsigned int) {aka void ()(long long unsigned int, short unsigned int, long long unsigned int, unsigned int)}'
funcs.onClientConnected = onClientConnected;
^
I am using Windows 10 Mingw compiler Qt 5.6.1
how can i use this call back fucntion in oop c++
I solve my problem to use TeamSpeak in Qt I initialize the server in the main.cpp and assign all call back functions in the struct and now I can use any function of the server in the main window for example if I want to show the channels in a text edit i use the function of it in any c++ class or Qt Dialog and I can call it without problems
the code of the main.cpp
// put the fucntion of the call back here
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
char *version;
short abort = 0;
uint64 serverID;
unsigned int error;
int unknownInput = 0;
uint64* ids;
int i;
struct ServerLibFunctions funcs;
/* Initialize all callbacks with NULL */
memset(&funcs, 0, sizeof(struct ServerLibFunctions));
funcs.onClientConnected = onClientConnected;
funcs.onClientDisconnected = onClientDisconnected;
funcs.onClientMoved = onClientMoved;
funcs.onChannelCreated = onChannelCreated;
funcs.onChannelEdited = onChannelEdited;
funcs.onChannelDeleted = onChannelDeleted;
funcs.onServerTextMessageEvent = onServerTextMessageEvent;
funcs.onChannelTextMessageEvent = onChannelTextMessageEvent;
funcs.onUserLoggingMessageEvent = onUserLoggingMessageEvent;
funcs.onClientStartTalkingEvent = onClientStartTalkingEvent;
funcs.onClientStopTalkingEvent = onClientStopTalkingEvent;
funcs.onAccountingErrorEvent = onAccountingErrorEvent;
funcs.onCustomPacketEncryptEvent = nullptr;
funcs.onCustomPacketDecryptEvent = nullptr;
if((error = ts3server_initServerLib(&funcs, LogType_FILE | LogType_CONSOLE | LogType_USERLOGGING, NULL)) != ERROR_ok) {
char* errormsg;
if(ts3server_getGlobalErrorMessage(error, &errormsg) == ERROR_ok) {
printf("Error initialzing serverlib: %s\n", errormsg);
ts3server_freeMemory(errormsg);
}
return 1;
}
MainWindow w;
w.show();
return a.exec();
// use any function to edit server in any c++ class as show chan add chancel and so on
}
use all function to edit the server in any c++ class it will work and i think we don't need to initialize the server more than once in main and we don't need to but it in class and if I want to make a VoIP using Qt GUI we need only the server edit function if there's a better answer please post it Thanks
Edit
another solution is to initialize the struct with the call back functions in main and pass it in Mainwindow or any c++ class in the constructor and use it to initialize server lib of TeamSpeak
Your issue can be simulated with below simple code.
Based on my understanding the function you are trying to assign is a class specific member. So the compiler considers it as a signature mismatch when you are trying to assign.
You may need to write the required functionality in a non class member and then assign. (unless there is a way to allow this assignment).
Make the structure with function inputs as a friend of your functional class as shown below.
#include <iostream>
// common namespace
using namespace std;
//Structure with function pointers.
struct funcPtrStruct
{
public:
void (*func)(int a, float b);
};
//The non member function that address your functionality
void testFuncOne(int a ,float b)
{
//Do something
}
//Class implementation
class Test
{
public:
Test()
{
funcPtrStruct funPtrSt;
//func = &testFunc; //Here the error is shown " a value of type .....can not convert......"
funPtrSt.func = &testFuncOne; //This is working but it is not a class memeber.
}
private:
friend struct funcPtrStruct; //Make the structure of function pointers as your friend.
};
int main() {
return 0;
}

Function call missing argument list to create pointer

I tried to connect my app to OpenViBE through VRPN server. My app works well until I try to add code to connect my app to VRPN server.
My code looks like this:
MainWindow.c code:
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QtUiTools/QUiLoader>
#include <QFile>
#include <QMessageBox>
#include <QFileDialog>
#include <iostream>
using namespace std;
#include "vrpn_Analog.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
currentImage = 0;
labelSize = ui->label_2->size();
createActions();
openFileDialog();
}
void MainWindow::checkChannels()
{
vrpn_Analog_Remote *vrpnAnalog = new vrpn_Analog_Remote("Mouse0#localhost");
vrpnAnalog->register_change_handler( 0, handle_analog );
}
void VRPN_CALLBACK MainWindow::handle_analog( void* userData, const vrpn_ANALOGCB a )
{
int nbChannels = a.num_channel;
cout << "Analog : ";
for( int i=0; i < a.num_channel; i++ )
{
cout << a.channel[i] << " ";
}
cout << endl;
}
MainWindow.h code:
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QFileInfoList>
#include "vrpn_Analog.h"
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
protected:
void resizeEvent(QResizeEvent *);
private slots:
void openFileDialog();
private:
void checkChannels();
void VRPN_CALLBACK handle_analog( void* userData, const vrpn_ANALOGCB a );
};
#endif // MAINWINDOW_H
With this code, when I try to run my app I get:
error: C3867: 'MainWindow::handle_analog': function call missing argument list; use '&MainWindow::handle_analog' to create a pointer to member
I try to edit code by error advice, but I get another error:
error: C2664: 'vrpn_Analog_Remote::register_change_handler' : cannot convert parameter 2 from 'void (__stdcall MainWindow::* )(void *,const vrpn_ANALOGCB)' to 'vrpn_ANALOGCHANGEHANDLER'
There is no context in which this conversion is possible
I search around, but I don't find any usable solution.
Methods checkChannels and handle_analog I "copy" from this code, where all works fine:
#include <QtCore/QCoreApplication>
#include <iostream>
#include "vrpn_Analog.h"
void VRPN_CALLBACK vrpn_analog_callback(void* user_data, vrpn_ANALOGCB analog)
{
for (int i = 0; i < analog.num_channel; i++)
{
if (analog.channel[i] > 0)
{
std::cout << "Analog Channel : " << i << " / Analog Value : " << analog.channel[i] << std::endl;
}
}
}
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
/* flag used to stop the program execution */
bool running = true;
/* VRPN Analog object */
vrpn_Analog_Remote* VRPNAnalog;
/* Binding of the VRPN Analog to a callback */
VRPNAnalog = new vrpn_Analog_Remote("openvibe_vrpn_analog#localhost");
VRPNAnalog->register_change_handler(NULL, vrpn_analog_callback);
/* The main loop of the program, each VRPN object must be called in order to process data */
while (running)
{
VRPNAnalog->mainloop();
}
return 0;
return a.exec();
}
Where I'm doing mistake? Thanks for all replies.
I had a similar error in Visual Studio: "function call missing argument list; use '&className::functionName' to create a pointer to member"..
I was just missing the parenthesis when calling the getter, so className.get_variable_a()
The error message tells you that the argument you provided does not match vrpn_ANALOGCHANGEHANDLER. You didn't show the definition of that. I checked online and it suggested
typedef void (*vrpn_ANALOGCHANGEHANDLER)(void *userdata, const vrpn_ANALOGCB info);
so I'm going with that.
Your code attempts to pass a pointer-to-member-function, which cannot be converted to a pointer-to-function. This is because a pointer-to-member-function can only be called on an object, so it wouldn't know what object to use.
If you look at the code you are "copying off", you will see that vrpn_analog_callback is a free function. However in your code it is a member function. You need to change your code so that the callback is a free function (or a static member function).
If your intent is that the callback should call the member function on the same MainWindow object that you are registering the handler on, then do this:
// In MainWindow's class definition, add this:
static void VRPN_CALLBACK cb_handle_analog( void* userData, const vrpn_ANALOGCB a )
{
static_cast<MainWindow *>(userData)->handle_analog(NULL, a);
}
// In checkChannels()
vrpnAnalog->register_change_handler( this, cb_handle_analog );
You cannot directly call a non-static class method using this callback. This is because the method is expecting to be called with the class this pointer.
If you don't need any data from your class, then just make the method static. If you do need data from the class, you can make a static "stub" that takes the class pointer in the userData parameter and then calls the original method. Something like:
Declaration:
static void VRPN_CALLBACK handle_analog_stub( void* userData, const vrpn_ANALOGCB a );
Definition
void VRPN_CALLBACK MainWindow::handle_analog_stub( void* userData, const vrpn_ANALOGCB a )
{
MainWindow *mainWindow = static_cast<MainWindow*>(userData);
mainWindow->handle_analog(NULL, a);
}
Then when you call the function use:
vrpnAnalog->register_change_handler( this, handle_analog_stub );
(Updated to static_cast to pointer, thanks rpavlik)

accessing a static variable in C++

I'm using Qt Creator to try and create a basic calculator app. I was trying to test out the first few methods and had to write one in order to make the rest of the coding easier, however, that method isn't compiling. I'm trying to access a static variable that holds the current value of the Calculator screen, but it keeps giving me:
C:\Users\****\Documents\Qt Projects\SimpleCalculator\calculator.cpp:15: error: C2248: 'Calculator::currVal' : cannot access private member declared in class 'Calculator'
Here is the Calculator.cpp
#include "calculator.h"
#include <QLCDNumber>
Calculator::Calculator(QWidget *parent) :
QWidget(parent), ui(new Ui::Calculator)
{
ans = 0;
currVal = 0;
setupUi(this);
}
//problem method
QString getNewVal(qint64 nextDig)
{
//--------------------------------------------
long long int val = Calculator::currVal;//this is where I am trying to access the variable
//--------------------------------------------
if(nextDig==0)
{
if(val > 0)
{
QString str = QString::number(val);
str.append("0");
return str;
}
else
{
return "0";
}
}
else if(nextDig==1)
{
QString str = QString::number(val);
str.append("1");
return str;
}
return NULL;
}
void Calculator::on_Zero_clicked()
{
ui->Display->display(getNewVal(0));
currVal = ui->Display->intValue();
}
void Calculator::on_One_clicked()
{
}
Here is the header file:
#ifndef CALCULATOR_H
#define CALCULATOR_H
#include "ui_calculator.h"
class Calculator : public QWidget, private Ui::Calculator
{
Q_OBJECT
public:
Calculator(QWidget *parent = 0);
private slots:
void on_Zero_clicked();
void on_One_clicked();
private:
Ui::Calculator *ui;
QString getNewVal(quint64);
static long long int ans;
static long long int currVal;
};
long long int Calculator::ans = 0;
long long int Calculator::currVal = 0;
#endif
// CALCULATOR_H
Calculator::currVal;//this is where I am trying to access the variable
Won't work because the value is declared private (as indicated by the warning) in your header:
private:
Ui::Calculator *ui;
QString getNewVal(quint64);
static long long int ans;
**static long long int currVal;**
and your function:
QString getNewVal(qint64 nextDig)
is not part of the class.
This
static long long int currVal;
is private!
try:
public:
static long long int currVal;
or create a getter method for that.
also you can make the getNewVal a friend function of your class:
public:
friend QString ::getNewVal(qint64 nextDig);
You need to specify that getNewVal belongs to Calculator
QString Calculator::getNewVal(quint64 nextDig)
// ^^^^^^^^^^ ^
// This was missing |
// |
// Add 'u' above to match the declaration
Otherwise, C++ thinks that this is a free-standing function (despite the fact that you have declared a member function with the same name inside Calculator).
You also need to move the two definitions
long long int Calculator::ans = 0;
long long int Calculator::currVal = 0;
from the header file to the implementation file.

How to use c++ std complex numbers in QtScript

I try to find out how to use complex numbers in QtScripts such that slots defined with complex arguments can be called from a QtScript. Also basic algebra (+,-,exp, ... ) of complex-numbers should be accessible to the user from the script.
Just for illustration want I want to call is:
#include<complex>
typedef complex<double> Complex;
class MyCppClass : public QObject
{
Q_OBJECT
public:
...
public slots:
void mySignal(Complex rCValue); !! <<== should be callable from QtScript
...
}
Any ideas? Thx!
I think you must implement complex algebra in QtScript (something like http://examples.oreilly.com/9781565923928/text/8-6.txt) and then modify mySignal to accept an object like this.
It's not the final answer ... since as indicated above the operators +,- and * cannot be used for Complex quantities on the javascript side. But for those interested I'd like to share the following code pieces, which allow to trigger slots with complex arguments.
test.h:
#include <QtCore>
#include <QtScript>
#include <complex>
#include <iostream>
using namespace std;
typedef complex<double> Complex;
Q_DECLARE_METATYPE(Complex)
class TestClass : public QObject
{
Q_OBJECT
public:
TestClass() : QObject() {};
public slots:
void TestOutput(Complex rValue);
};
test.cpp:
#include "test.h"
void TestClass::TestOutput(Complex rValue)
{
cout << "received value "<< rValue << endl;
}
main.cpp:
#include "test.h"
QScriptValue toScriptValue(QScriptEngine *eng, const Complex& rValue)
{
QScriptValue obj = eng->newObject();
obj.setProperty("re",real(rValue));
obj.setProperty("im",imag(rValue));
return obj;
}
void fromScriptValue(const QScriptValue &obj, Complex& rValue)
{
double re=obj.property("re").toNumber();
double im=obj.property("im").toNumber();
rValue=Complex(re,im);
}
QScriptValue constructComplex(QScriptContext *context, QScriptEngine *engine)
{
Complex complex=Complex(2,1);
return engine->toScriptValue(complex);
}
int main(int argc, char *argv[])
{
QCoreApplication app(argc, argv);
QScriptEngine eng;
// register our custom type
qScriptRegisterMetaType<Complex>(&eng, toScriptValue, fromScriptValue);
TestClass *test=new TestClass;
QObject *someObject = (QObject*)test;
QScriptValue objectValue = eng.newQObject(someObject);
eng.globalObject().setProperty("myObject", objectValue);
QScriptValue val = eng.evaluate("function Complex(real, imaginary) { this.re = real; this.im = imaginary;}; cadd = function (a, b) {return new Complex(a.re + b.re, a.im + b.im);};");
val = eng.evaluate("my_complex=new Complex(8,1); my_comp=new Complex(2,9); my_c=cadd(my_comp,my_complex);");
cout << "script"<< val.toString().toStdString() << endl;
Complex cval = qscriptvalue_cast<Complex>(val);
cout << "qscriptvalue_cast : "<< cval << endl;
val = eng.evaluate("myObject.TestOutput(my_c)");
return 0;
}