• 6057阅读
  • 10回复

[提问]功能函数做成QT多线程的问题 [复制链接]

上一主题 下一主题
离线xinlanbobo
 

只看楼主 倒序阅读 楼主  发表于: 2015-03-25
请问各位,
我现在有一个QHomeWidget,点击其上一个按钮,会调用一个功能函数 fun()。
在 fun()中去实现连接功能,连接成功与否需要等待一段时间才知道。这段时间我的程序界面无法操作。
这里我想使用多线程的方式,去解决 “等待时无法操作的问题”。


使用了以下的类

class MyWorker : public QObject
{
    Q_OBJECT
public:
    MyWorker();
public slots:
    void slot1(QWidget*);
};
void slot1(QWidget*)
{
   fun (QHomeWidget中的某一子Widget);
}


在QHomeWidget中,有
m_worker = new MyWorker;
QThread*  theThread = new QThread(this);
m_worker->moveToThread(theThread);
connect(this,SIGNAL( signal1(QWidget*)), m_worker, SLOT(slot1(QWidget*)));
theThread->start();


但是运行时,走到 MyWorker::slot1() 中的 fun (QHomeWidget中的某一子Widget);这一步就会出错,无法向子线程传递QObject!!!



请问我应当如何处理该问题呢?
或者我应该如何实现最初的需求呢?
谢谢。


离线xinlanbobo

只看该作者 1楼 发表于: 2015-03-25
论坛里的帖子都是传递int、QString之类的啊。

哪位大侠来指点一下?

本帖提到的人: @jdwx
离线蜡人张

只看该作者 2楼 发表于: 2015-03-25
定义一个QThread的子类myThread,将fun()的函数体写到run()里面去
在main()函数里加入代码:
MyWorker m;
myThread t;
QObject::connect(&m,SIGNAL(clicked()),&t),SLOT(start()));

槽函数start()执行之后就会自动调用run()函数了
离线xinlanbobo

只看该作者 3楼 发表于: 2015-03-25
回 蜡人张 的帖子
蜡人张:定义一个QThread的子类myThread,将fun()的函数体写到run()里面去
在main()函数里加入代码:
MyWorker m;
myThread t;
QObject::connect(&m,SIGNAL(clicked()),&t),SLOT(start()));
....... (2015-03-25 19:48) 

你这样还是在子线程中调用了 QHomeWidget中的Widget。
还是不行。
离线xuang

只看该作者 4楼 发表于: 2015-03-25
乍一看感觉像是子线程操作了GUI的问题,Qt4里的子线程不能和QtGui有关系,不知道Qt5里是不是没这个问题了?
离线xinlanbobo

只看该作者 5楼 发表于: 2015-03-25
回 xuang 的帖子
xuang:乍一看感觉像是子线程操作了GUI的问题,Qt4里的子线程不能和QtGui有关系,不知道Qt5里是不是没这个问题了? (2015-03-25 21:27) 

嗯。你说得对。
但是我希望在子线程中实现连接视频的功能,需要用到QWidget的winId呢。
不知道直接传winid是否可以。
离线bran_lee

只看该作者 6楼 发表于: 2015-03-26
回 xinlanbobo 的帖子
xinlanbobo:嗯。你说得对。
但是我希望在子线程中实现连接视频的功能,需要用到QWidget的winId呢。
不知道直接传winid是否可以。 (2015-03-25 22:22) 

很多gui的接口是可以在子线程操作的,只是gui相关的类一定要在主线程里创建,至于信号传QObject,直接传实例是不行的,因为没有拷贝构造函数,指针和其他基本类型都是可以的,自定义的类要用qRegisterMetaType后才能传
当你只有锤子时,你看什么都像是钉子!
离线渡世白玉

只看该作者 7楼 发表于: 2015-03-26
QWidget 及其子类,统统只能在主线程操作、、
需要启动线程中任务,用信号发出去,子线程槽,接受处理、、
线程数据返回的操作,也用信号传出来,weidget接受,并针对信号做相应的处理、、
全部用信号槽交互、、
离线xinlanbobo

只看该作者 8楼 发表于: 2015-03-26
回 bran_lee 的帖子
bran_lee:很多gui的接口是可以在子线程操作的,只是gui相关的类一定要在主线程里创建,至于信号传QObject,直接传实例是不行的,因为没有拷贝构造函数,指针和其他基本类型都是可以的,自定义的类要用qRegisterMetaType后才能传 (2015-03-26 08:10) 

你说的传QWidget的指针至子线程,这个也不行吧!
我现在就是传的指针,然后掉的 WinId, 不可以!
离线xinlanbobo

只看该作者 9楼 发表于: 2015-03-26
回 渡世白玉 的帖子
渡世白玉:QWidget 及其子类,统统只能在主线程操作、、
需要启动线程中任务,用信号发出去,子线程槽,接受处理、、
线程数据返回的操作,也用信号传出来,weidget接受,并针对信号做相应的处理、、
全部用信号槽交互、、 (2015-03-26 09:54) 

嗯。
我现在是这样实现的:
主线程中信号 void preview_signal(HWND)  可以将GUI中某一个QWidget的句柄传递。
子线程中         void slot1(HWND)  接收传进来的句柄,使用该句柄。

我暂时这样可以实现功能。不知道还有无他法。

多谢各位的帮助。
离线bran_lee

只看该作者 10楼 发表于: 2015-03-26
回 xinlanbobo 的帖子
xinlanbobo:你说的传QWidget的指针至子线程,这个也不行吧!
我现在就是传的指针,然后掉的 WinId, 不可以! (2015-03-26 12:33)

指针是肯定能用信号直接传的,至于QWidget和其他子类的指针传到线程后,某些接口可以调用,有些不行,像QThread的run里可以直接对QTextEdit调用append,但一般来说都会引起一些信号和事件无法触发,从而引发很多问题,而且gui的类基本都不是线程安全的,所以一般不会在线程里直接操作gui的东西,但并不是其他人说的那样绝对的不可以

当你只有锤子时,你看什么都像是钉子!
快速回复
限100 字节
 
上一个 下一个