forked from PyQt5/PyQt
-
Notifications
You must be signed in to change notification settings - Fork 6
/
Signals.py
144 lines (117 loc) · 3.97 KB
/
Signals.py
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
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
Created on 2019年9月18日
@author: Irony
@site: https://pyqt.site , https://github.com/PyQt5
@email: [email protected]
@file: QtQuick.Signals
@description: 信号槽
"""
import sys
from time import time
try:
from PyQt5.QtCore import QCoreApplication, Qt, pyqtSlot, pyqtSignal, QTimer
from PyQt5.QtQml import QQmlApplicationEngine
from PyQt5.QtWidgets import QApplication, QMessageBox, QWidget, QVBoxLayout, \
QPushButton, QTextBrowser
except ImportError:
from PySide2.QtCore import QCoreApplication, Qt, Slot as pyqtSlot, Signal as pyqtSignal, QTimer
from PySide2.QtQml import QQmlApplicationEngine
from PySide2.QtWidgets import QApplication, QMessageBox, QWidget, QVBoxLayout, \
QPushButton, QTextBrowser
QML = """import QtQuick 2.0
import QtQuick.Controls 1.6
import QtQuick.Layouts 1.3
ApplicationWindow {
visible: true
width: 400
height: 400
id: root
title: "editor"
// 定义信号槽
signal valueChanged(int value)
Component.onCompleted: {
// 绑定信号槽到python中的函数
valueChanged.connect(_Window.onValueChanged)
// 绑定python中的信号到qml中的函数
_Window.timerSignal.connect(appendText)
}
function appendText(text) {
// 定义添加文字函数
textArea.append(text)
}
ColumnLayout {
id: columnLayout
anchors.fill: parent
Button {
id: button
text: qsTr("Button")
Layout.fillWidth: true
onClicked: {
// 点击按钮调用python中的函数并得到返回值
var ret = _Window.testSlot("Button")
textArea.append("我调用了testSlot函数得到返回值: " + ret)
}
}
Slider {
id: sliderHorizontal
Layout.fillWidth: true
stepSize: 1
minimumValue: 0
maximumValue: 100
// 拉动条值改变时发送信号
onValueChanged: root.valueChanged(value)
}
TextArea {
id: textArea
Layout.fillWidth: true
}
}
}
"""
class Window(QWidget):
# 定义一个时间信号
timerSignal = pyqtSignal(str)
def __init__(self, *args, **kwargs):
super(Window, self).__init__(*args, **kwargs)
layout = QVBoxLayout(self)
layout.addWidget(QPushButton('Python调用qml中的函数',
self, clicked=self.callQmlFunc))
self.resultView = QTextBrowser(self)
layout.addWidget(self.resultView)
self._timer = QTimer(self, timeout=self.onTimeout)
self._timer.start(2000)
def onTimeout(self):
# 定时器发送信号通知qml
self.timerSignal.emit('定时器发来:' + str(time()))
def callQmlFunc(self):
# 主动调用qml中的appendText函数
engine.rootObjects()[0].appendText('我是被Python调用了')
@pyqtSlot(int)
def onValueChanged(self, value):
# qml中的自定义信号valueChanged所绑定的槽函数
self.resultView.append('拉动条值: %s' % value)
@pyqtSlot(str, result=str) # 可以获取返回值
def testSlot(self, name):
# 被qml调用的函数
self.resultView.append('我被主动调用: %s' % name)
return str(len(name))
if __name__ == '__main__':
try:
QCoreApplication.setAttribute(Qt.AA_EnableHighDpiScaling)
except:
pass
app = QApplication(sys.argv)
# 测试界面
w = Window()
w.resize(400, 400)
w.show()
w.move(400, 400)
engine = QQmlApplicationEngine()
# 提供一个沟通的对象_Window,必须是要继承QObject的类
engine.rootContext().setContextProperty('_Window', w)
engine.objectCreated.connect(
lambda obj, _: QMessageBox.critical(None, '错误', '运行失败,请检查') if not obj else 0)
engine.loadData(QML.encode())
sys.exit(app.exec_())