Qt里创建子线程时,传入this指针出现问题
初学Linux下Qt编程,在设计一个简单的聊天程序的时候,使用到了线程。但是线程处理函数不属于UI界面类里面的成员函数,无法在线程处理函数中使用UI界面上的控件。于是我在创建线程的时候,传入了this指针。并且该线程处理函数已经申明成为全局函数和主界面类的友元函数。编译无错,运行时会发生卡死或者异常退出等问题。貌似功能代码设计没有问题,多次测试发现此时传入进来的this指针,在该函数中使用后就会发生这种问题。
请教下这样使用this传入到底有没有问题,有没有要改进的地方。
具体代码如下:
头文件:(cli.h)
...
void* pthread_func(void*); //线程处理函数
namespace Ui {
class Cli;
}
class Cli : public QMainWindow
{
Q_OBJECT
public:
explicit Cli(QWidget *parent = 0);
friend void* pthread_func(void*); //申明为友元函数
...
cli.cpp文件:
...
void Cli::on_startconnect_clicked() //单击“连接”后
{
...
//创建线程
if(pthread_create(&ntid,NULL,pthread_func,(void*)this) < 0)
{
QMessageBox::about(this,"error","pthread_create");
return ;
}
....
}
//线程处理函数,用于循环接受对方发送来的消息,并显示到界面上
void* pthread_func(void* tothis)
{
Cli* mythis = (Cli*)tothis; //定义临时变量,获取this指针
while(1)
{
memset(msg_buf_recv.str,0,sizeof(msg_buf_recv.str));
len = recv(sock_cli_fd,&msg_buf_recv,sizeof(msg_buf_recv),0);
if(len < 0)
{
//QMessageBox::about(mythis,"error","recv error"); //该处运行弹窗
qDebug("*******recv error"); //会卡死,所以换成qdebug
break;
}
else if(len == 0)
{
qDebug("*****ser error quit");
break;
}
mythis->ui->send->setEnabled(false);
mythis->ui->startconnect->setEnabled(true);
mythis->ui->disconnect->setEnabled(false);
break;
}
QString recv_str = QString::fromLocal8Bit(msg_buf_recv.str);
mythis->ui->display_text->append(recv_str); //此处用的是QTextBrowser控件,运行后
} //无法正常显示
pthread_exit((void*)0);
}
很奇怪的是,mythis指针在使用的时候,有些地方不会出问题,比如mythis->ui->send->setEnabled(false);
但是有些例如QMessageBox,还有后面的QTextBrowser都会令程序异常退出或者卡死.
我也在网上查过,Qt里一般是使用QThread线程类的派生类来处理多线程任务,但是小弟初学,知道这种传入this,设置为友元函数的方法也可行,只是问题多多。希望各位给出提示。。。。
[解决办法]
QT里面最重要的信号槽机制应该看一下,它有两种连接方式,一是直接连接,二是队列连接,你想立即显示在UI界面上,可以使用第一种信号槽连接方式就可以。当线程接收到数据后,发送信号,执行槽函数。