遇見的坑
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; } } }