QT pthread在线程函数中调用类的非静态成员函数

fancy_sky 2014-04-28 05:30:29
我有一个test类,display是我的槽函数,在槽函数中用pthread开启线程,我已经用最简单的方法测试qt用pthread显示图片,可就是没有效果,,当点击按键时运行槽函数,,执行完了就是不显示图片,,,

ui.dis_label->setPixmap(QPixmap("E:\\triangle.jpg"));,这句话不放进pthread线程里,,就完全没有问题,,,不知道错在哪里了,,麻烦各位帮忙看一下,,,

我是为了一个视频显示使用pthread的,,我先把图片测试好后再做视频,,

void test::display()
{
pthread_t id;
void *arg;
ret = pthread_create(&id,NULL,dis_play,this);
if (ret != 0)
{
exit(1);
}

}
void *test::dis_play(void *arg)
{
test *pDlg = (test*)arg;
pDlg->run();
return 0;
}

void test::run()
{

//qt 测试图片在主对话框中显示
ui.dis_label->setPixmap(QPixmap("E:\\triangle.jpg"));//直接显示

}
...全文
673 13 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
fancy_sky 2015-01-22
  • 打赏
  • 举报
回复
非常感谢楼上各位,这个问题已经搞定了,结贴
fancy_sky 2014-05-03
  • 打赏
  • 举报
回复
引用 11 楼 dbzhang800 的回复:
[quote=引用 10 楼 jiangnanyidiao 的回复:] 十分感谢,,你的意思现在不管我做什么建什么线程,只要用到ui下的控件来显示比如要使用ui.dis_label->setPixmap(QPixmap("E:\\triangle.jpg"));这样的语句来显示东西,,这种语句都必须放在主线程吗??
对的,文件操作,图片读取,图片处理,你都可以在次线程中进行。但是要将它显示出来,你需要先将该图片以线程安全的方式传递给主线程,而后主线程负责显示。 题外,QImage可以在次线程中使用,但是QPixmap不能在次线程中使用。[/quote] 非常感谢你的回复,,我后面又研究了一下,确实像你说的一样,一起与gui相关的操作都必须在主线程里。。现在我想问一下如果我把视频的每一帧都作处理,,处理过程在次线程,处理完毕后然后要一帧一帧的传给主线程QImage用来显示,这样频繁的线程通信,,能达到多线程的目的吗??会不会还是像没有建线程一样的卡死呢??谢谢..
fancy_sky 2014-04-29
  • 打赏
  • 举报
回复
引用 9 楼 dbzhang800 的回复:
[quote=引用 8 楼 jiangnanyidiao 的回复:] 我大概明白了你的想法,,,现在我不知道DisplayThread::DisplayThread(MainWindow *pWindow, QObject *parent) : QThread(parent)的构造函数是怎样实现的,,我新建线程类,没有MainWindow *pWindow,,,于是我更改建好的类的构造函数定义和实现,,结果报错了,,,
代码都是手写的,如果你这儿的报错是指编译错误,说明你需要补充一些C++的基础。 题外,不管前面给出的代码在特定的平台下能不能给出正确的结果,在次线程中调用 QWidget 及其派生类的成员,都是错误的,因为这些成员都是不可重入的。 正确的方法是使用Qt的事件系统进行线程间通讯(包括queue方式的信号槽,queue方式的invoke等等)。Qt的事件系统是线程安全的。[/quote] 十分感谢,,你的意思现在不管我做什么建什么线程,只要用到ui下的控件来显示比如要使用ui.dis_label->setPixmap(QPixmap("E:\\triangle.jpg"));这样的语句来显示东西,,这种语句都必须放在主线程吗??
dbzhang800 2014-04-29
  • 打赏
  • 举报
回复
引用 8 楼 jiangnanyidiao 的回复:
我大概明白了你的想法,,,现在我不知道DisplayThread::DisplayThread(MainWindow *pWindow, QObject *parent) : QThread(parent)的构造函数是怎样实现的,,我新建线程类,没有MainWindow *pWindow,,,于是我更改建好的类的构造函数定义和实现,,结果报错了,,,
代码都是手写的,如果你这儿的报错是指编译错误,说明你需要补充一些C++的基础。 题外,不管前面给出的代码在特定的平台下能不能给出正确的结果,在次线程中调用 QWidget 及其派生类的成员,都是错误的,因为这些成员都是不可重入的。 正确的方法是使用Qt的事件系统进行线程间通讯(包括queue方式的信号槽,queue方式的invoke等等)。Qt的事件系统是线程安全的。
fancy_sky 2014-04-29
  • 打赏
  • 举报
