#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, пожалуйста, предложите. Эйланеск, большое тебе спасибо. Я посмотрю и изучу больше о фрагментах, которые вы предоставили.