|
|
/******************************************************************
|
|
|
Copyright © Deng Zhimao Co., Ltd. 1990-2030. All rights reserved.
|
|
|
* @projectName tcpserver
|
|
|
* @brief TcpServer.qml
|
|
|
* @author Deng Zhimao
|
|
|
* @email 1252699831@qq.com
|
|
|
* @date 2020-07-31
|
|
|
*******************************************************************/
|
|
|
import QtQuick 2.9
|
|
|
import QtQuick.Window 2.2
|
|
|
import mytcpserver 1.0
|
|
|
import QtQuick.Layouts 1.1
|
|
|
import QtQuick.Controls 2.0
|
|
|
import QtQuick.Controls.Styles 1.4
|
|
|
import QtQuick 2.12
|
|
|
import QtQuick.VirtualKeyboard 2.2
|
|
|
import "../helpbutton"
|
|
|
|
|
|
Item {
|
|
|
visible: false
|
|
|
id: window
|
|
|
property int bottomDistance: 0
|
|
|
property string netWorkInfo: ""
|
|
|
property string connectSate : "请先与客户端连接"
|
|
|
|
|
|
HelpMessages {
|
|
|
anchors.fill: parent
|
|
|
z: 105
|
|
|
appIcon: WINStyle ? "" : "qrc:/desktop/androidstyleicons/tcpserver.png"
|
|
|
appName: "Tcp服务端"
|
|
|
appVersion: "Version 1.0.0"
|
|
|
subtoolText: "1.此软件为tcp服务器,点击聊天中的人物头像可获取本机的ip信息,可断开服务端的连接,清空聊天记录等。
|
|
|
2.请先用本机上的客户端连接或者手机下载一个tcp通信软件连接该软件,连上后就可以互相发信息聊天!"
|
|
|
versionText: "1.【Version 1.0.0 2020-10-06】。\n初始版本"
|
|
|
}
|
|
|
|
|
|
onVisibleChanged: {
|
|
|
formState.state == 'right' ? formState.state = '' : formState.state = 'right'
|
|
|
}
|
|
|
|
|
|
Component.onCompleted: {
|
|
|
mainListview.model.insert(mainListview.model.count,{"detail":"您好!我是TCP服务端小胖子,请先用客户端连接,点击我头像可获取连接信息",
|
|
|
"messageBg":"qrc:/tcpserver/images/rightMessagebg.png",
|
|
|
"fatherMirroring":false,"childrenMirroring":false,
|
|
|
"headPhotoImage":"qrc:/tcpserver/images/boy.jpg",
|
|
|
"messBackground":"#b8fa99"})
|
|
|
mainListview.currentIndex = mainListview.count - 1
|
|
|
netWorkInfo = tcpserver.getLocalIpAddress()
|
|
|
window.x = parent.width
|
|
|
}
|
|
|
Item {
|
|
|
id: formState
|
|
|
states: State {
|
|
|
name: "right"
|
|
|
PropertyChanges {
|
|
|
target: window
|
|
|
x: 0
|
|
|
}
|
|
|
}
|
|
|
transitions: Transition {
|
|
|
NumberAnimation {
|
|
|
property: "x"
|
|
|
easing.type: Easing.InOutQuart
|
|
|
duration: 500
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
MyTcpserver{
|
|
|
id: tcpserver
|
|
|
onRecMessageChanged: {
|
|
|
// listmodel.append({"detail":tcpserver.recMessage})
|
|
|
mainListview.model.insert(mainListview.model.count,{"detail":tcpserver.recMessage,
|
|
|
"messageBg":"qrc:/tcpserver/images/leftMessagebg.png",
|
|
|
"fatherMirroring":true,"childrenMirroring":true,
|
|
|
"headPhotoImage":"qrc:/tcpserver/images/gril.jpg",
|
|
|
"messBackground":"#e3e3f8"})
|
|
|
mainListview.currentIndex = mainListview.count - 1
|
|
|
}
|
|
|
onNewConnetChanged:{
|
|
|
connectSate = "断开连接"
|
|
|
mainListview.model.insert(mainListview.model.count,{"detail":tcpserver.newConnet,
|
|
|
"messageBg":"qrc:/tcpserver/images/rightMessagebg.png",
|
|
|
"fatherMirroring":false,"childrenMirroring":false,
|
|
|
"headPhotoImage":"qrc:/tcpserver/images/boy.jpg",
|
|
|
"messBackground":"#b8fa99"})
|
|
|
mainListview.currentIndex = mainListview.count - 1
|
|
|
}
|
|
|
}
|
|
|
|
|
|
ListView{
|
|
|
add: Transition {
|
|
|
// 设置增加Item时的动画 from 100,100 to不设置 就是默认在ListView
|
|
|
NumberAnimation { properties: "x,y"; from: window.height; duration: 200 }
|
|
|
}
|
|
|
id: mainListview
|
|
|
anchors.top: parent.top
|
|
|
anchors.topMargin: 30
|
|
|
anchors.bottom: bottomrect.top
|
|
|
anchors.bottomMargin: 10
|
|
|
anchors.left: parent.left
|
|
|
anchors.right:parent.right
|
|
|
highlightFollowsCurrentItem: true
|
|
|
spacing: 30
|
|
|
MouseArea{
|
|
|
width: parent.width - 120
|
|
|
height: parent.height
|
|
|
anchors.centerIn: parent
|
|
|
onClicked: textfield.focus = false
|
|
|
}
|
|
|
delegate: Component{
|
|
|
Rectangle{
|
|
|
LayoutMirroring.enabled: fatherMirroring
|
|
|
LayoutMirroring.childrenInherit: childrenMirroring
|
|
|
height: label1.lineCount * 12 + 35
|
|
|
implicitWidth: fitWidth(label1.text) > window.width * 0.2
|
|
|
? Math.min(fitWidth(label1.text), window.width * 0.2) + 60 : label1.implicitWidth + 80
|
|
|
color:"transparent"
|
|
|
anchors.right: parent.right
|
|
|
anchors.rightMargin: 0
|
|
|
Image {
|
|
|
anchors.right: parent.right
|
|
|
width: 40
|
|
|
height: 40
|
|
|
id: headPhoto
|
|
|
source: headPhotoImage
|
|
|
MouseArea {
|
|
|
anchors.fill: parent
|
|
|
onClicked: {
|
|
|
// state属性值为空字符串时('')即默认状态
|
|
|
onClicked: container.state == 'right' ? container.state = '' : container.state = 'right'
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
Rectangle{
|
|
|
id: myMessbg
|
|
|
width: parent.width - 60
|
|
|
anchors.top: parent.top
|
|
|
anchors.left: parent.left
|
|
|
anchors.bottom: parent.bottom
|
|
|
color: messBackground //"#b8fa99"
|
|
|
radius: 5
|
|
|
Item{
|
|
|
anchors.left: myMessbg.left
|
|
|
anchors.leftMargin: 10
|
|
|
anchors.right: myMessbg.right
|
|
|
anchors.rightMargin: 10
|
|
|
anchors.verticalCenter: parent.verticalCenter
|
|
|
Text{
|
|
|
id: label1
|
|
|
anchors.fill: parent
|
|
|
verticalAlignment: Text.AlignVCenter
|
|
|
wrapMode: fitWidth(label1.text) >= window.width*0.2 ? Text.WrapAnywhere:Text.NoWrap
|
|
|
text: detail
|
|
|
font.pixelSize: 12
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
BorderImage{
|
|
|
id: mebg
|
|
|
source: messageBg
|
|
|
anchors.left: myMessbg.right
|
|
|
anchors.leftMargin: 0
|
|
|
width: 5
|
|
|
height: 10
|
|
|
anchors.verticalCenter: myMessbg.verticalCenter
|
|
|
smooth: true
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
model:ListModel{
|
|
|
id:listmodel
|
|
|
// ListElement{
|
|
|
// detail:"请先连接服务器"
|
|
|
// }
|
|
|
}
|
|
|
}
|
|
|
|
|
|
function fitWidth(text){
|
|
|
return fontMetrics.advanceWidth(text)
|
|
|
}
|
|
|
|
|
|
function qmlsendMessage(){
|
|
|
if(textfield.text != ""){
|
|
|
//listmodel.append({"detail":textfield.text})
|
|
|
mainListview.model.insert(mainListview.model.count,{"detail":textfield.text,
|
|
|
"messageBg":"qrc:/tcpserver/images/rightMessagebg.png",
|
|
|
"fatherMirroring":false,"childrenMirroring":false,
|
|
|
"headPhotoImage":"qrc:/tcpserver/images/boy.jpg",
|
|
|
"messBackground":"#b8fa99"})
|
|
|
mainListview.currentIndex = mainListview.count - 1
|
|
|
tcpserver.sendMessage(textfield.text)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
FontMetrics {
|
|
|
id: fontMetrics
|
|
|
//font.family: "Arial"
|
|
|
}
|
|
|
|
|
|
// 底部
|
|
|
Rectangle{
|
|
|
z: 55
|
|
|
height: 40
|
|
|
anchors.bottom: pannelbg.top
|
|
|
//anchors.bottomMargin: bottomDistance
|
|
|
id: bottomrect
|
|
|
Row{
|
|
|
TextField{
|
|
|
id: textfield
|
|
|
placeholderText: "输入内容"
|
|
|
height: bottomrect.height
|
|
|
width: window.width * 0.8
|
|
|
Keys.enabled: true
|
|
|
font.pixelSize: 13
|
|
|
color: "white"
|
|
|
Keys.onReturnPressed : qmlsendMessage()
|
|
|
onFocusChanged: {
|
|
|
if(inputPanel.state == 'visible' )
|
|
|
container.state = ''
|
|
|
}
|
|
|
background: Rectangle{
|
|
|
color: "transparent"
|
|
|
Rectangle {
|
|
|
anchors.bottom: parent.bottom
|
|
|
width: parent.width
|
|
|
color: textfield.focus ? "#27d7f0" : "gray"
|
|
|
height: textfield.focus ? 2 : 1
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
Button{
|
|
|
text:"发送(或者按回车键)"
|
|
|
height: bottomrect.height
|
|
|
width: window.width * 0.2
|
|
|
onClicked: {
|
|
|
qmlsendMessage()
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
Rectangle{
|
|
|
z: 88
|
|
|
id: pannelbg
|
|
|
width: parent.width
|
|
|
anchors.bottom: inputPanel.top
|
|
|
height: inputPanel.state == "visible" ? bottomDistance = 30 * window.height / 480 : 0
|
|
|
color: "black"
|
|
|
}
|
|
|
InputPanel {
|
|
|
id: inputPanel
|
|
|
z: 88
|
|
|
//x: -11
|
|
|
y: window.height
|
|
|
width: window.width
|
|
|
visible: parent.visible
|
|
|
states: State {
|
|
|
name: "visible"
|
|
|
when: inputPanel.active
|
|
|
PropertyChanges {
|
|
|
target: inputPanel
|
|
|
y: window.height - inputPanel.height
|
|
|
}
|
|
|
}
|
|
|
transitions: Transition {
|
|
|
from: ""
|
|
|
to: "visible"
|
|
|
reversible: true
|
|
|
ParallelAnimation {
|
|
|
NumberAnimation {
|
|
|
properties: "y"
|
|
|
duration: 250
|
|
|
easing.type: Easing.InOutQuad
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
Item {
|
|
|
id: container
|
|
|
states: State {
|
|
|
name: "right"
|
|
|
// rect水平移动
|
|
|
PropertyChanges {
|
|
|
target: boyInfo
|
|
|
x: parent.width * (smallScreen ? 0.50 : 0.65)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
transitions: Transition {
|
|
|
// 数字(x坐标)动画,设置了easing的回弹效果和动画时间
|
|
|
NumberAnimation {
|
|
|
property: "x"
|
|
|
easing.type: Easing.InOutQuart
|
|
|
duration: 1000
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
Item {
|
|
|
id: boyInfo
|
|
|
z: 40
|
|
|
width: parent.width * (smallScreen ? 0.50 : 0.35)
|
|
|
height: parent.height
|
|
|
x: parent.width
|
|
|
Flickable {
|
|
|
id: myflickable
|
|
|
anchors.fill: parent
|
|
|
contentWidth: parent.width
|
|
|
contentHeight: parent.height +(smallScreen ? 208 : 20)
|
|
|
Rectangle{
|
|
|
anchors.fill: parent
|
|
|
color: "#cc424242"
|
|
|
MouseArea {
|
|
|
anchors.fill: parent
|
|
|
onClicked: {
|
|
|
// state属性值为空字符串时('')即默认状态
|
|
|
onClicked: container.state == 'right' ? container.state = '' : container.state = 'right'
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
Image {
|
|
|
id: boyID
|
|
|
source: "qrc:/tcpserver/images/boy.jpg"
|
|
|
width: 50
|
|
|
height: 50
|
|
|
anchors.left: parent.left
|
|
|
anchors.leftMargin: 20
|
|
|
anchors.top: parent.top
|
|
|
anchors.topMargin: 30
|
|
|
}
|
|
|
Text {
|
|
|
id: juese
|
|
|
anchors.left: boyID.right
|
|
|
anchors.leftMargin: 20
|
|
|
anchors.top: boyID.top
|
|
|
text: qsTr("角色:TCP服务器")
|
|
|
color: "white"
|
|
|
font.bold: true
|
|
|
font.pixelSize: 15
|
|
|
}
|
|
|
Text {
|
|
|
id: idName
|
|
|
text: qsTr("I D:小胖子\n监听端口:888")
|
|
|
lineHeightMode: Text.FixedHeight //设置行间距 以像素的方式设置
|
|
|
lineHeight: 18 //行间距比例 最大 1
|
|
|
anchors.left: juese.left
|
|
|
anchors.top: juese.bottom
|
|
|
anchors.topMargin: 5
|
|
|
color: "#99eeeeee"
|
|
|
font.bold: true
|
|
|
font.pixelSize: 14
|
|
|
}
|
|
|
Text {
|
|
|
anchors.top: boyID.bottom
|
|
|
anchors.topMargin: 30
|
|
|
anchors.horizontalCenter: parent.horizontalCenter
|
|
|
id: networkMess
|
|
|
text: netWorkInfo
|
|
|
color: "#28dcf7"
|
|
|
font.bold: true
|
|
|
font.pixelSize: 13
|
|
|
}
|
|
|
Button{
|
|
|
id: refreshBtn
|
|
|
anchors.top: networkMess.bottom
|
|
|
anchors.horizontalCenter: parent.horizontalCenter
|
|
|
width: 40
|
|
|
height: 40
|
|
|
background: Rectangle{
|
|
|
color: "transparent"
|
|
|
Image {
|
|
|
//anchors.fill: parent
|
|
|
anchors.centerIn: parent
|
|
|
id: refresh
|
|
|
source: "qrc:/tcpserver/images/refresh.png"
|
|
|
}
|
|
|
}
|
|
|
onClicked: {
|
|
|
netWorkInfo = "正在读取本地网卡信息,请稍候..."
|
|
|
refreshAnima.running = true
|
|
|
}
|
|
|
}
|
|
|
RotationAnimator {
|
|
|
id: refreshAnima
|
|
|
target: refreshBtn
|
|
|
from: 0
|
|
|
to: 360
|
|
|
duration: 1000
|
|
|
//loops: Animation.Infinite
|
|
|
running: false
|
|
|
onRunningChanged: {
|
|
|
if (running === false) {
|
|
|
from = refreshBtn.rotation;
|
|
|
to = from+360;
|
|
|
}
|
|
|
}
|
|
|
onStopped: {
|
|
|
netWorkInfo = tcpserver.getLocalIpAddress()
|
|
|
}
|
|
|
}
|
|
|
Button{
|
|
|
id: clearMessage
|
|
|
anchors.top: refreshBtn.bottom
|
|
|
//anchors.topMargin: -20
|
|
|
anchors.horizontalCenter: parent.horizontalCenter
|
|
|
width: 120
|
|
|
height: 35
|
|
|
background: Rectangle{
|
|
|
color: "transparent"
|
|
|
radius: 20
|
|
|
border.color: "#28dcf7"
|
|
|
border.width: 1
|
|
|
Text {
|
|
|
anchors.centerIn: parent
|
|
|
id: clearText
|
|
|
text: qsTr("清空所有聊天记录")
|
|
|
font.pixelSize: 13
|
|
|
color: clearMessage.pressed ? "white":"#28dcf7"
|
|
|
}
|
|
|
}
|
|
|
onClicked: {
|
|
|
if(mainListview.count != 0)
|
|
|
mainListview.model.clear()
|
|
|
mainListview.model.insert(mainListview.model.count,{"detail":"已经清空!",
|
|
|
"messageBg":"qrc:/tcpserver/images/rightMessagebg.png",
|
|
|
"fatherMirroring":false,"childrenMirroring":false,
|
|
|
"headPhotoImage":"qrc:/tcpserver/images/boy.jpg",
|
|
|
"messBackground":"#b8fa99"})
|
|
|
mainListview.currentIndex = mainListview.count - 1
|
|
|
}
|
|
|
}
|
|
|
|
|
|
Button{
|
|
|
id: disConetFromClient
|
|
|
anchors.top: clearMessage.bottom
|
|
|
anchors.topMargin: 10
|
|
|
anchors.horizontalCenter: parent.horizontalCenter
|
|
|
width: 120
|
|
|
height: 35
|
|
|
background: Rectangle{
|
|
|
color: "transparent"
|
|
|
radius: 20
|
|
|
border.color: "#28dcf7"
|
|
|
border.width: 1
|
|
|
Text {
|
|
|
anchors.centerIn: parent
|
|
|
id: disConetText
|
|
|
text: connectSate
|
|
|
color: disConetFromClient.pressed ? "white":"#28dcf7"
|
|
|
font.pixelSize: 13
|
|
|
}
|
|
|
}
|
|
|
onClicked: {
|
|
|
tcpserver.disConnect()
|
|
|
connectSate = "已断开连接"
|
|
|
}
|
|
|
}
|
|
|
|
|
|
}
|
|
|
}
|
|
|
}
|