在Qt 开发过程中,多线程是应用非常普遍的,GUI进程与数据处理进程分离,防止界面冻结卡死;
Qt 的多线程有两种方法,一种是重写虚函数run
的方法,另一种是使用 moveToThread
的方法,本文以第二种为例;
效果图:
程序、界面构思:
- 主界面布置两个内容输出框;
- 主界面线程开启一个定时器,定时往输出框① 输出内容;
- 子线程发送两个信号,一个带参数,一个不带参数;
- 带参数的在输出框① 显示;不带参数的在输出框② 显示;
首先,先创建一个包含UI的主界面Widget
对象,再Add new -> C++ Class
,新建一个子线程对象Sub_thread
,继承QObject ;
主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();
}
需要源码的请留言,稍后打包上传
版权属于:编码书生
本文链接:https://codess.cc/archives/460.html
所有原创文章采用知识共享署名-非商业性使用 4.0 国际许可协议进行许可。
除特别注明,您可以自由的转载和修改,但请务必注明文章来源且不可用于商业目的。
1 条评论
代码注释写得真好,感谢博主分享!