将具有多种状态的 QtQuick 项目保存到 .png 文件

Posted

技术标签:

【中文标题】将具有多种状态的 QtQuick 项目保存到 .png 文件【英文标题】:Saving QtQuick Items with multiple states to .png files 【发布时间】:2018-12-30 17:54:44 【问题描述】:

我正在尝试将具有多个状态的视觉项目保存为 .png 图像(每个状态一个 png)

我在 onStateChanged 信号处理程序中调用项目的 grabToImage() 方法,但图像仅在最后一次状态更改发生后保存,仅创建一个与项目的最后设置状态相对应的图像。

我也尝试在 python 端调用 saveToFile() 但这会导致运行时错误(请参阅 python 代码中的 cmets)

grab_states.py

from PySide2.QtCore import QUrl
from PySide2.QtWidgets import QApplication
from PySide2.QtQuick import QQuickView


app = QApplication([])

view = QQuickView()
view.setSource(QUrl('grab_states.qml'))
view.show()

rect = view.rootObject()
rect.setState('off')
rect.setState('on')

# RuntimeError: Internal C++ object (PySide2.QtQuick.QQuickItemGrabResult) already deleted.
# rect.grabToImage().data().saveToFile(rect.property('state') + ".png")

app.exec_()

grab_states.qml

import QtQuick 2.0

Rectangle 
  id: rect
  width: 100
  height: 100

  color: "black"

  states: [
      State name: "off"; PropertyChangestarget: rect; color: "red",
      State name: "on";  PropertyChangestarget: rect; color: "green"
  ]

  onStateChanged: 
    print('stateChaged: ' + state)
    rect.grabToImage(function(result)
      print("saveToFile: " + rect.state);
      result.saveToFile(state + '.png');
      
    )
  

saveToFile 函数按预期调用了两次,但只是在所有状态更改发生之后,所以我只得到一个显示最后一个状态的图像并覆盖第一个图像。如果我使用不同的文件名来防止覆盖,那么我会得到两张图像,都显示最终状态。

如何为项目的每个状态保存对应的图像?

【问题讨论】:

这可能会让你感兴趣github.com/benlau/sparkqml 【参考方案1】:

您有 2 个错误:

您正在更改您的状态,但没有确保您已经保存了图像。

通过上述操作,grabToImage中state的值会更新,并指向之前的状态。

在这两种情况下,解决方案都是确保图像已保存以更改状态。综合以上情况,解决方案如下:

*.py

from PySide2 import QtCore, QtGui, QtQuick

if __name__ == '__main__':
    import sys
    app = QtGui.QGuiApplication(sys.argv)
    view = QtQuick.QQuickView()
    view.setSource(QtCore.QUrl('grab_states.qml'))
    view.show()
    rect = view.rootObject()
    rect.setProperty("currentIndex", 0)
    sys.exit(app.exec_())

*.qml

import QtQuick 2.0

Rectangle 
    id: rect
    width: 100
    height: 100
    color: "black"
    property int currentIndex: -1
    onCurrentIndexChanged: if(currentIndex >= 0 && currentIndex < states.length) state = states[currentIndex].name
    states: [
        State name: "off"; PropertyChangestarget: rect; color: "red",
        State name: "on";  PropertyChangestarget: rect; color: "green"
    ]

    onStateChanged: 
        rect.grabToImage(function(result)
            result.saveToFile(state + ".png");
            currentIndex+= 1;
            console.log(filename);
        )
    

【讨论】:

以上是关于将具有多种状态的 QtQuick 项目保存到 .png 文件的主要内容,如果未能解决你的问题,请参考以下文章

如何在未聚焦的 QtQuick 项目中接收键盘事件?

具有多种状态的 Pygame 动画

使用jQuery将具有特定类的每个div的名称保存到变量中

未安装错误模块“QtQuick.Dialogs”

通过将新项目保存到具有继承的过滤获取请求的CoreData错误

Qt5 & QtQuick2 - 透明主窗口