遇见的坑
qt 5.11 与 qt 5.12 中Qquick的差异还是蛮大的,由开发环境:Pyqt5.11 + Qt5.12 部署到 Pyqt5.11 + Qt5.11时遇到以下问题:
1.当一个Item引用另一个Item,当层次比较深入时,有可能引用不到此Item对象。这时可以用alias别名尝试把此对象作为顶层类的属性。另还有一个可能是因为Item文件的命名冲突,比如我把Item文件命名为ContentLeft.qml就会出现一些莫名奇妙的问题,后来把名称改为ContentLeftF.qml就没有。由“ContentLeft"改成”ContentLeftF.qml"问题解决。
2.有些str类型的属性可以直接用于QML,但有些会提示QString不对
#barcode @pyqtProperty(str,notify=barcodeChanged) def barcode(self): return self._barcode @barcode.setter def barcode(self, value): self._barcode = value self.barcodeChanged.emit(value)
把以上写法改为下面写法即没问题:
projectName = pyqtProperty(str, fget=getProjectValue, fset= setProjectValue, notify=projectNameChanged)
一些套路
1.把python类注册成qml类
qmlRegisterType(CameraOpencv,'MyCamera',1,0,'MyCustomOpenCVItem')
可以直接在qml用
import QtQuick 2.9 import QtQuick.Controls 2.2 import QtQuick.Layouts 1.1 import MyCamera 1.0 Item{ id:root property alias myCustomOpenCVItem: myCustomOpenCVItem Rectangle{ color:"black" anchors.fill: parent MyCustomOpenCVItem{ id:myCustomOpenCVItem objectName:"camera_win" anchors.fill:parent } MouseArea{ anchors.fill: parent onClicked: { content.contentMiddle.myCustomOpenCVItem.save() } } } }
2.把python对象传至qml
self.imageModel = ModelImages() self.rootContext().setContextProperty('ImagesModel', self.imageModel)
qml中直接调用
ListView { id : m_listView parent.width height: root.height clip: true model: ImagesModel //modelImages delegate: m_delegate spacing: 5 focus: true verticalLayoutDirection: ListView.BottomToTop add: Transition { NumberAnimation { properties: "y";duration: 400 } } remove: Transition { NumberAnimation { properties: "y";duration: 400 } } }
3.设置可在qml中用的属性
方法一:
self._goodsName = '' #当前商品名称 goodsNameChanged = pyqtSignal(str) @pyqtProperty(str,notify=goodsNameChanged) def goodsName(self): return self._goodsName @goodsName.setter def goodsName(self, value): self._goodsName = value self.goodsNameChanged.emit(value)
方法二:
projectName = pyqtProperty(str, fget=getProjectValue, fset= setProjectValue, notify=projectNameChanged)
4.qml动态设置component
function getLoader (){ switch (uploadStatus) { case "imgUploadFail": return uploadFail case "imgUploadOK": return uploadOK case "imgUploading": return uploading case "imgUploadReady": return null default: return null } } Loader{ id:currLoad anchors.fill:parent sourceComponent:getLoader() }
5.使用虚拟键盘
需要先安装VirtualKeyboard插件
先声明:
os.environ["QT_IM_MODULE"] = "qtvirtualkeyboard"
qml中:
import QtQuick.VirtualKeyboard 2.2 //键盘 InputPanel{ id: vkb z:3 visible: false anchors.bottom: parent.bottom parent.width * 0.85 height: parent.height * 0.3 x:parent.width * 0.5 - width * 0.5 //这种集成方式下点击隐藏键盘的按钮是没有效果的, //只会改变active,因此我们自己处理一下 onActiveChanged: { if(!active) { visible = false; } } }