wxWidget中的线程编程模型? Topic is solved
-
- Earned a small fee
- Posts: 14
- Joined: Thu Mar 06, 2008 2:10 am
wxWidget中的线程编程模型?
我想使用一个线程来实现较长时间的计算,并用一个进度条来显示计算进度,该如何设计呢?wxWidget自带的例子看的不是很明白,感觉把计算和界面类耦合的太厉害,可能自己对wxWidget的线程模型不了解才有这样的感觉,有谁能说说线程模型吗?
你是指wxWidgets/samples/thread下的例子吧?我个人觉得挺清晰的啊~
不过它把所有代码写到一个文件里是有些混乱,你可以把代码折叠起来看。
按你的要求,主要看类MyWorkerThread。它边工作,边把进度存放在它创建的一个事件里,发送给主进程,wxProgressDialog收到这个事件就会作出回应。
这是一种推荐的线程更新GUI的做法,用事件。另外一种方式是wxMutexGuiEnter()和wxMutexGuiLeave(),MyThread类使用了这种方式。
-Utensil
不过它把所有代码写到一个文件里是有些混乱,你可以把代码折叠起来看。
按你的要求,主要看类MyWorkerThread。它边工作,边把进度存放在它创建的一个事件里,发送给主进程,wxProgressDialog收到这个事件就会作出回应。
这是一种推荐的线程更新GUI的做法,用事件。另外一种方式是wxMutexGuiEnter()和wxMutexGuiLeave(),MyThread类使用了这种方式。
-Utensil
In fascination of creating worlds by words, and in pursuit of words behind the world.
On Github: http://utensil.github.com
Technical Blog in Chinese: http://utensil.iteye.com/
On Github: http://utensil.github.com
Technical Blog in Chinese: http://utensil.iteye.com/
-
- Earned a small fee
- Posts: 14
- Joined: Thu Mar 06, 2008 2:10 am
类MyWorkerThread中的Entry函数
代码中可以看出,它的计算时间是可以实现确定的。如果我的计算时间无法实现确定,如何显示进度?
此外,我在计算完之后需要利用计算后的数据创建一个新的窗口,但是我的数据没计算完,窗口就显示了。如何利用线程保证数据计算完之后再显示窗口?
Code: Select all
void *MyWorkerThread::Entry()
{
for ( m_count = 0; !m_frame->Cancelled() && (m_count < 100); m_count++ )
{
// check if we were asked to exit
if ( TestDestroy() )
break;
// create any type of command event here
wxCommandEvent event( wxEVT_COMMAND_MENU_SELECTED, WORKER_EVENT );
event.SetInt( m_count );
// send in a thread-safe way
wxPostEvent( m_frame, event );
// wxSleep() can't be called from non-main thread!
wxThread::Sleep(200);
}
wxCommandEvent event( wxEVT_COMMAND_MENU_SELECTED, WORKER_EVENT );
event.SetInt(-1); // that's all
wxPostEvent( m_frame, event );
return NULL;
}
此外,我在计算完之后需要利用计算后的数据创建一个新的窗口,但是我的数据没计算完,窗口就显示了。如何利用线程保证数据计算完之后再显示窗口?
Utensil wrote:你是指wxWidgets/samples/thread下的例子吧?我个人觉得挺清晰的啊~
不过它把所有代码写到一个文件里是有些混乱,你可以把代码折叠起来看。
按你的要求,主要看类MyWorkerThread。它边工作,边把进度存放在它创建的一个事件里,发送给主进程,wxProgressDialog收到这个事件就会作出回应。
这是一种推荐的线程更新GUI的做法,用事件。另外一种方式是wxMutexGuiEnter()和wxMutexGuiLeave(),MyThread类使用了这种方式。
-Utensil
-
- Earned some good credits
- Posts: 103
- Joined: Thu Apr 03, 2008 5:35 am
- Location: China
- Contact:
嗯。
其实较长时间的操作要想显示进度也不一定要用多线程的。
我是VB转过来的,喜欢用DoEvents,嗬嗬,单线程配合DoEvents一样好使。
可以参考我写的一个拷贝文件并且显示进度,还可以响应其他消息的例子代码:
http://forums.wxwidgets.org/viewtopic.php?t=18836
我是VB转过来的,喜欢用DoEvents,嗬嗬,单线程配合DoEvents一样好使。
可以参考我写的一个拷贝文件并且显示进度,还可以响应其他消息的例子代码:
http://forums.wxwidgets.org/viewtopic.php?t=18836
-
- Earned a small fee
- Posts: 14
- Joined: Thu Mar 06, 2008 2:10 am
Re: 嗯。
我看了一下你的代码,与Windows平台相关了,不过使用时间器的确是个选择。
liuqi5521 wrote:其实较长时间的操作要想显示进度也不一定要用多线程的。
我是VB转过来的,喜欢用DoEvents,嗬嗬,单线程配合DoEvents一样好使。
可以参考我写的一个拷贝文件并且显示进度,还可以响应其他消息的例子代码:
http://forums.wxwidgets.org/viewtopic.php?t=18836
代码里哪里确定时间了? 你能够确定百分比,就能够显示进度了。代码中可以看出,它的计算时间是可以实现确定的。如果我的计算时间无法实现确定,如何显示进度?
如果你是说那个 wxThread::Sleep(200),那你就误会了,因为这个线程什么都不干,它不加这句话,它就瞬间结束了。你可以把它置换为任何需要耗费时间的计算过程。
此外,我在计算完之后需要利用计算后的数据创建一个新的窗口,但是我的数据没计算完,窗口就显示了。如何利用线程保证数据计算完之后再显示窗口?
你可以参照代码中的方法,在线程结束时,把一个不寻常的整数(如-8)放进事件里,然后再在主程序的事件处理那边作专门处理。
-Utensil
In fascination of creating worlds by words, and in pursuit of words behind the world.
On Github: http://utensil.github.com
Technical Blog in Chinese: http://utensil.iteye.com/
On Github: http://utensil.github.com
Technical Blog in Chinese: http://utensil.iteye.com/
-
- Earned some good credits
- Posts: 103
- Joined: Thu Apr 03, 2008 5:35 am
- Location: China
- Contact:
如果你的计算时间确实无法确定
如果你的计算时间确实无法确定,那么你可以用进度条的脉动模式啊,就是Pulse方法。
-
- Earned a small fee
- Posts: 14
- Joined: Thu Mar 06, 2008 2:10 am
我的代码将计算和创建新窗口都放在一个线程内,窗口显示不正确。
难道必须这样设计:将计算放在线程里,在线程结束后在显示新窗口?
难道必须这样设计:将计算放在线程里,在线程结束后在显示新窗口?
Utensil wrote:代码里哪里确定时间了? 你能够确定百分比,就能够显示进度了。代码中可以看出,它的计算时间是可以实现确定的。如果我的计算时间无法实现确定,如何显示进度?
如果你是说那个 wxThread::Sleep(200),那你就误会了,因为这个线程什么都不干,它不加这句话,它就瞬间结束了。你可以把它置换为任何需要耗费时间的计算过程。
此外,我在计算完之后需要利用计算后的数据创建一个新的窗口,但是我的数据没计算完,窗口就显示了。如何利用线程保证数据计算完之后再显示窗口?
你可以参照代码中的方法,在线程结束时,把一个不寻常的整数(如-8)放进事件里,然后再在主程序的事件处理那边作专门处理。
-Utensil
你把你的代码(相关的部份)贴上来看一看?应该显示正确的,我就在线程里弹出过窗口。
-Utensil
-Utensil
In fascination of creating worlds by words, and in pursuit of words behind the world.
On Github: http://utensil.github.com
Technical Blog in Chinese: http://utensil.iteye.com/
On Github: http://utensil.github.com
Technical Blog in Chinese: http://utensil.iteye.com/
-
- Earned a small fee
- Posts: 14
- Joined: Thu Mar 06, 2008 2:10 am
Re: 如果你的计算时间确实无法确定
脉动模式的特点是什么?我感觉挺怪的,每一次移动的好慢
liuqi5521 wrote:如果你的计算时间确实无法确定,那么你可以用进度条的脉动模式啊,就是Pulse方法。
-
- Earned a small fee
- Posts: 14
- Joined: Thu Mar 06, 2008 2:10 am
-
- Earned some good credits
- Posts: 103
- Joined: Thu Apr 03, 2008 5:35 am
- Location: China
- Contact:
Re: 如果你的计算时间确实无法确定
每次调用Pulse确实移动的很小。但如果你调用多次,就会移动的很多Justin2008 wrote:脉动模式的特点是什么?我感觉挺怪的,每一次移动的好慢liuqi5521 wrote:如果你的计算时间确实无法确定,那么你可以用进度条的脉动模式啊,就是Pulse方法。
for(long i=0;i<20;i++)
wxGuage1->Pulse();
不要仅仅把一句放在那里,应该用一个循环