QtQuick,动态图像和C ++ [英] QtQuick, Dynamic Images and C++

查看:125
本文介绍了QtQuick,动态图像和C ++的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是Qt的新用户,以及我在 qt-project.org 等地; QtQuick似乎是一个有吸引力的选择,因为它有能力在指针和触摸设备上工作。我的问题是让它与c ++工作良好。



我决定在Hello World之后写下Conway的生命之游戏的变种作为下一步。我对如何获得board - 一个[height] [width] [bytes-per-pixel]数组的字符 - 集成到场景图中彻底神秘。



基本上,过程是LifeBoard遍历其规则并更新char * / image。我有这个简单的QML:

  ::: QML 
ApplicationWindow {
id:life_app_window
visible:true
title:qsTr(Life)

menuBar:MenuBar {
Menu {
title:qsTr(File)
MenuItem {
text:qsTr(Quit)
onTriggered:Qt.quit();
}
}
}

toolBar:ToolBar {
id:lifeToolBar;
ToolButton {
id:toolButtonQuit
text:qsTr(Quit)
onClicked:Qt.quit()
}
ToolButton {
id:toolButtonStop
text:qsTr(Stop)
enabled:false
// onClicked:
}
ToolButton {
id:toolButtonStart
text:qsTr(Start)
enabled:true
// onClicked://开始生活。
}
ToolButton {
id:toolButtonReset
text:qsTr(Stop)
// onClicked://重置生命。
}
}

Flow {
id:flow1
anchors.fill:parent
// *****
// WHAT GOES HERE
// *****
}

statusBar:StatusBar {
enabled:false
Text {
//从迭代次数得到我
text:qsTr(Iterations。)
}
}
}
pre>

我想要来自类似api的类的图像,如下:

  class Life {
public:
QImage getImage(){}
//或
char * getPixels(int h,int w,QImage :: Format_ARGB8888 ){}
}



我没有线索,通过教程的小时没有帮助。如何将一个char *图像在c ++中链接到???在QML中,以便QML可以启动/停止生命周期循环,并使生命周期循环并更新字符数组,并通知QML重绘它?






注意:我已经查看了子类化QQuickImageProvider基于信息此处。这种方法的问题是,我看不到如何让c ++驱动屏幕上的图像。我希望将控制从QML传递到c ++,并让c ++告诉QML什么时候用更改的图像更新显示。有这种方法的解决方案吗?或者另一种方法。

解决方案

第一种方法是创建一个 Rectangle 用于QML中的每个游戏像素,这可能适合8x8板,但不适用于100x100板,因为您需要为每个像素手动写入QML代码。



因此,我会去用C ++创建的并暴露于QML的图像。您可以通过图片提供者呼叫他们,以允许异步加载。让生活仅执行逻辑。



从QML中调用该图像,如下所示:

 图片{
id:board
source:image:// gameoflife / board
height:400
width:400
}

现在 code>是图像提供程序的名称, board 所谓的 id 以后可以使用。



中注册 gameoflife main.cpp

  LifeImageProvider * lifeIP = new LifeImageProvider(life); 
engine.addImageProvider(gameoflife,lifeIP);

其中引擎是您的主要<$ c游戏引擎的实例$ c> QQmlApplicationEngine 生活



LifeImageProvider 是您创建pixeldata的课程。以某种方式开始像

 类LifeImageProvider:public QQuickImageProvider 
{
public:
LifeImageProvider * myLifeEngine);
QPixmap requestPixmap(const QString& id,QSize * size,const QSize& requestedSize);

private:
Life * myLifeEngine_;
};

重要的方法是 requestPixmap ,它是从QML调用的。



生活发送 stateChanged时刷新游戏面板()信号,将生命作为QML的全局对象:

  context-> setContextProperty(life,& life); 

您可以将信号绑定到QML

 图片{
id:board
source:image:// gameoflife / board
height:400
width:400
}

Connections {
target:life
onStateChanged:{
board.source =image:// gameoflife / board? + Math.random()
//更改URL以刷新图像。添加随机URL部分以避免缓存
}
}


