2019-09-18 22:32:19 +08:00
|
|
|
|
#!/usr/bin/env python
|
|
|
|
|
# -*- coding: utf-8 -*-
|
|
|
|
|
|
|
|
|
|
"""
|
|
|
|
|
Created on 2019年9月18日
|
|
|
|
|
@author: Irony
|
2021-07-13 14:52:26 +08:00
|
|
|
|
@site: https://pyqt.site , https://github.com/PyQt5
|
2019-09-18 22:32:19 +08:00
|
|
|
|
@email: 892768447@qq.com
|
|
|
|
|
@file: QtQuick.Signals
|
|
|
|
|
@description: 信号槽
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
import sys
|
2021-07-13 14:52:26 +08:00
|
|
|
|
from time import time
|
2019-09-18 22:32:19 +08:00
|
|
|
|
|
2021-07-13 14:52:26 +08:00
|
|
|
|
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
|
2019-09-18 22:32:19 +08:00
|
|
|
|
|
|
|
|
|
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中的函数
|
2019-09-18 23:20:18 +08:00
|
|
|
|
valueChanged.connect(_Window.onValueChanged)
|
|
|
|
|
// 绑定python中的信号到qml中的函数
|
|
|
|
|
_Window.timerSignal.connect(appendText)
|
2019-09-18 22:32:19 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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):
|
2019-09-18 23:20:18 +08:00
|
|
|
|
# 定义一个时间信号
|
|
|
|
|
timerSignal = pyqtSignal(str)
|
|
|
|
|
|
2019-09-18 22:32:19 +08:00
|
|
|
|
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)
|
2019-09-18 23:20:18 +08:00
|
|
|
|
self._timer = QTimer(self, timeout=self.onTimeout)
|
|
|
|
|
self._timer.start(2000)
|
|
|
|
|
|
|
|
|
|
def onTimeout(self):
|
|
|
|
|
# 定时器发送信号通知qml
|
|
|
|
|
self.timerSignal.emit('定时器发来:' + str(time()))
|
2019-09-18 22:32:19 +08:00
|
|
|
|
|
|
|
|
|
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_())
|