QtQuick,动态图像和C++

jus*_*ane 5 c++ qml qt-quick qt5

我是Qt的新手,也是我在qt-project.org和其他地方读过的内容.QtQuick似乎是一个很有吸引力的选择,因为它能够在指针和触摸设备上工作.我的问题是让它与c ++一起使用.

在"Hello World"之后,我决定写一个Conway的生命游戏变体作为下一步.关于如何获得"板" - 一个[高度] [宽度] [字节每像素] char数组 - 我已经完全神秘化了 - 集成到场景图中.

基本上,过程是"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: //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.")
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

我想要形象来自一个类似api的类:

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

我没有任何线索,并且通过教程的时间没有帮助.如何将c ++中的char*图像链接到??? 在QML中,QML可以启动/停止"Life"循环,以便"Life"循环并更新char数组并通知QML重绘它?


注意:我已经根据这里的信息查看了子类化QQuickImageProvider .这种方法的问题在于我无法看到如何让c ++"驱动"屏幕上的图像.我希望将控制从QML传递给c ++,让c ++告诉QML何时用更改的图像更新显示.这种方法有解决方案吗?或完全是另一种方法.

Sim*_*rta 7

第一种方法是为QML中的每个游戏像素创建一个矩形,这对于8x8板可能很奇特,但对于100x100板则不行,因为您需要为每个像素手动编写QML代码.

因此,我会选择用C++创建并暴露给QML的图像.您可以通过映像提供程序调用它们以允许异步加载.我们Life只做逻辑.

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

Image {
    id: board
    source: "image://gameoflife/board"
    height: 400
    width: 400
}
Run Code Online (Sandbox Code Playgroud)

现在gameoflife是图像提供者的名称,您可以在以后使用board所谓的名称id.

注册gameoflifemain.cpp

LifeImageProvider *lifeIP = new LifeImageProvider(life);
engine.addImageProvider("gameoflife", lifeIP);
Run Code Online (Sandbox Code Playgroud)

engine你的主要QQmlApplicationEnginelife你的Life游戏引擎的实例在哪里.

LifeImageProvider是你的类创建pixeldata.开始有点像

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

private:
    Life *myLifeEngine_;
};
Run Code Online (Sandbox Code Playgroud)

重要的方法是requestPixmap,它是从QML调用的.你需要实现它.

要在Life发送stateChanged()信号时刷新游戏板,请将其life作为全局对象公开给QML:

context->setContextProperty("life", &life);
Run Code Online (Sandbox Code Playgroud)

您可以将信号绑定到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
    }
}
Run Code Online (Sandbox Code Playgroud)