ورود

View Full Version : دسترسی به کنترل های QML از c++



ali_72
سه شنبه 25 اسفند 1394, 02:26 صبح
سلام
من از این کد برای فراخوانی تابع از c++ در main.cpp استفاده میکنم ولی خیلی درست و خوب کار میکنه.

int main(int argc, char *argv[]){
QApplication app(argc, argv);

QQmlApplicationEngine engine;
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));

QObject * object = engine.rootObjects().value(0);

QVariant returnedValue;
QVariant msg = "Hello from C++";
QMetaObject::invokeMethod(object, "myQmlFunction",
Q_RETURN_ARG(QVariant, returnedValue),
Q_ARG(QVariant, msg));

return app.exec(); }

اما در سایر کلاس ها من چطور میتونم این دسترسی را داشته باشم؟ این کد در سایر کلاس ها ی c++ کار نمیکنه.
مثلا من یه کلاس برای ارتباط با پورت سریال ساختم
و میخوام مثلا در صورت دریافت داده خاص یه سری کنترل ها غیرفعال شه یا فعال شه یا دیالوگی همراه با پیام خاصی نمایش بدم ایکون کنترل ها تغییر کنه و ....

برای مثال:

void MySerialPort::readData(){
QByteArray data = serial->readAll();
if(data[0]=='0') // For example
Show qml dialog
if(data[1]=='1') // For example
disable GroupBox

...
... }

فعلا این کار رو با تعریف پراپرتی انجام دادم ولی تعداد پراپرتی ها خیلی خیلی زیاد شده
ایا روش بهتری وجود نداره؟

ravaei
دوشنبه 09 فروردین 1395, 22:33 عصر
سلام
من از این کد برای فراخوانی تابع از C++‎ در main.cpp استفاده میکنم ولی خیلی درست و خوب کار میکنه.

int main(int argc, char *argv[]){
QApplication app(argc, argv);

QQmlApplicationEngine engine;
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));

QObject * object = engine.rootObjects().value(0);

QVariant returnedValue;
QVariant msg = "Hello from C++‎";
QMetaObject::invokeMethod(object, "myQmlFunction",
Q_RETURN_ARG(QVariant, returnedValue),
Q_ARG(QVariant, msg));

return app.exec(); }

اما در سایر کلاس ها من چطور میتونم این دسترسی را داشته باشم؟ این کد در سایر کلاس ها ی C++‎ کار نمیکنه.
مثلا من یه کلاس برای ارتباط با پورت سریال ساختم
و میخوام مثلا در صورت دریافت داده خاص یه سری کنترل ها غیرفعال شه یا فعال شه یا دیالوگی همراه با پیام خاصی نمایش بدم ایکون کنترل ها تغییر کنه و ....

برای مثال:

void MySerialPort::readData(){
QByteArray data = serial->readAll();
if(data[0]=='0') // For example
Show qml dialog
if(data[1]=='1') // For example
disable GroupBox

...
... }

فعلا این کار رو با تعریف پراپرتی انجام دادم ولی تعداد پراپرتی ها خیلی خیلی زیاد شده
ایا روش بهتری وجود نداره؟

درود ...

چیزی که من متوجه شدم اینه که شما می خواین یک backEnd با ++C داشته باشید و userInterface رو با Qml ایجاد کنید اگه اینطوره پیشنهاده من به شما اینه که به جای اینکه بخواین از سمته++C به کنترل های Qml دسترسی داشته باشین یه سری کلاس سمت ++C ایجاد کنید و اونارو پورت کنید سمت Qml !!!


به عنوان مثال


//.h
#include <QObject>

class Serial:public QObject{

Q_OBJECT
public:
Serial();
Q_INVOKABLE bool GetSerial();


};


//.cpp

bool serial::GetSerial(){

QByteArray data = serial->readAll();
if(data[0]=='0') // For example
return true;
if(data[1]=='1') // For example
return false;
}




//main.cpp

#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQmlComponent>
#include <QObject>
#include <QtQml>


int main(int argc, char *argv[])
{
QGuiApplication app(argc, argv);

qmlRegisterType<Database>("serial", 1,0, "MySerialClass");


QQmlApplicationEngine engine;
engine.load(QUrl(QStringLiteral("qrc:///main.qml")));

return app.exec();
}



//Qml side Just an Example


import QtQuick 2.5
import serial 1.0


Window{
id:Example
visible:true
width:100
height:100

MySerialClass{
id:serial
}

component.oncomplete{
if(serial.GetSerial)
ExampleRectangle.color="green"
else{
ExampleRectangle.color="Red"
ExampleRectangle.enable=false
}
}




rectangle{
id:ExampleRectangle
}


}





البته این مثال رو تو notepad نوشتم تست نکردم و صرفا برای توضیح روش کار بود ...