I'm new to Qt, and from what I've read on qt-project.org and other places; QtQuick seems like an attractive option because of its ability to work on both pointer and touch based devices. My problem is getting it to work well with c++.

I decided to write a variant of Conway's Game of Life as a next step after "Hello World". I am thoroughly mystified as to how to get the "board" -- a [height][width][bytes-per-pixel] array of char -- integrated into the scene graph.

Basically, the process is that the "LifeBoard" iterates through its rules and updates the char*/image. I've got this simple QML:

:::QML
ApplicationWindow {
    id:         life_app_window
    visible:    true
    title: qsTr("Life")

    menuBar: MenuBar {
        Menu {
            title: qsTr("File")
            MenuItem {
                text: qsTr("Quit")
                onTriggered: Qt.quit();
            }
        }
    }

    toolBar: ToolBar {
        id: lifeToolBar;
        ToolButton {
            id: toolButtonQuit
            text: qsTr("Quit")
            onClicked: Qt.quit()
        }
        ToolButton {
            id: toolButtonStop
            text: qsTr("Stop")
            enabled: false
            //onClicked:
        }
        ToolButton {
            id: toolButtonStart
            text: qsTr("Start")
            enabled: true
            //onClicked: //Start life.
        }
        ToolButton {
            id: toolButtonReset
            text: qsTr("Stop")
           // onClicked: //Reset life.
        }
    }

    Flow {
        id: flow1
        anchors.fill: parent
        //*****
        // WHAT GOES HERE
        //*****
    }

    statusBar: StatusBar {
        enabled: false
        Text {
            // Get me from number of iterations
            text: qsTr("Iterations.")
        }
    }
}

I want to image to come from a class with a api kinda like this:

class Life {
    public:
        QImage getImage() {}
        // Or
        char* getPixels(int h, int w, QImage::Format_ARGB8888) {}
}

I have no clue, and hours wading through tutorials did not help. How does one link a char* image in c++ to a ??? in QML so that the QML can start/stop the "Life" loop and so that the "Life" loop and update the char array and notify QML to redraw it?


Note: I've looked at subclassing QQuickImageProvider based on the info here. The problem with this approach is that I cannot see how to let c++ "drive" the on screen image. I wish to pass control from QML to c++ and let c++ tell QML when to update the display with the changed image. Is there a solution with this approach? Or another approach entirely.

解决方案

First way to do that would be creating a Rectangle for each game pixel in QML, which might be fancy for a 8x8 board, but not for a 100x100 board, since you need to write the QML code manually for each pixel.

Thus I'd go for images created in C++ and exposed to QML. You call them via an image provider to allow asynchronous loading. Let Life do the logic only.

The image is called from QML like this:

Image {
    id: board
    source: "image://gameoflife/board"
    height: 400
    width: 400
}

Now gameoflife is the name of the image provider and board the so-called id you can use later.

Register gameoflife in you main.cpp

LifeImageProvider *lifeIP = new LifeImageProvider(life);
engine.addImageProvider("gameoflife", lifeIP);

where engine is your main QQmlApplicationEngine and life an instance of your Life game engine.

LifeImageProvider is your class to create pixeldata. Starts somehow like

class LifeImageProvider : public QQuickImageProvider
{
public:
    LifeImageProvider(Life *myLifeEngine);
    QPixmap requestPixmap(const QString &id, QSize *size, const QSize &requestedSize);

private:
    Life *myLifeEngine_;
};

The important method is requestPixmap, which is called from QML. You need to implement it.

To refresh the game board when Life sends a stateChanged() signal, expose life as a global object to QML:

context->setContextProperty("life", &life);

You can bind the signal to QML

Image {
    id: board
    source: "image://gameoflife/board"
    height: 400
    width: 400
}

Connections {
    target: life
    onStateChanged: {
        board.source = "image://gameoflife/board?" + Math.random()
        // change URL to refresh image. Add random URL part to avoid caching
    }
}

这篇关于QtQuick,动态图像和C ++的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