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

Python 将具有多个状态的QtQuick项目保存到.png文件,python,qml,qtquick2,pyside2,Python,Qml,Qtquick2,Pyside2,我正在尝试将具有多个状态的可视项保存为.png图像(每个状态一个png) 我在onStateChanged信号处理程序中调用该项的grabToImage()方法,但图像仅在发生最后一次状态更改后保存,仅创建一个与该项的最后一次设置状态相对应的图像 我还尝试在python端调用saveToFile(),但这会导致运行时错误(请参阅python代码中的注释) grab_states.py from PySide2.QtCore import QUrl from PySide2.QtWidgets i

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

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

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

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_()
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_())
grab_states.qml

import QtQuick 2.0

Rectangle {
  id: rect
  width: 100
  height: 100

  color: "black"

  states: [
      State {name: "off"; PropertyChanges{target: rect; color: "red"}},
      State {name: "on";  PropertyChanges{target: rect; color: "green"}}
  ]

  onStateChanged: {
    print('stateChaged: ' + state)
    rect.grabToImage(function(result){
      print("saveToFile: " + rect.state);
      result.saveToFile(state + '.png');
      }
    )
  }
}
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"; PropertyChanges{target: rect; color: "red"}},
        State {name: "on";  PropertyChanges{target: rect; color: "green"}}
    ]

    onStateChanged: {
        rect.grabToImage(function(result){
            result.saveToFile(state + ".png");
            currentIndex+= 1;
            console.log(filename);
        })
    }
}
saveToFile函数的调用是预期的两倍,但只是在所有状态更改发生之后,所以我只得到一个显示最后一个状态并覆盖第一个图像的图像。如果我使用不同的文件名来防止覆盖,那么我会得到两个图像,都显示最终状态

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

您有两个错误:

  • 您正在更改状态,但未确保已保存图像

  • 通过执行上述操作,状态值将在grabToImage中更新,并将指向以前的状态

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

*.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_()
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"

  states: [
      State {name: "off"; PropertyChanges{target: rect; color: "red"}},
      State {name: "on";  PropertyChanges{target: rect; color: "green"}}
  ]

  onStateChanged: {
    print('stateChaged: ' + state)
    rect.grabToImage(function(result){
      print("saveToFile: " + rect.state);
      result.saveToFile(state + '.png');
      }
    )
  }
}
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"; PropertyChanges{target: rect; color: "red"}},
        State {name: "on";  PropertyChanges{target: rect; color: "green"}}
    ]

    onStateChanged: {
        rect.grabToImage(function(result){
            result.saveToFile(state + ".png");
            currentIndex+= 1;
            console.log(filename);
        })
    }
}
导入QtQuick 2.0
长方形{
id:rect
宽度:100
身高:100
颜色:“黑色”
属性int currentIndex:-1
onCurrentIndexChanged:if(currentIndex>=0&¤tIndex
这可能会引起您的兴趣