把函数放在线程中执行碰到的问题及解决:

技术背景:

首先,主类对象中,通过循环,创建最多20个进程,每个进程都会向主类进程返回字串,并且根据通过返回的字符串对进程进行相应的管理,比如,kill()及close(),两个函数位于接受消息函数中资信。接受消息函数通过readyReadStandardOutput()信号触发。问题是,这个消息处理函数中,在20多个进程同时返回消息的时候,在一些配置比较低的电脑中,会造成卡顿,所以考虑放进进程中进行处理。

在这个项目环境下,不考虑继承QObject使用movetoThread()和继承QThread直接重写run()的方法,理由:

因为在消息处理函数中,还需要使用到主进程中的其他的对象,比如QTextBrower,QLineEdit对象,如果使用这两种方法,目前我没有想到实现的方法。

所以考虑使用QFuture+QtConcurrent的形式,具体使用:

bool state = false;
    qRegisterMetaType<QTextCursor>("QTextCursor");
    QFuture<void> future = QtConcurrent::run(this, &run_bank::ReadData, sender(),state);
    while (!future.isFinished()) {
        QCoreApplication::processEvents();
    }
    if(state == true)
    {
        ((QProcess *)sender())->close();
        ((QProcess *)sender())->kill();
        if(((QProcess *)sender())->isOpen())
        {
            QMessageBox::information(this, "提示信息", "脚本还未正常关闭",QMessageBox::Yes, QMessageBox::Yes);
        }
    }

代码的说明:state是记录ReadData函数中处理得出的是否需要清楚进程的标志位。
之所以注册QTextCursor,是因为进程之间会使用到这个类型作为数据传输。这个传输是我使用的QTextEdit等对象中隐藏的,当我们通过QtConcurrent把函数放到单独的一个线程的时候,因为第三行的写法是执行的类中的方法,所以还是可以直接使用对象的,但是需要传递到主进程中,已经隐藏了数据传递过程。

出现的几个问题:

QObject::startTimer: Timers cannot be started from another thread
网上资料:每个QObject实例中,接受信号或者事件时,槽函数或者事件处理器将在对象所处的线程中执行。然后这个定时器是在线程类的构造函数中,我们在主进程中创建了一个对象,所以定时器是在主进程中的,而start()在线程中调用,所以会报错。
解决这个问题的方法:
1、在TestThread线程启动后创建定时器:线程在主进程中实例化,他的子对象也需要在主进程里创建,不能指定定时器的福对象为子线程。使用事件循环exec(),否则线程也会立即结束,并发出finished()信号。stop()也需要在线程中调用。
2、在主进程中创建,然后使用movetoThread()方法改变定时器多出的线程,不要给定时器设置父类,否则该函数将不会生效。
我使用的方法是第二种,直接QTimer *timer = new QTimer();不要继承this就行。

一般都不要继承this,否则我们在子进程或是什么定位设置了一个禁止接受消息,就会卡顿到timeout()信号,就会出问题。

QWinEventNotifier: Event notifiers cannot be enabled or disabled from another thread
出现这个问题主要就是因为if(state == true)之后的代码段,之前我的if函数体是放在QtConcurrent(线程安全)开启的单独线程中的,和主线程是不相关的,所以在QtConcurrent创建的线程中,会出现改错误。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值