昨晚在做ModBus的时候遇到了两个问题,第一个是tcpsocket突然无法发送数据了,显示tcpsocket无法跨进程调用;第二个是编译时一直显示无法访问QObject的私有变量。


一、QTcpSocket无法跨进程调用的问题

当时的情况是这样的,经过两天的思考与实现之后,程序突然无法收到从RTU返回的信息了,两天前同样的收集线程程序明明可以的。找了半天到底是哪里出了问题。

最后发现问题是出在启动线程的start()函数上,之前我的所有线程都是在主线程初始化的时候就start。主进程里面有线程的对象(不是指针),线程的对象会随着主进程初始化而初始化,tcpsocket对象(不是指针)在线程初始化的时候初始化,同时通过tcp/ip连接模拟程序。这样线程初始化完成之后就立刻开始运行。

后来我写了一个按钮响应,把线程的start()给挪到按钮响应里去了,这样之后每次tcpsocket发送数据的时候就是出错,输出“tcpsocket无法跨线程调用”,于是我又把start给挪回构造函数里了,下一步准备试一下在按钮响应里面new一个线程的对象。

这个问题我觉得可能是因为主进程和线程的关系的原因?


二、无法访问QObject私有变量

这个问题其实是发生在上一个问题之前的,这个问题在之前的我看来其实是蛮无厘头的。光说可能没啥感觉,上个图先。
qobjectclass.png

上图就是这次问题的三个主角,DataBlockCollectionThreadDBManager需要交代的是DataBlock这个主角中的主角是一个关系户,他爸爸是QObject(传说中Qt大家庭里面大部分人的爷爷or太爷爷...) 也就是说DataBlock直接继承自QObject。然后编译的时候就一直提示我“无法访问QObject的私有成员”,我还真信了,跑去看了几个DataBlock里面的变量,后来想不可能啊,以我这奇葩的命名方式,怎么可能会那么巧合的重名!于是我百度了。

然后我发现是因为QObject不允许copy或者opeartor=,然后我看了看我的代码,果真有地方用了等于号。

本来是想借用Qt的QObject的管理机制来管理这个DataBlock的,原来这么多限制, 于是就取消了DataBlock和QObject的父子关系, 于是就不让DataBlock继承QObject了,也不用Q_OBJECT宏了。这样就解决了。

需要注意的是之前我以为必须纳入Qt的体系中才可以用QList管理数据,现在发现不需要纳入Qt的体系也可以用QList管理数据。


三、在非QObject子类中使用connect函数

(2015.10.20补充)
今天我又遇到Qobject的子类不能copy和operator=的问题了,但是我需要在那个类里面使用connect函数连接槽函数和消息,这该怎么办呢?

我想了一个麻烦的办法和一个简单的办法。麻烦的办法就是传给它一个是Qobject子类的对象的指针,用这个指针来调用connect函数。

简单的办法有效,所以我就没有尝试麻烦的办法究竟可行不可行,QObject::connect(...),这样就行了。
我理解的qt程序是都运行在一个core上,所以只需要通知它绑定了什么信号和槽就行了。


liyu34
43 声望1 粉丝

软件工程在读研究生一枚