对于PyQt5+QML+Python3混合编程,如何实现PyQt5与QML响应彼此发送的信号,这是一个棘手的问题。

大抵有如下五种方式:

要运行下面五个例子,千万不能在eric6中运行,会报错。错误信息是:qml-test.py文件的第一个字符是无效的标识符

(1)QML显式的调用Python函数,无返回值

#文件名:qml-test.py
#文件名:test.qml
#!/usr/bin/env python
'''
(1)QML显式的调用Python函数 定义一个类,并继承QtCore.QObject对象,并使用@修饰符修饰pyqtSlot 创建rootContext对象,并使用setContextProperty(string, object)注册对象,
这样在QML中就可以调用这个函数了。 这个例子运行后,如果点击鼠标的话,会在控制台打印字符串。
'''
from PyQt5.QtCore import QUrl, QObject, pyqtSlot
from PyQt5.QtGui import QGuiApplication
from PyQt5.QtQuick import QQuickView class MyClass(QObject):
@pyqtSlot(str) # 输入参数为str类型
def outputString(self, string):
print(string) if __name__ == '__main__':
path = 'test.qml' # 加载的QML文件
app = QGuiApplication([])
view = QQuickView()
con = MyClass()
context = view.rootContext()
context.setContextProperty("con", con)
view.engine().quit.connect(app.quit)
view.setSource(QUrl(path))
view.show()
app.exec_()
import QtQuick 2.0

Rectangle {
width: 320; height: 240
color: "lightblue"
Text {
id: txt
text: "Clicked me"
font.pixelSize: 20
anchors.centerIn: parent
}
MouseArea {
id: mouse_area
anchors.fill: parent // 有效区域
onClicked: {
con.outputString("Hello, Python3") //QML显式的调用Python函数
}
}
}

(2)QML显式的调用Python函数,有返回值

#文件名:qml-test2.py
#文件名:test2.qml
#!/usr/bin/env python
'''
(2)QML显式的调用Python函数,并有返回 这个例子跟上一个相类似,只是这次调用Python的函数具有返回值功能。 运行程序后,点击鼠标,左上角会显示数字30。
'''
from PyQt5.QtCore import QUrl, QObject, pyqtSlot
from PyQt5.QtGui import QGuiApplication
from PyQt5.QtQuick import QQuickView class MyClass(QObject):
@pyqtSlot(int, result=str) # 声明为槽,输入参数为int类型,返回值为str类型
def returnValue(self, value):
return str(value+10) if __name__ == '__main__':
path = 'test2.qml' # 加载的QML文件
app = QGuiApplication([])
view = QQuickView()
con = MyClass()
context = view.rootContext()
context.setContextProperty("con", con)
view.engine().quit.connect(app.quit)
view.setSource(QUrl(path))
view.show()
app.exec_()
import QtQuick 2.0

Rectangle {
id: root
width: 320; height: 240
color: "lightgray"
Text {
id: txt
text: "Clicked me"
font.pixelSize: 20
anchors.centerIn: parent
}
Text {
id: txt1
text: "..."
font.pixelSize: 20
}
MouseArea {
id: mouse_area
anchors.fill: parent // 有效区域
onClicked: {
console.log("test...") // 控制台打印信息
txt1.text = con.returnValue(20) //QML显式的调用Python函数
}
}
}

(3)QML连接信号到Python

#文件名:qml-test3.py
#文件名:test3.qml
#!/usr/bin/env python
'''
(3)QML连接信号到Python 当QML触发事件的时候,发射一个信号给Python,此时Python调用一个函数。 先在QML中定义一个信号, 然后在捕获事件的时候,发射信号, 最后Python中创建一个rootObject对象,然后连接这个对象, 这个例子中,当点击鼠标的时候,控制台会打印信息。
'''
from PyQt5.QtCore import QUrl
from PyQt5.QtGui import QGuiApplication
from PyQt5.QtQuick import QQuickView def outputString(string):
print(string) if __name__ == '__main__':
path = 'test3.qml' # 加载的QML文件
app = QGuiApplication([])
view = QQuickView()
view.engine().quit.connect(app.quit)
view.setSource(QUrl(path))
view.show()
context = view.rootObject()
context.sendClicked.connect(outputString) # 连接QML信号sendCLicked
app.exec_()
import QtQuick 2.0

Rectangle {
id: root
width: 320; height: 240
color: "lightgray"
signal sendClicked(string str) // 定义信号 Text {
id: txt
text: "Clicked me"
font.pixelSize: 20
anchors.centerIn: parent
}
MouseArea {
id: mouse_area
anchors.fill: parent //有效区域
onClicked: {
root.sendClicked("Hello, Python3")//发射信号到Python
}
}
}

