import QtQuick import QtQuick.Controls import QtQuick.Layouts import QtQuick.Dialogs import "./common" Item { id: self property var systemInterfaceUuid: "" property var interfacetypeNames: [] property var interfacetypes: [] property var serialPorts: [] property var serialBuadRates: ["9600", "19200", "38400", "115200"] property var serialStopBits: ["1", "1.5", "2"] property var serialParity: ["None", "Odd", "Even", "Mark", "Space"] property var serialByteSize: ["8", "7", "6", "5"] property var tcpRole: ["服务器", "客户端"] property var settingData: null property var supportType: {} signal refreshSerial signal beginSaveSerial Component.onCompleted: { initInterFace() createAddButton() getAvailablePorts() loadInterface() } ListModel { id: interfaceModel } Component { id: contactDelegate Rectangle { width: 283 height: 311 radius: 9 color: "#ffffff" property var rowIndex : model.index Component.onCompleted: { cbCom.currentIndex = cbCom.find(serialPort) var baudrateIndex = cbBuad.find(baudrate) if(baudrateIndex == -1 ) { if(baudrate != "") { var tempSerialBuadRates = ["9600", "19200", "38400", "115200"] tempSerialBuadRates.push(baudrate) cbBuad.model = tempSerialBuadRates cbBuad.currentIndex = cbBuad.find(baudrate) } } else { cbBuad.currentIndex = baudrateIndex } cbRole.currentIndex = cbRole.find(role) > -1 ? cbRole.find(role) : 0 cbParity.currentIndex = cbParity.find(parity) > -1 ? cbParity.find(parity) : 0 cbStopBits.currentIndex = cbStopBits.find(stopbits) > -1 ? cbStopBits.find(stopbits) : 0 cbByteSize.currentIndex = cbByteSize.find(bytesize) > -1 ? cbByteSize.find(bytesize) : 0 } Connections{ target: self function onRefreshSerial() { cbCom.currentIndex = cbCom.find(serialPort) cbBuad.currentIndex = cbBuad.find(baudrate) cbRole.currentIndex = cbRole.find(role) } function onBeginSaveSerial() { model.serialPort = cbCom.currentText if(cbBuad.editText == "") model.baudrate = cbBuad.currentText else model.baudrate = cbBuad.editText model.stopbits = cbStopBits.currentText model.parity = cbParity.currentText model.bytesize = cbByteSize.currentText model.role = cbRole.currentText } } Rectangle { anchors.fill: parent radius: 9 color: "#ffffff" visible: model.id != "add" Column { spacing: 9 anchors.horizontalCenter: parent.horizontalCenter anchors.top: parent.top anchors.topMargin: 10 Item { width: 233 height: 25 Rectangle { id: control anchors.left: parent.left visible: model.id != systemInterfaceUuid && type != "http" property var checked: false property var realChecked: false implicitWidth: 40 implicitHeight: 20 radius: 20 smooth: true color: control.checked ? "#3096ff" : "#ffffff" border.color: control.checked ? "#3096ff" : "#cccccc" Rectangle { x: control.checked ? parent.width - width : 0 width: 20 height: 20 radius: 10 smooth: true color: control.down ? "#cccccc" : "#ffffff" border.color: control.checked ? (control.down ? "#3096ff" : "#3096ff") : "#999999" } Component.onCompleted: { control.realChecked = interfaceManager.isConnect(model.id) control.checked = control.realChecked } Connections { target: interfaceManager function onConnectSuccess(_id) { if(model.id == _id) { control.realChecked = true control.checked = true } } function onConnectClosed(_id) { if(model.id == _id) { control.realChecked = false control.checked = false } } function onConnectFailed(_id) { if(model.id == _id) { // connectErrorDialog.visible = true control.realChecked = false control.checked = false } } } MouseArea{ anchors.fill: parent onClicked: { editCtrl.checked = false if(control.realChecked == false) { interfaceManager.open(model.id) } else { if(interfaceManager.close(model.id)) control.realChecked = false } control.checked = control.realChecked if(!control.checked) { cbAutoReconnect.checked = false interfaceManager.stopAutoReconnect(model.id) model.auto = "false" updateInterface(model.index) } } } } CheckBox{ id: cbAutoReconnect anchors.left: control.right anchors.leftMargin: 40 anchors.verticalCenter: control.verticalCenter visible: control.visible font.pointSize: 9 checked: model.auto == "true" ? true : false text: "自动连接" onClicked: { if (checked) { interfaceManager.startAutoReconnect(model.id) model.auto = "true" } else { interfaceManager.stopAutoReconnect(model.id) model.auto = "false" } updateInterface(model.index) } } // Switch{ // id: control // anchors.left: parent.left // checked: false // property var realChecked: false // visible: model.id != systemInterfaceUuid && type != "http" // indicator: Rectangle { // implicitWidth: 40 // implicitHeight: 20 // radius: 20 // smooth: true // color: control.checked ? "#3096ff" : "#ffffff" // border.color: control.checked ? "#3096ff" : "#cccccc" // Rectangle { // x: control.checked ? parent.width - width : 0 // width: 20 // height: 20 // radius: 10 // smooth: true // color: control.down ? "#cccccc" : "#ffffff" // border.color: control.checked ? (control.down ? "#3096ff" : "#3096ff") : "#999999" // } // } // Connections { // target: interfaceManager // function onConnectSuccess(_id) // { // if(model.id == _id) // { // control.realChecked = true // control.checked = true // } // } // function onConnectFailed(_id) // { // if(model.id == _id) // { // // connectErrorDialog.visible = true // control.realChecked = false // control.checked = false // } // } // } // onClicked: { // editCtrl.checked = false // if(realChecked == false) // { // interfaceManager.open(model.id) // } // else // { // if(interfaceManager.close(model.id)) // realChecked = false // } // checked = realChecked // } // } Image { id: editCtrl property var checked: false anchors.right: removeBtn.left anchors.rightMargin: 10 width: 26 height: 26 visible: model.id != systemInterfaceUuid enabled: !control.checked source: checked ? "./resource/finish.svg" : "./resource/edit.svg" MouseArea { anchors.fill: parent onClicked: { // 如果当前在编辑模式(checked为true表示正在编辑,点击后变为完成),需要保存数据 if(editCtrl.checked) { updateInterface(model.index) } editCtrl.checked = !editCtrl.checked } } } Image { id: removeBtn anchors.right: parent.right anchors.rightMargin: -18 width: 26 height: 26 visible: model.id != systemInterfaceUuid source: "./resource/remove.svg" MouseArea { anchors.fill: parent onClicked: { deleteDialog.visible = true deleteDialog.index = index } } } } Item { width: 233 height: 28 Text { text: "类型" font.pointSize: 11 color: "#737373" anchors.verticalCenter: parent.verticalCenter } TextField { id: tfType height: parent.height text: !!type ? supportType[type] : "" verticalAlignment: TextInput.AlignVCenter width: 150 anchors.right: parent.right enabled: false } } Item { width: 233 height: 28 Text { text: "名称" font.pointSize: 11 color: "#737373" anchors.verticalCenter: parent.verticalCenter } TextField { id: tfName text: name verticalAlignment: TextInput.AlignVCenter width: 150 height: parent.height enabled: editCtrl.checked selectByMouse: true anchors.right: parent.right onTextChanged: { if (text != model.name) { model.name = text updateInterface(model.index) } } } } Item { width: 233 height: 28 visible: type == "serial" || type == "tbus" || type == "tbus_ns" Text { text: "端口" font.pointSize: 11 color: "#737373" anchors.verticalCenter: parent.verticalCenter } ComboBox{ id: cbCom width: 150 height: parent.height model:serialPorts enabled: editCtrl.checked anchors.right: parent.right onActivated: { updateInterface(rowIndex) } } MouseArea{ anchors.fill: parent propagateComposedEvents: false onPressed:(mouse)=> { // 刷新串口 getAvailablePorts() refreshSerial() mouse.accepted = false } } } Item { width: 233 height: 28 visible: type == "serial" || type == "tbus" || type == "tbus_ns" Text { text: "波特率" font.pointSize: 11 color: "#737373" anchors.verticalCenter: parent.verticalCenter } ComboBox{ id: cbBuad width: 150 height: parent.height editable: true enabled: editCtrl.checked model:serialBuadRates anchors.right: parent.right onActivated: { updateInterface(rowIndex) } onEditTextChanged:{ updateInterface(rowIndex) } } } Item { width: 233 height: 28 visible: type == "serial" || type == "tbus" || type == "tbus_ns" Text { text: "数据位" font.pointSize: 11 color: "#737373" anchors.verticalCenter: parent.verticalCenter } ComboBox{ id: cbByteSize width: 150 height: parent.height // editable: true enabled: editCtrl.checked model:serialByteSize anchors.right: parent.right onActivated: { updateInterface(rowIndex) } } } Item { width: 233 height: 28 visible: type == "serial" || type == "tbus" || type == "tbus_ns" Text { text: "停止位" font.pointSize: 11 color: "#737373" anchors.verticalCenter: parent.verticalCenter } ComboBox{ id: cbStopBits width: 150 height: parent.height // editable: true enabled: editCtrl.checked model:serialStopBits anchors.right: parent.right onActivated: { updateInterface(rowIndex) } } } Item { width: 233 height: 28 visible: type == "serial" || type == "tbus" || type == "tbus_ns" Text { text: "奇偶校验" font.pointSize: 11 color: "#737373" anchors.verticalCenter: parent.verticalCenter } ComboBox{ id: cbParity width: 150 height: parent.height // editable: true enabled: editCtrl.checked model:serialParity anchors.right: parent.right onActivated: { updateInterface(rowIndex) } } } Item { width: 233 height: 28 visible: type == "tcp" || type == "tbus_tcp" Text { text: "角色" font.pointSize: 11 color: "#737373" anchors.verticalCenter: parent.verticalCenter } ComboBox{ id: cbRole width: 150 height: parent.height model:tcpRole enabled: editCtrl.checked anchors.right: parent.right onActivated: { updateInterface(rowIndex) } } } Item { width: 233 height: 28 visible: type == "tcp" || type == "tbus_tcp" Text { text: "IP" font.pointSize: 11 color: "#737373" anchors.verticalCenter: parent.verticalCenter } TextField{ id: cbIp width: 150 text: ip verticalAlignment: TextInput.AlignVCenter height: parent.height enabled: editCtrl.checked selectByMouse: true anchors.right: parent.right onTextChanged: { if (text != model.ip) { model.ip = text updateInterface(rowIndex) } } } } Item { width: 233 height: 28 visible: type == "tcp" || type == "tbus_tcp" Text { text: "端口号" font.pointSize: 11 color: "#737373" anchors.verticalCenter: parent.verticalCenter } TextField{ id: tfPort width: 150 height: parent.height text: port enabled: editCtrl.checked verticalAlignment: TextInput.AlignVCenter selectByMouse: true anchors.right: parent.right onTextChanged: { if(text != model.port) { model.port = text updateInterface(rowIndex) } } } } } } Item { anchors.fill: parent visible: model.id == "add" Image{ id: imgAdd anchors.centerIn: parent source: "./resource/add.svg" } MouseArea{ anchors.fill: parent hoverEnabled: true onEntered:{ imgAdd.scale = 0.9 } onExited: { imgAdd.scale = 1 } onClicked:{ dialog.visible = true } } } } } GridView { clip: true anchors.left: parent.left anchors.right: parent.right anchors.bottom: parent.bottom anchors.top: parent.top anchors.leftMargin: 10 anchors.topMargin: 18 flow: GridView.FlowLeftToRight cellWidth: 293; cellHeight: 321 delegate: contactDelegate model: interfaceModel boundsBehavior: Flickable.StopAtBounds } function initInterFace() { supportType = interfaceManager.getSupportedType() interfacetypes = [] interfacetypeNames = [] for (var key in supportType) { interfacetypes.push(key) interfacetypeNames.push(supportType[key]) } cbInterfaceType.model = interfacetypeNames } function createAddButton(){ interfaceModel.append({ 'id': "add", 'name': "", 'type': "", 'auto': "", 'serialPort': "", 'baudrate': "", 'parity': "", 'bytesize': "", 'stopbits': "", 'role':"", 'ip':"", 'port':"" }) } function createInterface(obj) { var name = obj.name var type = obj.type var attr = {} var interfaceId = interfaceManager.create(name, type, attr) if(interfaceId != "") { obj.id = interfaceId interfaceModel.insert(interfaceModel.count-1, obj) } } function deleteInterface(index) { var obj = interfaceModel.get(index) var interfaceId = obj.id if(interfaceManager.delete(interfaceId)) { interfaceModel.remove(index) } } function updateInterface(index) { beginSaveSerial() var obj = interfaceModel.get(index) var interfaceId = obj.id if (interfaceId == systemInterfaceUuid) return var name = obj.name var type = obj.type var attr = {} if (type == "tcp" || type == "tbus_tcp") { attr = { "auto": obj.auto, "role": obj.role, "ip": obj.ip, "port": obj.port } } else { attr = { "auto": obj.auto, "port": obj.serialPort, "baudrate":obj.baudrate, "parity": obj.parity, "bytesize": obj.bytesize, "stopbits": obj.stopbits, } } interfaceManager.update(interfaceId, name, attr) } function loadInterface(){ systemInterfaceUuid = common.getSystemInterfaceUuid() var interfaceList = interfaceManager.getInfo("all") if(!!interfaceList) { for(var i = 0; i < interfaceList.length; ++i) { var interfaceObj = interfaceList[i] var obj = { 'id': interfaceObj.id, 'name': interfaceObj.name, 'type': interfaceObj.type, 'auto': "auto" in interfaceObj.attrs ? interfaceObj.attrs.auto : "false", 'serialPort': "port" in interfaceObj.attrs ? interfaceObj.attrs.port : "", 'baudrate': "baudrate" in interfaceObj.attrs ? interfaceObj.attrs.baudrate : "" , 'parity': "parity" in interfaceObj.attrs ? interfaceObj.attrs.parity : "", 'bytesize': "bytesize" in interfaceObj.attrs ? interfaceObj.attrs.bytesize : "", 'stopbits': "stopbits" in interfaceObj.attrs ? interfaceObj.attrs.stopbits : "", 'role': "role" in interfaceObj.attrs ? interfaceObj.attrs.role : "", 'ip': "ip" in interfaceObj.attrs ? interfaceObj.attrs.ip : "", 'port': "port" in interfaceObj.attrs ? interfaceObj.attrs.port : "", } interfaceModel.insert(interfaceModel.count - 1, obj) if(obj.auto == "true") { interfaceManager.startAutoReconnect(obj.id) } } } } function getAvailablePorts(){ serialPorts = common.getComList() } Dialog{ id: dialog visible: false anchors.centerIn: parent width : 465 height: 230 title: "添加接口" onAccepted:{ createInterface({ name: tfInterfaceName.text, type: interfacetypes[cbInterfaceType.currentIndex] }) dialog.close() } contentItem:Rectangle{ Column{ spacing: 15 anchors.centerIn: parent Item { width: 332 height: 32 Text { text: "名称" } TextField { id: tfInterfaceName width: 286 height: 32 selectByMouse: true anchors.right: parent.right } } Item { width: 332 height: 32 Text { text: "类型" } ComboBox{ id: cbInterfaceType width: 286 height: 32 anchors.right: parent.right } } Item { width: 332 height: 50 Row { anchors.centerIn: parent spacing: 21 Button{ text:"添加" width: 80 height: 32 onClicked: dialog.accepted() } Button{ text:"取消" width: 80 height: 32 onClicked: dialog.close() } } } } } } Dialog{ id: deleteDialog visible: false property var index: 0 anchors.centerIn: parent width : 342 height: 160 title: "提示" onAccepted:{ deleteInterface(index) deleteDialog.close() } contentItem:Rectangle{ Column { anchors.centerIn: parent spacing: 30 Item{ width: 181 height: 32 Text{ anchors.centerIn: parent font.pointSize: 12 text: "是否继续删除?" } } Item { width: 181 height: 32 Row { anchors.centerIn: parent spacing: 10 Button{ text:"确定" width: 80 height: 32 onClicked: deleteDialog.accepted() } Button{ text:"取消" width: 80 height: 32 onClicked: deleteDialog.close() } } } } } } Dialog{ id: connectErrorDialog visible: false property var index: 0 anchors.centerIn: parent width : 270 height: 160 title: "提示" onAccepted:{ deleteInterface(index) deleteDialog.close() } contentItem:Rectangle{ Column { anchors.centerIn: parent spacing: 30 Text{ font.pointSize: 12 text: " 连接失败" } Button{ text:"确定" width: 80 height: 32 onClicked: connectErrorDialog.close() } } } } }