学习pyqt第二天,研究了一整天这个模式,各种搜索,并没有太多这方面的资料!
经过自己不断的修改和试错。最终得出了这种方式,如果大家有更优的方式,希望大家能评论告诉我一下!
好,废话不多说,贴代码!首先是定义相当于WPF中ViewModel类,PYQT5和PYQT6代码一样
from PyQt6.QtQuick import QQuickView
from PyQt6.QtQml import qmlRegisterType,QQmlApplicationEngine
from PyQt6.QtCore import *
from PyQt6.QtCore import QCoreApplication, Qt, QUrl,pyqtProperty
from PyQt6.QtWidgets import QApplication
import sys
#viewModel类,这边写属性以及窗体事件代码
class MainWindowViewModel(QObject):
def __init__(self, parent=None):
super().__init__(parent)
#-------------定义属性开始-------------------
#私有变量,用来操作和初始化值
_userName = '我是初始值'
#定义pyqtSignal,跟pyqtProperty的类型需要一直
userNameChanged = pyqtSignal(str)
#定义pyqtProperty属性,第一个是属性的类型,第二个是notify
@pyqtProperty(str,notify=userNameChanged)
def userName(self):
return self._userName
#定义属性改变事件,py代码改变属性值将调用这个方法
@userName.setter
def userName(self, value):
self._userName = value
#将属性值更新到qml中
self.userNameChanged.emit(value)
#-------------定义属性结束------------------------
#-------------这边开始定义事件--------------------
#使用pyqtSlot来定义返回值,如无返回值则可以不设置
@pyqtSlot(result=str)
def outputString(self):
print(self.userName)
return 'success'
#带参数的事件或者方法,定义参数类型就行,可以有多个参数类型,需要与py方法的参数对应
@pyqtSlot(str,int,result=str)
#self是必须带上的,放在第一个
def setString(self,name,val):
self.userName='我被py代码改变'
print(name+":"+ str(val))
#-------------定义事件结束--------------------
然后在main函数中设置对象
if __name__ == '__main__':
app = QApplication(sys.argv)
#-------------------从这边开始设置-----------------------
view = QQuickView()
#实例化ViewModel类
viewModel = MainWindowViewModel()
context = view.rootContext()
#将ViewModel绑定到qml代码中的viewModel变量,qml通过这个来调用相关属性和方法
context.setContextProperty("viewModel",viewModel)
view.setSource(QUrl('main.qml'))
#-------------------到这边设置完成-----------------------
view.engine().quit.connect(app.quit)
#设置窗体标题
view.setTitle('例子')
view.show()
sys.exit(app.exec())
接下来是QML的写法,这边属性的双向绑定我捉摸出了2种写法,大家自行选择就行
TextField {
id: txt_userName
placeholderText: "请输入账号"
color: "#D9000000"
//------------------------关键绑定代码开始-----------------------------
//这句话可以将qml属性值绑定到py变量
onEditingFinished: viewModel.userName=text
//这句代码py变量绑定到qml属性
text: viewModel.userName
/* 第二种写法
Binding {
property: "text"
target: txt_userName
value: viewModel.userName
}
Binding {
property: "userName"
target: viewModel
value: txt_userName.text
}
*/
//------------------------关键绑定代码结束-----------------------------
width: 120
background: Rectangle
{
border.color: "#26000000"
}
}
}
接下来是事件的写法
Button {
width: 60
height: 30
font.family: "Microsoft YaHei"
text: "测试调用"
//事件
onClicked: {
viewModel.outputString()
//直接调用ViewModel中定义的方法就行
viewModel.setString('设置参数', 1)
//获取属性
console.log(viewModel.userName)
}
}
以上就是我今天研究出来的方法,经过自己的多次测试与修改!
以下是我写的VsCode快捷代码片段,有需要的可以导入使用
{
"qmlwindow": {
"prefix": "qml",
"body": [
"import QtQuick 2.7",
"import QtQuick.Window 2.0",
"import QtQuick.Controls 2.5",
"import QtQuick.Layouts 1.12",
"",
"Rectangle {",
" visible: true",
" $0",
"}"
],
"description": "qml窗体控件代码"
},
"QMLPyFile": {
"prefix": "qmlwindow",
"body": [
"from PyQt6.QtQuick import QQuickView",
"from PyQt6.QtQml import qmlRegisterType,QQmlApplicationEngine",
"from PyQt6.QtCore import *",
"from PyQt6.QtCore import QCoreApplication, Qt, QUrl,pyqtProperty",
"from PyQt6.QtWidgets import QApplication",
"import sys ",
"",
"",
"class $1ViewModel(QObject):",
" def __init__(self, parent=None):",
" super().__init__(parent)",
"",
" $0",
"",
"#-------------提示开始-------------------",
"#1、属性使用propqml",
"#2、事件使用eventqml",
"#-------------提示结束-------------------",
"",
"",
"",
"",
"if __name__ == '__main__':",
" app = QApplication(sys.argv)",
" view = QQuickView()",
" viewModel = $1ViewModel()",
" context = view.rootContext()",
" context.setContextProperty(\"$2\",viewModel)",
" view.setSource(QUrl('$3.qml'))",
" view.engine().quit.connect(app.quit)",
" view.setTitle('$4')",
" view.show()",
" sys.exit(app.exec())"
],
"description": "qml py代码"
},
"propqml": {
"prefix": "propqml",
"body": [
" _$1 = None",
" $1Changed = pyqtSignal($2)",
" @pyqtProperty($2,notify=$1Changed)",
" def $1(self):",
" return self._$1",
"",
" @$1.setter",
" def $1(self, value):",
" self._$1 = value",
" self.$1Changed.emit(value)",
"$0",
"",
],
"description": "qml绑定属性"
},
"eventqml": {
"prefix": "eventqml",
"body": [
" @pyqtSlot(result=$1)",
" def $2(self):",
" $0",
],
"description": "qml绑定事件"
},
}
转载请注明出处就行!