(4)Python调用QML函数

#文件名:qml-test4.py
#文件名:test4.qml
# -*- coding: utf-8 -*-
'''
(4)Python调用QML函数 QML中创建一个函数, Python中创建一个rootObject对象,并连接这个函数, 例子中,每隔1s,指针会旋转45 deg;。
'''
from PyQt5.QtCore import QUrl, QTimer
from PyQt5.QtGui import QGuiApplication
from PyQt5.QtQuick import QQuickView if __name__ == '__main__':
path = 'test4.qml' # 加载的QML文件 app = QGuiApplication([])
view = QQuickView()
view.engine().quit.connect(app.quit)
view.setSource(QUrl(path))
view.show() timer = QTimer()
timer.start(2000)
root = view.rootObject()
timer.timeout.connect(root.updateRotater) # 调用QML函数 app.exec_()
import QtQuick 2.0

Rectangle {
id: page
width: 500; height: 200
color: "lightgray" function updateRotater() {// 定义函数
rotater.angle += 5
} Rectangle {
id: rotater
property real angle : 0
x: 240; y: 95
width: 100; height: 5
color: "black" transform: Rotation {
origin.x: 10; origin.y: 5
angle: rotater.angle
}
}
}

(5)信号/槽 机制

#文件名:qml-test5.py
#文件名:test5.qml
from PyQt5.QtCore import pyqtProperty, pyqtSignal, pyqtSlot, QRectF, Qt, QUrl
from PyQt5.QtGui import QColor, QGuiApplication, QPainter, QPen
from PyQt5.QtQml import qmlRegisterType
from PyQt5.QtQuick import QQuickPaintedItem, QQuickView class PieChart(QQuickPaintedItem): chartCleared = pyqtSignal() # 定义信号 @pyqtProperty(str)
def name(self):
return self._name @name.setter
def name(self, name):
self._name = name @pyqtProperty(QColor)
def color(self):
return self._color @color.setter
def color(self, color):
self._color = QColor(color) def __init__(self, parent=None):
super(PieChart, self).__init__(parent) self._name = ''
self._color = QColor() def paint(self, painter):
painter.setPen(QPen(self._color, 2))
painter.setRenderHints(QPainter.Antialiasing, True) rect = QRectF(0, 0, self.width(), self.height()).adjusted(1, 1, -1, -1)
painter.drawPie(rect, 90 * 16, 290 * 16) @pyqtSlot()
def clearChart(self):
self.color = QColor(Qt.transparent)
self.update() self.chartCleared.emit() # 发射信号 if __name__ == '__main__':
import os
import sys app = QGuiApplication(sys.argv) qmlRegisterType(PieChart, "Charts", 1, 0, "PieChart") view = QQuickView()
view.setResizeMode(QQuickView.SizeRootObjectToView)
view.setSource(
QUrl.fromLocalFile(
os.path.join(os.path.dirname(__file__),'tes5.qml')))
view.show() sys.exit(app.exec_())
import Charts 1.0
import QtQuick 2.0 Item {
width: 300; height: 200 PieChart {
id: aPieChart
anchors.centerIn: parent
width: 100; height: 100
color: "red" onChartCleared: console.log("The chart has been cleared") //槽
} MouseArea {
anchors.fill: parent
onClicked: aPieChart.clearChart()
} Text {
anchors { bottom: parent.bottom; horizontalCenter: parent.horizontalCenter; bottomMargin: 20 }
text: "Click anywhere to clear the chart"
}
}

参考:

【QML与Python通信】

http://my.oschina.net/u/1275030/blog/186341

【Connecting QML signals in PySide】

http://qt-project.org/wiki/Connecting_QML_Signals_in_PySide

【PyQt 5.1.1 Reference Guide -> Support for Signals and Slots】:

http://pyqt.sourceforge.net/Docs/PyQt5/signals_slots.html?highlight=pyqtslot#PyQt5.QtCore.pyqtSlot

