pyqt5与QML开发小结

发布时间:2019-05-22 22:11:50编辑:auto阅读(2167)

    遇见的坑

    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
                width: 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
                width: parent.width * 0.85
                height: parent.height * 0.3
                x:parent.width * 0.5 - width * 0.5
                //这种集成方式下点击隐藏键盘的按钮是没有效果的,
                //只会改变active,因此我们自己处理一下
                onActiveChanged: {
                    if(!active) { visible = false; }
                }
            }

     

关键字