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
}
}
}
運行結果如下:
本人水平有限,如果有疏漏之處,歡迎指點。
總結
以上是生活随笔為你收集整理的python qt信号在qml 的使用_QML与Python通信的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: UI翻天覆地!iQOO Neo5S/SE
- 下一篇: “三”大方向构筑5G下一站:中国移动张晓