1. 利用TCP/IP实现QML与Python通信

1. 说明

本篇文章的***主要功能:***使用QML搭建客户端,使用Python搭建服务端,利用TCP/IP通信方式建立客户端和服务端之间的连接。***作用:***某些情况下,虽然使用QT做了软件开发,但是在工业领域的机器人控制当中有可能需要Python脚本区执行自动化功能,所以需要建立两者之间的通信,达软件界面间接控制机器人的效果。
效果展示:

Qml_Tcp_Python

2. 相关代码如下:

客户端Qt代码
main.qml:

import QtQuick 2.9
import QtQuick.Window 2.2
import QtQuick.Controls 2.2
import QtQuick.Layouts 1.0

Window {
    id: window
    visible: true
    width: 300
    height: 300
    title: qsTr("Hello World")

    Connections{
        target: tcpPython
        onMessagerecived:{	//响应TcpForPython.cpp中的信号,注意和TCP通信区分开
            element2.text = mStr
        }
    }

    Button {
        id: button
        x: 171
        y: 46
        text: qsTr("Connect")
        onClicked: {
        	//点击请求TCP连接
            tcpPython.newConnect(textInput.text,textInput1.text)
        }
    }
    Rectangle{
        id:btline
        anchors.left: textInput.left
        anchors.right: textInput.right
        anchors.top: textInput.bottom
        height: 1
        color: "black"

    }
    Rectangle{
        id:btline2
        x: -23
        y: -41
        anchors.left: textInput1.left
        anchors.right: textInput1.right
        anchors.top: textInput1.bottom
        height: 1
        color: "black"
    }
    Rectangle{
        id:btline3
        anchors.left: textInput2.left
        anchors.right: textInput2.right
        anchors.top: textInput2.bottom
        height: 1
        color: "black"
    }

    Text {
        id: element
        x: 15
        y: 42
        text: qsTr("IP:")
        verticalAlignment: Text.AlignVCenter
        horizontalAlignment: Text.AlignHCenter
        Layout.preferredHeight: 16
        Layout.preferredWidth: 21
        font.pixelSize: 12
    }

    TextInput {
        id: textInput
        x: 41
        y: 40
        verticalAlignment: Text.AlignVCenter
        horizontalAlignment: Text.AlignHCenter
        width: 80
        height: 20
        font.pixelSize: 12
    }

    Text {
        id: element1
        x: 15
        y: 68
        text: qsTr("Port:")
        verticalAlignment: Text.AlignVCenter
        horizontalAlignment: Text.AlignHCenter
        font.pixelSize: 12
    }

    TextInput {
        id: textInput1
        x: 47
        y: 65
        width: 80
        height: 20
        verticalAlignment: Text.AlignVCenter
        horizontalAlignment: Text.AlignHCenter
        font.pixelSize: 12
    }

    Text {
        id: element2
        x: 36
        y: 126
        width: 242
        height: 64
        anchors.horizontalCenter: parent.horizontalCenter
        anchors.verticalCenter: parent.verticalCenter
        verticalAlignment: Text.AlignVCenter
        horizontalAlignment: Text.AlignHCenter
        font.pixelSize: 12
    }

    TextInput {
        id: textInput2
        x: 29
        y: 263
        width: 135
        height: 20
        font.pixelSize: 12
        selectByMouse: true
        verticalAlignment: Text.AlignVCenter
        horizontalAlignment: Text.AlignHCenter
    }

    Button {
        id: button1
        x: 171
        y: 253
        text: qsTr("Send")
        onClicked: {
        	//点击发送数据到服务器端
            tcpPython.sendMsg(textInput2.text)
        }
    }

}

TcpForPython.h

#ifndef TCPFORPYTHON_H
#define TCPFORPYTHON_H

#include <QObject>
#include <QTcpSocket>

class TcpForPython : public QObject
{
    Q_OBJECT
public:
    explicit TcpForPython(QObject *parent = nullptr);

    ~ TcpForPython();

    Q_INVOKABLE void newConnect(QString mIp,QString mPort); //请求连接(QML调用)
    Q_INVOKABLE void sendMsg(QByteArray mStr);  //发送数据(QML调用)
    
signals:
    void messagerecived(QString mStr); //接收到信息,发送信号告知QML

private:

    QTcpSocket *tcpSocket;

    QString messageRead;    //读数据
    QByteArray messageWrite; //发数据

private slots:
    void readMessage();  //接收数据

};

#endif // TCPFORPYTHON_H

TcpForPython.cpp

#include "tcpforpython.h"

TcpForPython::TcpForPython(QObject *parent) : QObject(parent)
{
    tcpSocket = new QTcpSocket(this);

    //建立连接后,检测到有数据发送过来时,调用读取函数
    connect(tcpSocket,SIGNAL(readyRead()),this,SLOT(readMessage()));
}

TcpForPython::~TcpForPython()
{
    tcpSocket->close();
}

void TcpForPython::newConnect(QString mIp, QString mPort)
{
    tcpSocket->abort(); //取消已有的连接

    tcpSocket->connectToHost(mIp,mPort.toInt()); //请求连接
}

void TcpForPython::sendMsg(QByteArray mStr)
{
    messageWrite = mStr;

    tcpSocket->write(messageWrite); //发送数据

}

void TcpForPython::readMessage()
{
    //读取1024个字节大小
    messageRead = tcpSocket->read(1024);
    emit messagerecived(messageRead); //接收到信息,发送信号告知QML

}

注意需要将上面的自定义C++类注册到QML的上下文背景中…
服务端Python代码

import socket

# 创建 socket 对象
serversocket = socket.socket(
    socket.AF_INET, socket.SOCK_STREAM)

# 获取本地主机名
host = '127.0.0.1' # 注意:如果上面的客户端是在Windows系统中运行的,则这里的 host = '192.168.244.140',总之host必须要和服务端所在主机相对应,否则连接失败
port = 8888

# 绑定端口号
serversocket.bind((host, port))

# 设置最大连接数,超过后排队
serversocket.listen(1)

if __name__ == "__main__":
    # 建立客户端连接
    clientsocket, addr = serversocket.accept()  # 接受连接,并获取socket和连接地址(ip,port)
    print("连接地址: %s" % str(addr))
    # 发送数据
    msg = 'hello! this is python,ha ha ha....'
    clientsocket.send(msg.encode('utf-8'))
    while True:
        # 循环接受数据
        msg = clientsocket.recv(1024)
        print(msg.decode('utf-8'))
        # 关闭连接
        if msg.decode("utf-8") == "4":
            print("连接关闭...")
            clientsocket.close()

持续更新中,请大家多多关注…

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

山间点烟雨

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值