qt连接sqlserver地址错误卡顿_Qt应用编程中,常用链路的封装

在面向设备的应用编程当中,各种各样的链路传输功能是非常常用的,并且是完全无关于业务的工具代码,在之前的工作当中,结合自己的经验,同时也参考和借鉴了一些开源库的逻辑,这里值得一提的是QGroundControl,我承认之前在一开始的时候,在项目中我是直接照搬它的逻辑的,但是后来在使用的过程当中,发现了一些问题,便做出了一些修改和完善(PS:当然我会在以后的日子里继续完善),使其可以更加通用于一般的面向设备的应用编程。

项目地址:

huxingqun/HsrComponents​github.com
61d92e013fbc58a43925fe22c8ec61f2.png

有啥

我把该链路模块称之为link,link代码结构上属于HsrCore库中,目前link中只是封装了tcp,udp,serialport三种链路;

特点

  • 三种链路都是基于线程实现的异步,起一个链路相当于一个线程,封装成异步的链路主要是为了防止在GUI线程当中发送数据时候,由于IO阻塞导致的界面卡顿情况;
  • 底层的网络IO和串口IO使用的都是Qt库,当然有兴趣的话可以使用其他的库代替,目前在终端应用编程当中,Qt的这些IO库是够用的了;
  • 参考了QGroundControl的链路实现,但是经过自己在工作和学习当中的修改和完善之后,比QGroundControl的更加精简,灵活,易用;
  • 发送数据和接收数据接口底层异步实现;
  • 从链路中接收数据可以任意选择信号槽的方式和回调的方式,链路类既提供了信号来分发从IO流中取出的数据,又提供了注册回调函数的方式来分发数据,两者可以同时使用,如果对接收到的数据实时性要求高,使用注册回调会好一些,并且可以在回调函数中进行数据初解析;

简单介绍

#ifndef HSRABSTRACTLINK_H
#define HSRABSTRACTLINK_H

#include <QThread>
#include <memory>
#include <functional>
#include "hsrcore_global.h"

// 链路数据回调函数
typedef std::function<void(const QByteArray& data)> ReceivedDataHandleFunc;

// udp通讯时候,暂时以ip来区分设备
typedef std::function<void(QString ip, QByteArray data)> UdpReceivedDataHandleFunc;

class HsrLinkAbstractConfig;
class HSRCORE_EXPORT HsrAbstractLink : public QObject
{
  Q_OBJECT

public:
  enum LinkOperateState {
    LINK_UNKNOW = 0,			//未知
    LINK_OPEN_FAILED = 1,		//打开失败
    LINK_OPEN_SUCCESSED = 2,	//打开成功
    LINK_CLOSED = 3,			//已关闭
  };
    explicit HsrAbstractLink(QObject* parent = nullptr);
    virtual ~HsrAbstractLink();

  virtual bool start() = 0;

  //! 打开连接
    virtual void open(const std::shared_ptr<HsrLinkAbstractConfig>& linkConfigPtr) = 0;

  //! 关闭连接
  virtual void close() = 0;

  //! 注册数据接收回调函数
  virtual void registerRecvdDataHandleFunc(ReceivedDataHandleFunc func);

  //! 取消注册数据接收回调函数
  virtual void unregisterRecvdDataHandleFunc();

  //! 是否已经打开
  virtual bool isOpen();

  //! 发送信息
  //! data 发送消息内容  消息长度
  virtual bool sendData(const QByteArray& data) = 0;

  //! 返回连接配置指针
    HsrLinkAbstractConfig* linkConfig();

signals:
  //! 准备工作信号,所有的操作都是基于该动作成功发出之后才可以进行
  void ready(bool success);

  //! 收到串口数据时候发出
  void dataReceived(QByteArray data);

  //! 打开连接结果
  //! opened: true 打开成功; false 打开失败
  void openLinkResp(bool opened);

  //! 通知连接已关闭
  void linkClosed();

protected slots:
  //响应打开回应
  void _respOpenLink(bool opened);

  //! 响应关闭连接
  void _respCloseLink();

protected:
    std::shared_ptr<HsrLinkAbstractConfig> m_linkconfig_ptr_;

  bool m_isopen_;					//记录link是否已经打开

  ReceivedDataHandleFunc m_recvd_data_handle_func_;

};

#endif

该类是所有链路的虚基类,可以看出,接口方法并不多,从注释上可以看出来就是打开、关闭、发送、注册回调以及一些通知信号,继承该基类的分别有三个派生类HsrTcpSocketLink、HsrUdpSocketLink以及HsrSerialPortLink分别对应三种链路方式;三种链路方式对应了三种配置分别是HsrTcpSocketLinkConfig、HsrUdpSocketLinkConfig以及HsrSerialPortLinkConfig,配置类也有一个共同的基类HsrLinkAbstractConfig,该基类主要有一个纯虚接口,主要是用来区分类型。

如何使用

这里简单拿串口链路来举例,这里举例就直接写用法:

  • 打开连接
HsrSerialPortLink* serialLink = new HsrSerialPortLink();
HsrSerialPortLinkConfig* serialCfg = new HsrSerialPortLinkConfig();
// 配置参数
serialCfg->setPortName("COM1");
serialCfg->setParity(QSerialPort::NoParity);
serialCfg->setBaudrate(QSerialPort::Baud115200);
serialCfg->setStopBits(QSerialPort::OneStop);
serialCfg->setFlowControl(QSerialPort::NoFlowControl);
// 打开串口
serialLink->open(std::shared_ptr<HsrLinkAbstractConfig>(serialCfg));
  • 发送数据
char data[5] = { 1,2,3,4,5 };
// 这里只是举例,实际使用时候可以序列化任何数据发出去
serialLink->sendData(QByteArray(data, 5));
  • 接收数据

方式1:使用信号槽的方式接收数据

// 这里为了演示方便,使用lambda表达式作为槽函数
QObject::connect(serialLink, &HsrSerialPortLink::dataReceived, [=] (QByteArray data){
    qDebug() << data.toHex();
  });

方式2:使用注册回调函数的方式接收数据,这里为了方便演示代码,使用lambda表达式作为回调函数,实际上这里可以使用全部函数或者任何的成员函数作为回调,只要你喜欢就可以

//同样是为了方便,使用lambda表达式作为回调函数
serialLink->registerRecvdDataHandleFunc([=](const QByteArray& data) {
    qDebug() << data.toHex();
  });
  • 关闭连接
serialLink->close();

结束语

虽然说这并不是什么很牛X的东西,但是自我感觉用起来还可以,并且在实际项目中一直在用,也一直会继续改善。如果对任何人有帮助,欢迎到github上去clone and star吧,同时有任何的批评和建议,欢迎Issue或者留言。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值