WhyCan Forum(哇酷开发者社区)

我们能随心所欲"有问题百度(谷歌)一下", 这得感谢为中文互联网持续输出优质内容的各位老铁们。 QQ: 516333132, 微信: whycan_cn (哇酷网/挖坑网/填坑网) service@whycan.cn

您尚未登录。

#1 2020-05-15 15:01:13

Gentlepig
会员
注册时间: 2018-10-24
累计积分: 436

请教,qt线程里读取的数据结构,如何发送出去?

新建了线程类,在线程类的run()函数里不停读取socketcan数据,成功后发送canReceived()信号。
可读取的是个结构体:

struct can_frame Rx_frame;
...
read(canSocket, &Rx_frame, sizeof(Rx_frame));

如果是把Rx_frame放到canReceived()信号的参数里,那么传递的是形参了吧?界面显示数据的时候,Rx_frame里的数据可能会变化吧?

离线

#2 2020-05-15 15:17:38

cgpsky
会员
注册时间: 2017-09-07
累计积分: 24

Re: 请教,qt线程里读取的数据结构,如何发送出去?

信号槽的连接方式有跨线程模式。 安全起见。 传参的形式用 copy 而不是引用或者指针即可

如果数据结构不支持 记得转成元类型

最近编辑记录 cgpsky (2020-05-15 15:19:16)

离线

#3 2020-05-15 16:30:13

kin
会员
注册时间: 2020-04-06
累计积分: 5

Re: 请教,qt线程里读取的数据结构,如何发送出去?

可以通过postEvent把Rx_frame以事件方式投递给目标对象,目标对象在event事件里可以取得这些内容

离线

#4 2020-05-15 16:31:38

Gentlepig
会员
注册时间: 2018-10-24
累计积分: 436

Re: 请教,qt线程里读取的数据结构,如何发送出去?

谢谢两位。

离线

#5 2020-05-15 17:17:12

Gentlepig
会员
注册时间: 2018-10-24
累计积分: 436

Re: 请教,qt线程里读取的数据结构,如何发送出去?

cgpsky 说:

信号槽的连接方式有跨线程模式。 安全起见。 传参的形式用 copy 而不是引用或者指针即可

如果数据结构不支持 记得转成元类型

我需要发送的结构体类型can_frame,不是我自定义的,好像是linux下就有的,是在can.h里定义的。我在我自定义的一个.h文件里,加了Q_DECLARE_METATYPE(can_frame);结果报错。总不能加到can.h里吧?

---------------------------------------------------------------

之前将Q_DECLARE_METATYPE(can_frame);放到类声明里了。试着放到类声明外面,并且改了下参数,结果不报错了。
Q_DECLARE_METATYPE(struct can_frame);

最近编辑记录 Gentlepig (2020-05-15 17:23:14)

离线

#6 2020-05-15 18:26:27

cgpsky
会员
注册时间: 2017-09-07
累计积分: 24

Re: 请教,qt线程里读取的数据结构,如何发送出去?

方法有二,用个结构包一层,定义对应的

离线

#7 2020-05-21 09:43:16

Gentlepig
会员
注册时间: 2018-10-24
累计积分: 436

Re: 请教,qt线程里读取的数据结构,如何发送出去?

又遇到问题了,再请教下。
我在线程里用socket接收,然后将接收到的数据作为信号的参数发送出去。
现在遇到的问题是,主界面下,在有can信号接收时,移动鼠标卡顿。尤其是突然来十几帧can信息时,鼠标基本卡住不动了。
我觉得是我线程里读取socket有问题,请大家看下我这样写对不对。

void CanRecvThread::run()
{
    int i, ret, ret1;
    struct can_frame Rx_frame;
    QVariant varCanRecv;
    
    qDebug() << "can recv thread run." << endl;

    while(1)
    {
        if(!canRunFlag)
        {
            qDebug() << "no can device in can recv thread." << endl;
            return;
        }
        ret1 = 0;
        while(ret1 < sizeof(Rx_frame))
        {
            ret = read(canSocket, &Rx_frame, sizeof(Rx_frame));
            if(ret == -1)
            {
                printf("recv error !! \n");
            }
            ret1 += ret;
            // printf("ret: %d\n", ret);
            // if(ret > 0)
            // {
                printf("\n can receive id = 0x%08X", Rx_frame.can_id&0x1FFFFFFF);
                printf("\n can receive dlc = %d", Rx_frame.can_dlc);
                for(i = 0; i < Rx_frame.can_dlc; i++)
                   printf(" 0x%02X", Rx_frame.data[i]);
                printf("\n");

                varCanRecv.setValue(Rx_frame);
                emit canReceived(varCanRecv);
                qDebug() << "emit canReceived." << endl;
            // }
        }
    }
}

-----------------------------

也尝试过把这个函数里的printf及qDebug()语句屏蔽掉,没有效果。

最近编辑记录 Gentlepig (2020-05-21 09:46:15)

离线

#8 2020-05-21 09:47:53

有梦的地方
会员
注册时间: 2020-03-17
累计积分: 203

Re: 请教,qt线程里读取的数据结构,如何发送出去?

while死循环里面加 usleep(30)

这样每次read之后可以切换到别的线程

离线

#9 2020-05-21 10:28:16

Gentlepig
会员
注册时间: 2018-10-24
累计积分: 436

Re: 请教,qt线程里读取的数据结构,如何发送出去?

有梦的地方 说:

while死循环里面加 usleep(30)

这样每次read之后可以切换到别的线程


其他设备是这样发送的:
每秒主动发送一个普通帧;
主机发送读取信息后,会一下子发送十几帧出去。

我用鼠标按圆形轨迹移动来判断是否卡顿。

之前不加sleep或usleep时:
每秒接收到信息后,鼠标卡顿一下;
点击读取按钮后发送信息出去,返回十几帧信息。此时鼠标基本卡住不动,大概几秒后才可以移动。

试了加sleep(1):
每秒接收信息后,鼠标仍卡顿一下;
点击读取按钮后发送信息出去,返回十几帧信息。但是因为是每秒读取一次了,所以也只是每秒卡顿一下。

试了加usleep(30):
每秒接收信息后,鼠标仍卡顿一下;
点击读取按钮后发送信息出去,返回十几帧信息。鼠标仍旧会卡住不动,大概几秒后才可移动。

最近编辑记录 Gentlepig (2020-05-21 10:36:47)

离线

#10 2020-05-21 10:41:04

歌以咏志
会员
注册时间: 2019-09-21
累计积分: 152

Re: 请教,qt线程里读取的数据结构,如何发送出去?

以前用 NUC972 跑 ucgui, 全屏刷的时候卡卡卡卡, 后来就换V3s了

离线

#11 2020-05-21 10:54:27

Gentlepig
会员
注册时间: 2018-10-24
累计积分: 436

Re: 请教,qt线程里读取的数据结构,如何发送出去?

主线程里接收到数据后,插入到qtablewidget的新行,然后qtablewidget滚动到最底部,并根据内容自适应列宽。

将qtablewidget滚动到最底部和自动调整列宽这两个语句屏蔽掉后,基本不卡顿了。
把qtablewidget的插入新行也屏蔽掉,就完全不卡顿了...

离线

页脚

工信部备案:粤ICP备20025096号-1 Powered by FluxBB