笔记

  在Qt 开发过程中,多线程是应用非常普遍的,GUI进程与数据处理进程分离,防止界面冻结卡死;

  Qt 的多线程有两种方法,一种是重写虚函数run的方法,另一种是使用 moveToThread的方法,本文以第二种为例;

效果图:
161453.png

程序、界面构思:

  • 主界面布置两个内容输出框;
  • 主界面线程开启一个定时器,定时往输出框① 输出内容;
  • 子线程发送两个信号,一个带参数,一个不带参数;
  • 带参数的在输出框① 显示;不带参数的在输出框② 显示;

54925.png

首先,先创建一个包含UI的主界面Widget对象,再Add new -> C++ Class,新建一个子线程对象Sub_thread,继承QObject ;

151215.png

Widget中实例化定时器对象;

    //主界面定时器实例化;
    main_timer = new QTimer(this);
    //连接信号槽;
    connect(main_timer, SIGNAL(timeout()), this, SLOT(Timeout_Update_GUI()));

在主Widget中,实例化子线程对象,和子线程,然后连接信号槽:

    //实例化子线程对象;
    sub_process = new Sub_thread();
    //实例化子线程;
    sub_thread = new QThread();
    //将子线程对象,移到子线程中处理;
    sub_process->moveToThread(sub_thread);

    //连接信号槽,
    /* 主界面:Widget, 启动信号:start_sub_signals,
     *  子线程对象:sub_process, 槽函数:init_subthread
     */
    connect(this, &Widget::start_sub_signals, sub_process, &Sub_thread::init_subthread);

    //子线程定时更新信号,传给主界面;——不带参数
    /* 子线程对象:sub_process, 信号:send2GUI_nodate,
     *  主界面对象:Widget, 槽函数:Sub_Update_GUI
     */
    connect(sub_process, &Sub_thread::send2GUI_nodate, this, &Widget::Update_GUI);

    //子线程自定义更新信号,传给主界面;——带参数;
    /* 子线程对象:sub_process, 信号:send2GUI_data,
     *  主界面对象:Widget, 槽函数:Sub_Update_GUI_data
     */
    connect(sub_process, &Sub_thread::send2GUI_data, this, &Widget::Update_GUI_data);

    //关闭窗口,注销线程
    connect(this, &Widget::destroyed, this, &Widget::close_thread);

Widget 定时器回调实现,与子线程响应函数;

//定时器回调实现
void Widget::Timeout_Update_GUI()
{
    ui->main_TextEdit->setTextColor(QColor("black"));
    //ui->main_TextEdit->setPlainText("主界面定时器更新");

    QString strData;

    strData = QString("时间[%1]: ").arg(TIMEMS);
    strData.append("GUI 定时器更新");

    ui->main_TextEdit->append(strData);
}


//子线程信号更新GUI , 不带参数;
void Widget::Update_GUI()
{
    ui->sub_TextEdit->setTextColor(QColor("red"));

    QString strData;

    strData = QString("时间[%1]: ").arg(TIMEMS);
    strData.append("子线程信号到达!");

    ui->sub_TextEdit->append(strData);


}

//子线程信号更新GUI, 带参数;
QString Widget::Update_GUI_data(QString  data)
{
    QString temp = data;

    ui->main_TextEdit->setTextColor(QColor("green"));

    QString strData;

    strData = QString("时间[%1]: ").arg(TIMEMS);
    strData.append("子线程信号带参数:");
    strData.append(temp);

    ui->main_TextEdit->append(strData);

    return 0;
}



  子线程定时器实例化,及定时器回调的实现;

//子线程初始化;
void Sub_thread::init_subthread()
{
    //在这里初始化子线程;
    qDebug() << "子线程ID线程为:" << QThread::currentThreadId();

    //实例化子线程定时器
    sub_timer = new QTimer();   //不能 this;
    //连接信号槽, 定时更新发送子线程数据;
    connect(sub_timer, SIGNAL(timeout()), this, SLOT(Timeout_send_data()));

    sub_timer->start(1000);     //子线程1s钟给GUI 发送一个信号;

}

//子线程定时器回调实现;
void Sub_thread::Timeout_send_data()
{

    counts ++;
    //发送子线程带参数信号;
    emit send2GUI_data(QString::number(counts));

    //子线程不带参数信号
    emit send2GUI_nodate();
}

需要源码的请留言,稍后打包上传

最后修改:2021 年 07 月 14 日
您的支持就是我持续更新的动力!