如何实现PyQt5与QML响应彼此发送的信号?的更多相关文章

  1. C# 响应微信发送的Token验证,文字、图文自动回复、请求客服对话.....

    代码如下,有需要的可以参考: using System; using System.Collections.Generic; using System.Linq; using System.Web; ...

  2. laravel响应的发送和程序终止

    响应的发送是通过index.php中的$response->send();实现的 vendor\symfony\http-foundation\Response.php public funct ...

  3. NodeJS 微信公共号开发 - 响应微信发送的Token验证(山东数漫江湖)

    背景 使用 NodeJS 进行微信公共号开发,首先需要响应微信发送的Token验证,官方文档 填写服务器配置 登录微信公共平台,在开发下的基本配置打开该页面. 依次填写接口的 URL.自定义的 Tok ...

  4. 向 Nginx 主进程发送 USR1 信号

    [1]Nginx重新打开日志文件 向 Nginx 主进程发送 USR1 信号.USR1 信号是重新打开日志文件: 方式一: kill -USR1 $(cat /usr/local/lib/ubcsrv ...

  5. pyqt5与QML开发小结

    遇见的坑 qt 5.11 与 qt 5.12 中Qquick的差异还是蛮大的,由开发环境:Pyqt5.11 + Qt5.12 部署到 Pyqt5.11 + Qt5.11时遇到以下问题: 1.当一个It ...

  6. 接口配置信息修改 请填写接口配置信息,此信息需要你有自己的服务器资源,填写的URL需要正确响应微信发送的Token验证

    // 1)将token.timestamp.nonce三个参数进行字典序排序 // 2)将三个参数字符串拼接成一个字符串进行sha1加密 // 3)开发者获得加密后的字符串可与signature对比, ...

  7. c# winform读取及发送串口信号

    请参考C#的API文档:https://docs.microsoft.com/zh-cn/dotnet/api/system.io.ports.serialport?redirectedfrom=MS ...

  8. 向nginx发送reopen信号以重新打开日志文件

    先移动日志文件 mv /usr/local/openresty/nginx/logs/access.log /usr/local/openresty/nginx/logs/access.log.201 ...

  9. QML于C++交互之信号与槽(signal&slot )

    connect c++ SIGNAL with QML SLOT 简介 QML 与 C++ 混合编程时,总结了一下qml和c++互相直接调用.及信号与槽连接 的几种情况,详细使用情况看示例代码 所有的 ...

随机推荐

  1. aws rhel 7 安装GUI ,配置VNC

    预计阅读时间:15分钟 预计配置时间:30分钟  (前提是已经申请AWS的EC2的rhel7 云主机并且成功运行) 目前AWS 亚马逊云免费试用一年,申请一个学习使用 痛点:没有GUI,无法搭建Jen ...

  2. Dos命令删除添加新服务

    安装服务sc create Svnservice binpath= "d:\subversion\bin\svnserve.exe --service -r E:\projectversio ...

  3. Python实例---CRM管理系统分析180331

    注意:一个项目基本都设计增删改查,且第一个需要做的就是设计表结构 思维导图: 组件使用: Django  +   bootStrap  +   Jquery 数据库表结构设计: 外键关联: 2种方式, ...

  4. Linux 文件的读写执行权限的说明

    文件的读写执行权限的说明 X 进入目录的权限: cd 1.文件本身是可执行的 2.普通用户还具备r的权限 3.root用户只需要有r的权限即可 r 查看目录/文件的内容 :ls dir 没有读的权 限 ...

  5. PSR规范学习笔记

    PSR已经经历了5次变革,如今PSR4就是最新的标准,但是还是有必要了解下5个版本的内容的,于是去php-fig网站看了下英文原版: 大概看了遍,发现这规范很多的必须很多时候只是建议,但是PHP解析器 ...

  6. windows 查看端口号,杀进程

    查看端口号: 开始--运行--cmd netstat –and 杀进程: windows任务管理器         查看--显示列-PID 相关知识: 一台机器的80端口被httpd (apache) ...

  7. 解决windows 10英文版操作系统中VS2017控制台程序打印中文乱码问题

    当您在windows 10英文版的操作系统中运行Vs2017控制台应用程序时,程序可能无法正常显示中文,中文都变成了乱码.这是由于大部分中文程序所使用的文字编码与Windows 英文系统的文字编码不同 ...

  8. 关于第一场HBCTF的Web题小分享,当作自身的笔记

    昨天晚上6点开始的HBCTF,虽然是针对小白的,但有些题目确实不简单. 昨天女朋友又让我帮她装DOTA2(女票是一个不怎么用电脑的),然后又有一个小白问我题目,我也很热情的告诉她了,哎,真耗不起. 言 ...

  9. (1)访问控制 (2)final关键字 (3)对象创建的过程 (4)多态

    1.访问控制(笔试题)1.1 常用的访问控制符 public - 公有的 protected - 保护的 啥也不写 - 默认的 private - 私有的 1.2 访问控制符的比较 访问控制符 访问权 ...

  10. RMAN恢复脚本案例

    $ crontab -l0 12,19 * * * $ORACLE_HOME/scripts/arcbkup.sh59 03 * * *  $ORACLE_HOME/scripts/dbbkup.sh ...