回复
引用 6 楼 sourire_will 的回复:
[quote=引用 4 楼 jiangnanyidiao 的回复:] 那要达到目的,应该这样使用呢,,谢谢
#include "displaythread.h"
#include "mainwindow.h"

DisplayThread::DisplayThread(MainWindow *pWindow, QObject *parent) :
    QThread(parent)
{
    m_pWindow = pWindow;
}

void DisplayThread::run()
{
    m_pWindow->display();
}



void MainWindow::on_pushButton_clicked()
{
    DisplayThread *pThread = new DisplayThread(this);
    pThread->start();
}

void MainWindow::display()
{
    ui->label->setPixmap(QPixmap(":/images/button.jpg"));
}
测试过,可用[/quote] 我大概明白了你的想法,,,现在我不知道DisplayThread::DisplayThread(MainWindow *pWindow, QObject *parent) : QThread(parent)的构造函数是怎样实现的,,我新建线程类,没有MainWindow *pWindow,,,于是我更改建好的类的构造函数定义和实现,,结果报错了,,,
fancy_sky 2014-04-29
  • 打赏
  • 举报
回复
引用 6 楼 sourire_will 的回复:
[quote=引用 4 楼 jiangnanyidiao 的回复:] 那要达到目的,应该这样使用呢,,谢谢
#include "displaythread.h"
#include "mainwindow.h"

DisplayThread::DisplayThread(MainWindow *pWindow, QObject *parent) :
    QThread(parent)
{
    m_pWindow = pWindow;
}

void DisplayThread::run()
{
    m_pWindow->display();
}



void MainWindow::on_pushButton_clicked()
{
    DisplayThread *pThread = new DisplayThread(this);
    pThread->start();
}

void MainWindow::display()
{
    ui->label->setPixmap(QPixmap(":/images/button.jpg"));
}
测试过,可用[/quote] 十分感谢,,,你上面的代码是在同一个cpp文件吗,,怎么会有void MainWindow::display()和void DisplayThread::run()同时出现呢,,,
dbzhang800 2014-04-29
  • 打赏
  • 举报
回复
引用 10 楼 jiangnanyidiao 的回复:
十分感谢,,你的意思现在不管我做什么建什么线程,只要用到ui下的控件来显示比如要使用ui.dis_label->setPixmap(QPixmap("E:\\triangle.jpg"));这样的语句来显示东西,,这种语句都必须放在主线程吗??
对的,文件操作,图片读取,图片处理,你都可以在次线程中进行。但是要将它显示出来,你需要先将该图片以线程安全的方式传递给主线程,而后主线程负责显示。 题外,QImage可以在次线程中使用,但是QPixmap不能在次线程中使用。
sourire_will 2014-04-28
  • 打赏
  • 举报
回复
引用 4 楼 jiangnanyidiao 的回复:
那要达到目的,应该这样使用呢,,谢谢
#include "displaythread.h"
#include "mainwindow.h"

DisplayThread::DisplayThread(MainWindow *pWindow, QObject *parent) :
    QThread(parent)
{
    m_pWindow = pWindow;
}

void DisplayThread::run()
{
    m_pWindow->display();
}



void MainWindow::on_pushButton_clicked()
{
    DisplayThread *pThread = new DisplayThread(this);
    pThread->start();
}

void MainWindow::display()
{
    ui->label->setPixmap(QPixmap(":/images/button.jpg"));
}
测试过,可用
fancy_sky 2014-04-28
  • 打赏
  • 举报
回复
引用 3 楼 dbzhang800 的回复:
QWidget及其派生类,都只能在主线程中使用!Qt文档中对此有明文规定
那要达到目的,应该这样使用呢,,谢谢
fancy_sky 2014-04-28
  • 打赏
  • 举报
回复
那要达到目的,应该这样使用呢,,谢谢
dbzhang800 2014-04-28
  • 打赏
  • 举报
回复
QWidget及其派生类,都只能在主线程中使用!Qt文档中对此有明文规定
sourire_will 2014-04-28
  • 打赏
  • 举报
回复
没试过这样用,楼主还是用Qt自带的线程类QThread吧
wang_qiao_ying 2014-04-28
  • 打赏
  • 举报
回复
新手学习中,路过。。。

16,816

社区成员

发帖
与我相关
我的任务
社区描述
Qt 是一个跨平台应用程序框架。通过使用 Qt,您可以一次性开发应用程序和用户界面,然后将其部署到多个桌面和嵌入式操作系统,而无需重复编写源代码。
社区管理员
  • Qt
  • 亭台六七座
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