python qt信号在qml 的使用_QML与Python通信

标签:

对于Python3和QML通信,实际上就是 PyQt5+QML+Python3混合编程,这是必须的,因为QML做图形界面比较容易,但是做功能实现就用Python比较好,虽然QML也能嵌入 JavaScript代码进行实现,但是这样话还不如用Python来实现,代码简洁、易懂。

对于以下的例子,参考了如下的连接:

Connecting QML signals in PySide:

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

(1)QML显式的调用Python函数

定义一个类,并继承QtCore.QObject对象,并使用@修饰符修饰pyqtSlot

1

2

3

4

5

6

7

8

9

class MyClass(QObject):

@pyqtSlot(str)    # 传递参数类型字符串

def outputString(self, string):

"""

功能: 创建一个槽

参数: 输出的数据string

返回值: 无

"""

print(string)

创建rootContext对象,并使用setContextProperty(string, object)注册对象,这样在QML中就可以调用这个函数了。

1

2

context = view.rootContext()

context.setContextProperty("con", con)

如下是一个完整的例子:

这个例子运行后,如果点击鼠标的话,会在控制台打印字符串。

Python3代码:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

# -*- coding: GBK -*-

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):

"""

功能: 创建一个槽

参数: 输出的数据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_()

QML代码(文件名保存为test.qml):

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

import QtQuick 2.0

Rectangle {

width: 320; height: 240

color: "lightgray"

Text {

id: txt

text: "Clicked me"

font.pixelSize: 20

anchors.centerIn: parent

}

MouseArea {

id: mouse_area

anchors.fill: parent  // 有效区域

onClicked: {

con.outputString("Hello, Python3")

}

}

}

运行结果如下:

(2)QML调用Python函数,并返回

这个例子跟上一个相类似,只是这次调用Python的函数具有返回值功能。

以下是一个完整的例子:

运行程序后,点击鼠标,左上角会显示数字30。

Python3代码:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

# -*- coding: GBK -*-

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):

"""

功能: 创建一个槽

参数: 整数value

返回值: 字符串

"""

return str(value+10)

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_()

QML代码(文件名保存为test.qml):

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

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)

}

}

}

运行效果如下:

未点击鼠标时:                                                              点击鼠标之后:

(3)QML连接信号到Python

当QML触发事件的时候,发射一个信号给Python,此时Python调用一个函数。

先在QML中定义一个信号,

1

signal sendClicked(string str) // 定义信号

然后在捕获事件的时候,发射信号,

1

2

3

4

5

6

7

MouseArea {

id: mouse_area

anchors.fill: parent  // 有效区域

onClicked: {

root.sendClicked("Hello, Python3")    # 发射信号到Python

}

}

最后Python中创建一个rootObject对象,然后连接这个对象,

1

2

3

4

5

6

7

def outputString(string):

"""

功能: 输出字符串

参数: 输出的数据string

返回值: 无

"""

print(string)

1

2

context = view.rootObject()

context.sendClicked.connect(outputString)   # 连接QML信号sendCLicked

以下是一个完整的例子:

这个例子中,当点击鼠标的时候,控制台会打印信息。

Python3代码:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

# -*- coding: GBK -*-

from PyQt5.QtCore import QUrl, pyqtSlot

from PyQt5.QtGui import QGuiApplication

from PyQt5.QtQuick import QQuickView

def outputString(string):

"""

功能: 输出字符串

参数: 输出的数据string

返回值: 无

"""

print(string)

if __name__ == ‘__main__‘:

path = ‘test.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_()

QML代码(文件名保存为test.qml):

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

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中创建一个函数,

1

2

3

function updateRotater() {

rotater.angle += 45

}

Python中创建一个rootObject对象,并连接这个函数,

1

2

root = view.rootObject()

timer.timeout.connect(root.updateRotater)

以下是一个完整的例子:

例子中,每隔1s,指针会旋转45°。

Python3代码:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

# -*- coding: GBK -*-

from PyQt5.QtCore import QUrl, QTimer

from PyQt5.QtGui import QGuiApplication

from PyQt5.QtQuick import QQuickView

if __name__ == ‘__main__‘:

path = ‘test.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)

app.exec_()

QML代码(文件名保存为test.qml):

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

import QtQuick 2.0

Rectangle {

id: page

width: 500; height: 200

color: "lightgray"

function updateRotater() {

rotater.angle += 45

}

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

}

}

}

运行结果如下:

本人水平有限,如果有疏漏之处,欢迎指点。

标签:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值