Отправить сигнал с Python на Compononent.OnCompleted

#python #qml #pyside2

Вопрос:

Я как бы связываю вещи воедино, и это постепенно начинает обретать больше смысла. Я понимаю, как посылать сигналы и т. Д. одним щелчком мыши.

Цель: графический интерфейс, где в зависимости от нажатия кнопки он будет считываться, и RFID-карта. Этот код будет сохранен и передан в базу данных.

Здесь есть две кнопки. Одно открыто, другое близко. Любой из них откроет один и тот же скрипт RFID Python для считывания карты. Все эти сценарии выполняются в стековом представлении. Ниже приведена страница просмотра стека картридера. Он отлично загружается с кнопок, нажатых на предыдущем экране.

Чтобы перейти к правильному представлению стека, stackView.push(Qt.resolvedUrl("**GET URL FROM PYTHON**")) .

Таким образом, в зависимости от кнопки, нажатой на предыдущей странице, он загрузит либо приветственный QML, либо прощальный QML

Основной QML

 ///For button OPEN
onClicked: {
    backend.open() ///Here connect to the correct python def
    stackView.push(Qt.resolvedUrl("ReadCard.qml")) ///Go to read card
}

/// For button CLOSE
onClicked: {
    backend.close() ///Here connect to the correct python def
    stackView.push(Qt.resolvedUrl("ReadCard.qml"))///Go to read card
}
 

Python: main.py

 # Signal Set Data
readOpen = Signal(str)
scanOut = Signal(str)

@Slot()
def open(self):
    # Read card code
    # SQL Code
    # Move to Welcome QML if the lock is opened.
    self.readOpen.emit("Welcome.qml")

@Slot()
def close(self):
    # Read card code
    # SQL Code
    # Move to Good-Bye QML when lock is closed.
    self.scanOut.emit("GoodBye.qml")
    print("This is where the code to clock out will go")  
 

QML: читатель.qml

 import QtQuick 2.0
import QtQuick.Controls 2.15
import "../controls"
import QtQuick.Layouts 1.0

Item {
    Rectangle {
        id: rectangle
        ...Other properties...

        Rectangle {
            id: rectangleTop
            ...Other Properties...
        }

        Rectangle {
            id: rectangleVisible
            color: "#1d2128"
            radius: 10
            anchors.left: parent.left
            anchors.right: parent.right
            anchors.top: rectangleTop.bottom
            anchors.bottom: parent.bottom
            anchors.bottomMargin: 40
            anchors.rightMargin: 50
            anchors.leftMargin: 50
            anchors.topMargin: 10

            //The timer just used to simulate card read as no card reader connected yet
            Timer {
                    id: timer
            }

            function delay(delayTime,cb) {
                timer.interval = delayTime;
                timer.repeat = false;
                timer.triggered.connect(cb);
                timer.start();
            }

            Component.onCompleted: delay(1000, function() {
                stackView.push(Qt.resolvedUrl("URL FROM PYTHON"))
            })

            Text {
                id: text1
                x: 148
                y: 119
                width: 288
                height: 109
                color: "#ffffff"
                text: qsTr("Scan your card")
                anchors.verticalCenter: parent.verticalCenter
                font.pixelSize: 36
                horizontalAlignment: Text.AlignHCenter
                verticalAlignment: Text.AlignVCenter
                anchors.horizontalCenter: parent.horizontalCenter
            }
        }
    }

    Connections{
        target: backend
    }
}
 

Так что главный вопрос в том. Как получить этот URL-адрес из Python и передать его в Qt.resolvedurl?

Ответ №1:

Из того, что я понял, ОП хочет, чтобы URL-адрес StackView обрабатывался с python, поэтому возможным решением является создание qproperty, который размещает URL-адрес через соединение:

 import os
import random
import sys
from pathlib import Path

from PySide2.QtCore import Property, QCoreApplication, QObject, Qt, QUrl, Signal, Slot
from PySide2.QtGui import QGuiApplication
from PySide2.QtQml import QQmlApplicationEngine

CURRENT_DIRECTORY = Path(__file__).resolve().parent


class Manager(QObject):
    url_changed = Signal(name="urlChanged")

    def __init__(self, parent=None):
        super().__init__(parent)
        self._url = QUrl()

    @Property(QUrl, notify=url_changed)
    def url(self):
        return self._url

    def _update_url(self, url):
        if self.url == url:
            return
        self._url = url
        self.url_changed.emit()

    @Slot()
    def open(self):
        self._update_url(QUrl("Welcome.qml"))

    @Slot()
    def close(self):
        self._update_url(QUrl("GoodBye.qml"))


def main():
    app = QGuiApplication(sys.argv)

    manager = Manager()

    engine = QQmlApplicationEngine()
    engine.rootContext().setContextProperty("manager", manager)

    filename = os.fspath(CURRENT_DIRECTORY / "main.qml")
    url = QUrl.fromLocalFile(filename)

    def handle_object_created(obj, obj_url):
        if obj is None and url == obj_url:
            QCoreApplication.exit(-1)

    engine.objectCreated.connect(handle_object_created, Qt.QueuedConnection)

    engine.load(url)

    sys.exit(app.exec_())


if __name__ == "__main__":
    main()
 

main.qml

 import QtQuick 2.15
import QtQuick.Controls 2.15
import QtQuick.Layouts 1.15
import QtQuick.Window 2.15

Window {
    width: 640
    height: 480
    visible: true
    title: qsTr("Qt is awesome!!!")

    RowLayout {
        id: row_layout

        width: parent.width

        Button {
            text: "Open"
            Layout.fillWidth: true
            onClicked: manager.open()
        }

        Button {
            text: "Close"
            Layout.fillWidth: true
            onClicked: manager.close()
        }

    }

    StackView {
        id: stack_view

        anchors.top: row_layout.bottom
        anchors.bottom: parent.bottom
        width: parent.width
    }

    Connections {
        function onUrlChanged() {
            stack_view.pop();
            stack_view.push(Qt.resolvedUrl(manager.url));
        }

        target: manager
    }

}
 

Добро пожаловать.qml

 import QtQuick 2.15
import QtQuick.Controls 2.15

Page {
    Text {
        text: "Welcome"
        anchors.centerIn: parent
    }

}
 

До свидания.qml

 import QtQuick 2.15
import QtQuick.Controls 2.15

Page {
    Text {
        text: "GoodBye"
        anchors.centerIn: parent
    }

}
 

Комментарии:

1. Извините. Я пытался сделать код как можно меньше из той реализации, которая у меня была, но он начал ломать кучу вещей из-за макетов и т. Д. Связи в части обмена-это то, с чем я боролся. Ты делаешь так, чтобы это выглядело так просто. Я видел в вашем профиле, что у вас есть несколько документов на github для просмотра. Я посмотрю. Если кто-нибудь может порекомендовать что-то хорошее для чтения и попробовать в одиночку для QT, пожалуйста, предложите. Эйланеск, большое тебе спасибо. Я посмотрю и изучу больше о фрагментах, которые вы предоставили.