从 Python 脚本执行 Qml 函数?
Execute a Qml function from Python script?
我正在尝试制作一个脚本,它将根据键盘命令打开一个输入框,您在其中输入一些内容,它会关闭,然后 returns 将文本发送到 python。到目前为止一切正常,在 python 中接受当我的组合键被满足时,我想不出一种方法来显示 Qml gui。我在 C++ 中看到了一些工作示例,但似乎没有找到 python.
main.py
import os
from pathlib import Path
import sys
from PySide6.QtCore import QCoreApplication, Qt, QUrl, QObject, Signal, Slot
from PySide6.QtGui import QGuiApplication
from PySide6.QtQml import QQmlApplicationEngine
from pynput.keyboard import Key, Listener, KeyCode
#is call qml function from python to show window.
CURRENT_DIRECTORY = Path(__file__).resolve().parent
COMBINATION = {Key.shift_r, Key.enter}
current = set()
#KEYBOARD LISTENER
class KeyMonitor(QObject):
keyPressed = Signal(KeyCode)
def __init__(self, parent=None):
super().__init__(parent)
self.listener = Listener(on_press=self.on_press, on_release=self.on_release)
def on_press(self, key):
if key in COMBINATION:
current.add(key)
if all(k in current for k in COMBINATION):
print('All modifiers active!')
#I WANT TO CALL QML FUNCTION OPEN() RIGHT HERE.
def on_release(self, key):
try:
current.remove(key)
except KeyError:
pass
def stop_monitoring(self):
self.listener.stop()
def start_monitoring(self):
self.listener.start()
#SLOT STUFF
class MainBackend(QObject):
def __init__(self):
QObject.__init__(self)
signalPrintTxtEmitter = Signal(bool)
@Slot()
def printTxt(self):
self.signalPrintTxtEmitter.emit(True)
print('Hello from Python!')
input_Text = Signal(str)
@Slot(str)
def sendToPython(self, text):
currentText=text
print("Python says you typed in:" + " " + currentText)
#RUNNING QML
def main():
app = QGuiApplication(sys.argv)
engine = QQmlApplicationEngine()
main = MainBackend()
engine.rootContext().setContextProperty("backend", main)
filename = os.fspath(CURRENT_DIRECTORY / "QML" / "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__":
monitor = KeyMonitor()
#monitor.keyPressed.connect(print)
monitor.start_monitoring()
main()
main.qml:
import QtQuick 2.15
import QtQuick.Controls 2.15
import QtQuick.Controls.Material 2.15
import QtQuick.Window 2.15
ApplicationWindow{
id: root
title: qsTr("Hello, I'm main.qml!")
visible: true
width: 400
height: 580
Material.theme: Material.Dark
Material.accent: Material.LightBlue
//Component.onCompleted: functions.close()
TextField {
id: input_Box
width: 160
placeholderText: qsTr("Enter Here")
anchors.centerIn: parent
focus: true
Keys.onPressed: {
if (event.key == Qt.Key_Return) {
//backend.printTxt()
backend.sendToPython(input_Box.text)
functions.close()
}
}
}
Button{
id: button
focus: true
text: qsTr("Click me!")
onClicked: functions.openQml()
}
QtObject {
id: functions
function close() {
root.hide()
}
function open() {
root.show()
}
}
Connections {
target: backend
function onSignalPrintTxtEmitter(boolValue){
return
}
function onSignalsendToPythonEmitter(str){
return
}
}
}
与其尝试从 python 调用 QML 函数,不如从 python 发出信号并将 QML 函数调用到关联的插槽:
class KeyMonitor(QObject):
keyPressed = Signal(KeyCode)
foo = Signal()
# ...
def on_press(self, key):
if key in COMBINATION:
current.add(key)
if all(k in current for k in COMBINATION):
print("All modifiers active!")
self.foo.emit()
main = MainBackend()
monitor = KeyMonitor()
QTimer.singleShot(1000, monitor.foo.emit)
monitor.start_monitoring()
engine.rootContext().setContextProperty("backend", main)
engine.rootContext().setContextProperty("monitor", monitor)
Connections{
target: monitor
function onFoo(){
console.log("Foo")
functions.open()
}
}
我正在尝试制作一个脚本,它将根据键盘命令打开一个输入框,您在其中输入一些内容,它会关闭,然后 returns 将文本发送到 python。到目前为止一切正常,在 python 中接受当我的组合键被满足时,我想不出一种方法来显示 Qml gui。我在 C++ 中看到了一些工作示例,但似乎没有找到 python.
main.py
import os
from pathlib import Path
import sys
from PySide6.QtCore import QCoreApplication, Qt, QUrl, QObject, Signal, Slot
from PySide6.QtGui import QGuiApplication
from PySide6.QtQml import QQmlApplicationEngine
from pynput.keyboard import Key, Listener, KeyCode
#is call qml function from python to show window.
CURRENT_DIRECTORY = Path(__file__).resolve().parent
COMBINATION = {Key.shift_r, Key.enter}
current = set()
#KEYBOARD LISTENER
class KeyMonitor(QObject):
keyPressed = Signal(KeyCode)
def __init__(self, parent=None):
super().__init__(parent)
self.listener = Listener(on_press=self.on_press, on_release=self.on_release)
def on_press(self, key):
if key in COMBINATION:
current.add(key)
if all(k in current for k in COMBINATION):
print('All modifiers active!')
#I WANT TO CALL QML FUNCTION OPEN() RIGHT HERE.
def on_release(self, key):
try:
current.remove(key)
except KeyError:
pass
def stop_monitoring(self):
self.listener.stop()
def start_monitoring(self):
self.listener.start()
#SLOT STUFF
class MainBackend(QObject):
def __init__(self):
QObject.__init__(self)
signalPrintTxtEmitter = Signal(bool)
@Slot()
def printTxt(self):
self.signalPrintTxtEmitter.emit(True)
print('Hello from Python!')
input_Text = Signal(str)
@Slot(str)
def sendToPython(self, text):
currentText=text
print("Python says you typed in:" + " " + currentText)
#RUNNING QML
def main():
app = QGuiApplication(sys.argv)
engine = QQmlApplicationEngine()
main = MainBackend()
engine.rootContext().setContextProperty("backend", main)
filename = os.fspath(CURRENT_DIRECTORY / "QML" / "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__":
monitor = KeyMonitor()
#monitor.keyPressed.connect(print)
monitor.start_monitoring()
main()
main.qml:
import QtQuick 2.15
import QtQuick.Controls 2.15
import QtQuick.Controls.Material 2.15
import QtQuick.Window 2.15
ApplicationWindow{
id: root
title: qsTr("Hello, I'm main.qml!")
visible: true
width: 400
height: 580
Material.theme: Material.Dark
Material.accent: Material.LightBlue
//Component.onCompleted: functions.close()
TextField {
id: input_Box
width: 160
placeholderText: qsTr("Enter Here")
anchors.centerIn: parent
focus: true
Keys.onPressed: {
if (event.key == Qt.Key_Return) {
//backend.printTxt()
backend.sendToPython(input_Box.text)
functions.close()
}
}
}
Button{
id: button
focus: true
text: qsTr("Click me!")
onClicked: functions.openQml()
}
QtObject {
id: functions
function close() {
root.hide()
}
function open() {
root.show()
}
}
Connections {
target: backend
function onSignalPrintTxtEmitter(boolValue){
return
}
function onSignalsendToPythonEmitter(str){
return
}
}
}
与其尝试从 python 调用 QML 函数,不如从 python 发出信号并将 QML 函数调用到关联的插槽:
class KeyMonitor(QObject):
keyPressed = Signal(KeyCode)
foo = Signal()
# ...
def on_press(self, key):
if key in COMBINATION:
current.add(key)
if all(k in current for k in COMBINATION):
print("All modifiers active!")
self.foo.emit()
main = MainBackend()
monitor = KeyMonitor()
QTimer.singleShot(1000, monitor.foo.emit)
monitor.start_monitoring()
engine.rootContext().setContextProperty("backend", main)
engine.rootContext().setContextProperty("monitor", monitor)
Connections{
target: monitor
function onFoo(){
console.log("Foo")
functions.open()
}
}