只能从GUI线程或从QQuickItem :: updatePaintNode()计划更新,>

问题描述 投票:3回答:1

我正在尝试使用带有PyQt5的QML使用存储在文件夹内的按钮(GPIO PIN)更改图像Python代码:

from gpiozero import Button
from signal import pause

from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtQml import *
import os, time, sys


def btn_pressed():
    global r
    return lambda: r.setProperty("source", "/home/pi/Desktop/example/sample/img/img1.jpg")

button1 = Button(20)        
myApp = QGuiApplication([])
myEngine = QQmlApplicationEngine()
directory = os.path.dirname(os.path.abspath(__file__))
myEngine.load(QUrl.fromLocalFile(os.path.join(directory, 'simple1.qml')))
if not myEngine.rootObjects():
    print("root object not found")

r = myEngine.rootObjects()[0].findChild(QObject, "DisplayImage")
dir(r)
print("Main Thead id ",myApp.thread())
updateUI = UpdateUI()

button1.when_pressed = btn_pressed()   
myEngine.quit.connect(myApp.quit)
sys.exit(myApp.exec_())

QML:

import QtQuick 2.10
import QtQuick.Controls 1.6
import QtQuick.Window 2.2

ApplicationWindow {
    id : main
    title: qsTr("Test")
    width: 640
    height: 480
    visible: true

    Rectangle{
        width: parent.width
        height: parent.height

        Image {
            id: img
            source: ""
            width : main.width;
            fillMode : Image.PreserveAspectFit
            objectName: "DisplayImage"
        }
    }
}

当我按下树莓派4中连接到GPIO 20的按钮时,出现以下错误消息。

QObject: Cannot create children for a parent that is in a different thread. 
(Parent is QQmlApplicationEngine(0x10f5ba0), parent's thread is QThread(0xf6f7c0), current thread is QThread(0xa98007c8)
Updates can only be scheduled from GUI thread or from QQuickItem::updatePaintNode()

我也尝试过使用更改图像源属性的方法创建类,然后在按下PushButton时调用相同的方法(通过Class Object,但它显示相同的错误消息)>

有没有一种方法可以在QML中设置Image的Source属性-从Python中的父线程开始。

在Winforms中,我们可以使用Delegates来避免出现“跨线程冲突错误”。

我们可以使用Signal and Slot解决PyQt5中的此问题。

[我正在尝试使用带有PyQt5 Python QML的QML使用存储在文件夹中的按钮(GPIO PIN)更改图像:from gpiozero import按钮来自PyQt5.QtCore import的信号导入暂停* from ...

python multithreading pyqt qml pyqt5
1个回答
0
投票

[gpiozero使用线程能够监视gpio,以便不阻塞主GUI,因此相关功能when_pressed将在该线程中执行,但Qt​​禁止从另一个线程更新GUI元素,例如图像。

解决方案是创建一个QObject,该对象以与when_pressed相关的方法来发射信号,因为该信号是线程安全的。

© www.soinside.com 2019 - 2024. All rights reserved.