C++ Q_属性变量的动态赋值
情况就是这样C++ Q_属性变量的动态赋值,c++,qt,qml,C++,Qt,Qml,情况就是这样 QQmlApplicationEngine* engine; QQmlContext* ctxt; class Fruit: public QObject { Q_OBJECT Q_PROPERTY(QString type MEMBER m_type NOTIFY fruitChanged) private: QString m_type; public: virtual void initFruit() = 0; void star
QQmlApplicationEngine* engine;
QQmlContext* ctxt;
class Fruit: public QObject
{
Q_OBJECT
Q_PROPERTY(QString type MEMBER m_type NOTIFY fruitChanged)
private:
QString m_type;
public:
virtual void initFruit() = 0;
void startEating(){
initFruit();
ctxt->setContextProperty("fruit", this);
engine->load(QUrl(QLatin1String("qrc:/qml/main.qml")));
app.exec();
engine->quit();
engine->deleteLater();
}
void setType(QString fruit){
m_type = fruit;
emit fruitChanged();
}
signals:
fruitChanged();
};
class Apple:public Fruit{
public:
explicit Appl(QObject *parent = nullptr);
void initFruit(){
Slice slice = new Slice(); // some other class
ctxt->setContextProperty("slice", slice);
}
};
class Banana:public Fruit{
public:
explicit Banana(QObject *parent = nullptr);
void initFruit(){
Peel peel = new Peel(); // some other class
ctxt->setContextProperty("peel", peel);
}
};
class Peel: public QObject
{
Q_OBJECT
Q_PROPERTY(QString color MEMBER m_peelColor NOTIFY peelChanged)
private:
QString m_peelColor;
signals:
void peelChanged();
public:
void someFunction(QString peelColor){
m_peelColor = peelColor;
emit peelChanged();
}
}
class Slice: public QObject
{
Q_OBJECT
Q_PROPERTY(int number MEMBER m_slices NOTIFY sliceChanged)
private:
QString m_slices;
signals:
void sliceChanged();
public:
void someFunction(QString slices){
m_slices = slices;
emit sliceChanged();
}
}
int main(int argc, char *argv[])
{
QGuiApplication app(argc, argv);
Fruit *fruit;
if (argv[1] == "Apple"){
fruit = new Apple();
}
else if (argv[1] == "Banana"){
fruit = new Banana();
}
engine = new QQmlApplicationEngine();
ctxt = engine->rootContext();
fruit->setType(argv[1].toString());
fruit->startEating();
}
然后在main.qml中
...
Rectangle{
Text {
text: { // I want to remove this if else statement
if(fruit.type == "Apple")
slice.number
else if(fruit.type == "Banana")
peel.color
}
}
}
您可以想象,随着水果数量的增加,main.qml中的if-else语句会变得多大。因此,我想知道是否有一种不同的方法来处理这样的场景,在这种情况下,我可以以某种方式将qml中的文本指定为一个值,然后它动态加载正确的后端属性 与其在initFruit方法中注册新的数据类型并使用全局变量,不如创建一个提供程序类:
#包括
#包括
#包括
#包括
类别:公共QObject
{
Q_对象
公众:
虚拟Q_可调用的QString name()=0;
};
苹果类:公众水果{
公众:
QString名称(){
返回“苹果”;
}
};
香蕉类:公共水果{
公众:
QString名称(){
返回“香蕉”;
}
};
类提供者:公共QObject{
Q_对象
Q_属性(水果*水果读取水果写入设置水果通知水果更改)
公众:
水果提供者(QObject*parent=nullptr):QObject(parent){}
水果常数{
返回m_水果。获取();
}
公众时段:
空果(果*果){
m_水果。重置(水果);
发出改变的声音();
}
Q_信号:
无效,无效();
私人:
qscopedpointermu水果;
};
int main(int argc,char*argv[]){
QCoreApplication::setAttribute(Qt::AA_enableHighdDiscaling);
QGUI应用程序应用程序(argc、argv);
水果供应商;
如果(argc<1){
返回-1;
}
如果(std::strcmp(argv[1],“Apple”)==0){
provider.setFruit(新苹果());
}
else if(std::strcmp(argv[1],“Banana”)==0){
provider.setFruit(新香蕉());
}
qqmlaplicationengine;
engine.rootContext()->setContextProperty(“提供者”、&provider);
const-QUrl-url(QStringLiteral(“qrc:/main.qml”);
QObject::connect(&engine),&QQmlApplicationEngine::objectCreated,
&应用程序,[url](QObject*obj,const-quorl和objUrl){
如果(!obj&&url==objUrl)
QCoreApplication::退出(-1);
},Qt::QueuedConnection);
引擎加载(url);
返回app.exec();
}
#包括“main.moc”
更新:
正如我在评论中指出的,消除if-elseif-else的想法是为了标准化对属性的访问,对于水果,您可以使用提供者。对于“数字”和“颜色”属性,您可以创建一个通用属性,该属性在每次修改其他属性时都会更新,并使用该属性访问QML中的信息
#包括
#包括
#包括
#包括
类:公共QObject{
Q_对象
Q_属性(QString颜色成员m_peelColor NOTIFY peelChanged)
私人:
QString m_peelColor;
信号:
void peelChanged();
公众:
void someFunction(QString peelColor){
m_peelColor=peelColor;
发射peelChanged();
}
};
类切片:公共QObject{
Q_对象
Q_属性(整数成员m_已更改)
私人:
int m_切片;
信号:
void sliceChanged();
公众:
void函数(int切片){
m_切片=切片;
发射切片改变();
}
};
类别:公共QObject{
Q_对象
Q_属性(QVariant公共成员m_公共通知公共更改)
公众:
无效开始测试(){
initFruit();
}
QVariant common()常量{
返回m_common;
}
Q_信号:
void commonChanged();
受保护的:
虚拟void initFruit()=0;
void setCommon(QVariant common){
m_公共=公共;
emit commonChanged();
}
私人:
qm_公共变量;
};
苹果类:公众水果{
公众:
虚无的果实(){
重置(新切片());
切片->函数(100);
setCommon(切片->属性(“编号”);
连接(slice.get(),&slice::sliceChanged,[this](){
setCommon(切片->属性(“编号”);
});
}
私人:
QScopedPointer切片;
};
香蕉类:公共水果{
公众:
虚无的果实(){
剥离。重置(新剥离());
剥离->某些功能(“红色”);
setCommon(剥离->属性(“颜色”);
连接(peel.get(),&peel::peelChanged,[this](){
setCommon(剥离->属性(“颜色”);
});
}
私人:
QScopedPointer果皮;
};
类提供者:公共QObject{
Q_对象
Q_属性(水果*水果读取水果写入设置水果通知水果更改)
公众:
水果常数{
返回m_水果。获取();
}
公众时段:
空果(果*果){
m_水果。重置(水果);
发出改变的声音();
}
Q_信号:
无效,无效();
私人:
qscopedpointermu水果;
};
int main(int argc,char*argv[]){
QCoreApplication::setAttribute(Qt::AA_enableHighdDiscaling);
QGUI应用程序应用程序(argc、argv);
水果供应商;
如果(argc<1){
返回-1;
}
如果(std::strcmp(argv[1],“Apple”)==0){
provider.setFruit(新苹果());
}
else if(std::strcmp(argv[1],“Banana”)==0){
provider.setFruit(新香蕉());
}
qqmlaplicationengine;
engine.rootContext()->setContextProperty(“提供者”、&provider);
const-QUrl-url(QStringLiteral(“qrc:/main.qml”);
QObject::connect(&engine),&QQmlApplicationEngine::objectCreated,
&应用程序,[url](QObject*obj,const-quorl和objUrl){
如果(!obj&&url==objUrl)
QCoreApplication::退出(-1);
},Qt::QueuedConnection);
引擎加载(url);
provider.fruit()->startEating();
返回app.exec();
}
#包括“main.moc”
打字错误:更改<代码>更改代码>到<代码>已更改()谢谢你的回答。但我还有一个问题。“剥”或“切片”课程怎么样?如果我希望文本是peel.color(如果是香蕉)或slice.size(如果是苹果),该怎么办?只有香蕉有皮,只有苹果有片…@Gebre根据你的片和皮,他们有相同的“某物”属性,现在你指出
Text{
text: provider.fruit.name()
}
Text{
text: provider.fruit.common
}