一、Qml作为窗口引入
例:QWidget窗口中用按钮打开和关闭Qml窗口
①QWidget窗口
import sys
from pathlib import Path
from PySide6.QtCore import QObject, Slot
from PySide6.QtQml import QQmlApplicationEngine
from PySide6.QtQuick import QQuickItem
from PySide6.QtWidgets import QApplication, QWidget, QPushButton
class TestWidget(QWidget):
def __init__(self, parent=None):
super(TestWidget, self).__init__(parent)
self.button_open = QPushButton(self)
self.button_open.setText("打开Qml窗口")
self.button_open.setGeometry(0, 100, 100, 50)
self.button_open.clicked.connect(self.handle_button_open_click)
self.button_close = QPushButton(self)
self.button_close.setText("关闭Qml窗口")
self.button_close.setGeometry(100, 100, 100, 50)
self.button_close.clicked.connect(self.handle_button_close_click)
# 打开Qml窗口
def handle_button_open_click(self):
self.widget = LoginQuickWidget()
# 关闭Qml窗口
def handle_button_close_click(self):
if hasattr(self, 'widget') and self.widget:
del self.widget
if __name__ == '__main__':
app = QApplication([])
widget = TestWidget()
widget.show()
app.exec()
②Qml窗口
注意:此处是直接引入qml文件。如果是从qrc资源文件中引入qml,则直接QQmlApplicationEngine.load即可
# 槽函数类(一个承载槽函数的容器类)
class Slots(QObject):
def __init__(self, objects):
self.objects = objects
super().__init__()
@Slot(str, result=None)
def set_text_msg(self, msg):
# 获取qml中的Text对象
child = self.objects[0].findChild(QQuickItem, "text1")
# 获取对象属性
p = child.property("text")
# 设置对象属性
child.setProperty("text", p + msg)
@Slot(result=str)
def get_text_msg(self):
return "皎氯"
"""
这种方式是以Qml作为窗口来使用。所有的逻辑UI都由Qml来完成。python提供可以调用数据的API即可。
"""
class LoginQuickWidget:
def __init__(self):
# 初始化UI
self.engine = QQmlApplicationEngine()
qml_file = Path(__file__).resolve().parent / "login.qml"
# 加载qml文件
self.engine.load(qml_file)
if not self.engine.rootObjects():
sys.exit(-1)
# qml对象集合
objects = self.engine.rootObjects()
# 实例化槽函数
self.slots = Slots(objects)
# 注入槽函数
self.engine.rootContext().setContextProperty('slots', self.slots)
③Qml文件
/**************************QML文件**************************/
import QtQuick
import QtQuick.Window
import QtQuick.Controls 6.3
import QtQuick.Layouts 6.3
import QtQuick.Controls.Windows 6.0
//主窗口
Window {
width: 800
height: 400
visible: true
title: qsTr("测试窗口")
Image {
id:background_image
anchors.fill: parent
fillMode: Image.PreserveAspectCrop
source: "http://cube.elemecdn.com/6/94/4d3ea53c084bad6931a56d5158a48jpeg.jpeg"
antialiasing: true
}
//文本展示框
Text {
id: text1
//用于python获取此对象
objectName:"text1"
x: 300
y: 20
width: 200
height: 34
text: qsTr("初始值")
font.pixelSize: 12
}
//一:通过JavaScript控制UI逻辑
Button {
id: button
x: 125
y: 179
width: 125
height: 29
text: qsTr("调用JavaScript方法")
//点击事件
onClicked: {
change()
}
//JavaScript函数
function change(){
var date = new Date();
text1.text=qsTr(date.getFullYear()+"年"+(date.getMonth() + 1)+"月"+date.getDate()+"日"+date.getHours()+"时"+date.getMinutes()+"分"+date.getSeconds()+"秒")
}
}
//二:通过Python控制UI逻辑(不推荐,因为要做UI与业务逻辑分离;槽函数相当于于ajax请求来获取数据,而不是去控制UI本身)
Button {
id: button1
x: 325
y: 179
width: 125
height: 29
text: qsTr("调用Python设置属性")
//点击事件
onClicked: {
//调用注入的槽函数,使用槽函数改变视图
slots.set_text_msg("小小改变")
}
}
//三:通过Python获取数据,JavaScript渲染UI(推荐方式)
Button {
id: button2
x: 525
y: 179
width: 125
height: 29
text: qsTr("调用Python获取数据")
//点击事件
onClicked: {
//调用注入的槽函数,使用槽函数获取数据
var msg=slots.get_text_msg()
//利用JS进行渲染
text1.text=qsTr(msg)
}
}
}
二、Qml作为控件引入(Qml根组件不能是window)
from PySide6.QtCore import QUrl, Slot, QObject
from PySide6.QtQuick import QQuickItem
from PySide6.QtQuickWidgets import QQuickWidget
from PySide6.QtWidgets import QWidget, QApplication, QVBoxLayout, QPushButton
# 槽函数类(一个承载槽函数的容器类)
class Slots(QObject):
def __init__(self, obj):
super(Slots, self).__init__()
self.obj = obj
@Slot(str, result=None)
def set_text_msg(self, msg):
# 获取qml中的Text对象
child = self.obj.findChild(QQuickItem, "text1")
# 获取对象属性
p = child.property("text")
# 设置对象属性
child.setProperty("text", p + msg)
@Slot(result=str)
def get_text_msg(self):
return "皎氯"
class TestQWidget(QWidget):
def __init__(self, parent=None):
super(TestQWidget, self).__init__(parent)
self.resize(800, 300)
# 垂直布局
self.layout = QVBoxLayout(self)
# OK按钮
self.button = QPushButton("OK")
self.button.clicked.connect(lambda: print("OK"))
self.layout.addWidget(self.button)
# QML控件
self.qml_widget = QQuickWidget()
# 设置缩放模式
self.qml_widget.setResizeMode(QQuickWidget.ResizeMode.SizeRootObjectToView)
# 向QML中传入数据(必须在setSource之前传入)
self.qml_widget.rootContext().setContextProperty("obj", '张良')
self.qml_widget.setSource(QUrl("test2.qml"))
# 获取QML中的对象(必须在setSource之后)
self.root_object: QQuickItem = self.qml_widget.rootObject()
# 实例化槽函数
self.slots = Slots(self.root_object)
# 注入槽函数
self.qml_widget.rootContext().setContextProperty('slots', self.slots)
# 获取对象
child: QQuickItem = self.root_object.findChild(QQuickItem, "text1")
# 获取对象属性
print(child.property("text"))
# 加入布局
self.layout.addWidget(self.qml_widget)
if __name__ == '__main__':
app = QApplication([])
widget = TestQWidget()
widget.show()
app.exec()
import QtQuick
import QtQuick.Window
import QtQuick.Controls 6.3
import QtQuick.Layouts 6.3
import QtQuick.Controls.Windows 6.0
Rectangle {
id:root
color: "yellow"
radius:10
//背景图
Image {
id:background_image
anchors.fill: parent
fillMode: Image.PreserveAspectCrop
source: "http://cube.elemecdn.com/6/94/4d3ea53c084bad6931a56d5158a48jpeg.jpeg"
antialiasing: true
}
//文本展示框
Text {
id: text1
//用于python获取此对象
objectName:"text1"
x: 300
y: 20
width: 200
height: 34
text: qsTr(obj)
font.pixelSize: 12
}
//一:通过JavaScript控制UI逻辑
Button {
id: button
x: 125
y: 179
width: 125
height: 29
text: qsTr("调用JavaScript方法")
//点击事件
onClicked: {
change()
}
//JavaScript函数
function change(){
var date = new Date();
text1.text=qsTr(date.getFullYear()+"年"+(date.getMonth() + 1)+"月"+date.getDate()+"日"+date.getHours()+"时"+date.getMinutes()+"分"+date.getSeconds()+"秒")
}
}
//二:通过Python控制UI逻辑(不推荐,因为要做UI与业务逻辑分离;槽函数相当于于ajax请求来获取数据,而不是去控制UI本身)
Button {
id: button1
x: 325
y: 179
width: 125
height: 29
text: qsTr("调用Python设置属性")
//点击事件
onClicked: {
//调用注入的槽函数,使用槽函数改变视图
slots.set_text_msg("小小改变")
}
}
//三:通过Python获取数据,JavaScript渲染UI(推荐方式)
Button {
id: button2
x: 525
y: 179
width: 125
height: 29
text: qsTr("调用Python获取数据")
//点击事件
onClicked: {
//调用注入的槽函数,使用槽函数获取数据
var msg=slots.get_text_msg()
//利用JS进行渲染
text1.text=qsTr(msg)
}
}
}
三、3个问题①Qml文件如何调用python函数②python代码如何控制Qml元素。③python如何执行Qml中的函数。
本文转载自: https://blog.csdn.net/wenxingchen/article/details/127683645
版权归原作者 苍穹之跃 所有, 如有侵权,请联系我们删除。
版权归原作者 苍穹之跃 所有, 如有侵权,请联系我们删除。