场景:

1. 非常根据程序的进展需要处理业务,以更新进度条,进度条的目的是为了让用户知道业务流程的进度。一个进度条程序更友好,让用户知道在程序执行。不是没有反应。

2. 现在更新见过这两种方法的进展。事件(信号,队列)的发送让主线程依照发送的顺序来更新进度条,一种是设置一个全局整形变量,

通过执行定时器的方式来更新进度条。第一种不适合在更新频率比較高的地方,比方一秒钟发送了20个事件,这样会造成主线程忙于处理事件界面出现假死状态。

所以最好的办法就是使用第2种通过定时器更新进度条,设置一个合理的值,比方500毫秒这样既能看到更新的进度,也不会让主线程过于忙。

3. 这里用wxWidgets做样例。事实上mfc,wtl,cocoa都是一样的。

部分代码:

my_thread.cpp

#include "domain/my_thread.h"
#include "window/my_frame.h" wxThread::ExitCode MyThread::Entry()
{
Sleep(500);
int i = 1;
while (!TestDestroy() && i <= 100)
{
if(type_)
{
//第一种方法,发事件更新进度条,注意,不能直接更新进度条控件,由于非主线程不能更新控件
wxCommandEvent* evt = new wxCommandEvent(wxEVT_COMMAND_MYTHREAD_UPDATE);
evt->SetInt(i);
wxQueueEvent(m_pHandler->GetEventHandler(), evt);
}else
{
//另外一种方法,直接更新MyFrame里的Int成员变量,然会wxTimer会依据这个值自己主动更新进度条控件.
m_pHandler->progress_value_ = i;
Sleep(200);
}
++i;
}
//1.最后这个事实上还是必要的,告诉wxTimer能够结束了。总之就是通知界面工作任务已经完毕,你自己做该做的事。
wxQueueEvent(m_pHandler->GetEventHandler(), new wxCommandEvent(wxEVT_COMMAND_MYTHREAD_COMPLETED));
return (wxThread::ExitCode)0;
}

my_frame.cpp

#include "window/my_frame.h"
#include "wx/xrc/xmlres.h"
#include <iostream>
#include "domain/my_thread.h" using namespace std; BEGIN_EVENT_TABLE(MyFrame, wxFrame)
EVT_COMMAND(wxID_ANY, wxEVT_COMMAND_MYTHREAD_UPDATE, MyFrame::OnThreadUpdate)
EVT_COMMAND(wxID_ANY, wxEVT_COMMAND_MYTHREAD_COMPLETED, MyFrame::OnThreadCompletion)
EVT_TIMER(wxID_ANY,MyFrame::OnTimer)
END_EVENT_TABLE() wxDEFINE_EVENT(wxEVT_COMMAND_MYTHREAD_COMPLETED, wxThreadEvent);
wxDEFINE_EVENT(wxEVT_COMMAND_MYTHREAD_UPDATE, wxThreadEvent); void MyFrame::Init()
{
gauge_ = XRCCTRL(*this, "m_gauge1", wxGauge); event_update_button_ = XRCCTRL(*this, "m_button1", wxButton);
event_update_button_->Bind(wxEVT_COMMAND_BUTTON_CLICKED,
wxCommandEventHandler(MyFrame::OnEventUpdate), this, XRCID("m_button1"));
timer_update_button_ = XRCCTRL(*this, "m_button3", wxButton);
timer_update_button_->Bind(wxEVT_COMMAND_BUTTON_CLICKED,
wxCommandEventHandler(MyFrame::OnTimerUpdate), this, XRCID("m_button3")); timer.SetOwner(this->GetEventHandler());
} MyFrame::MyFrame(wxWindow* parent)
{
progress_value_ = 0;
} MyFrame::~MyFrame()
{
} void MyFrame::OnThreadUpdate(wxCommandEvent& evt)
{
cout << "OnThreadUpdate" << endl;
gauge_->SetValue(evt.GetInt());
} void MyFrame::OnThreadCompletion(wxCommandEvent&)
{
cout << "OnThreadCompletion" << endl;
if(!type_)
{
timer.Stop();
gauge_->SetValue(progress_value_);
} timer_update_button_->Enable();
event_update_button_->Enable(); } void MyFrame::OnTimer(wxTimerEvent&)
{
cout << "OnTimer" << endl;
gauge_->SetValue(progress_value_);
} void MyFrame::DoTask(bool type)
{
timer_update_button_->Enable(false);
event_update_button_->Enable(false); MyThread *m_pThread = new MyThread(type,this);
if ( m_pThread->Run() != wxTHREAD_NO_ERROR )
{
cout << "Can't create the thread!: " << type << endl;
delete m_pThread;
m_pThread = NULL;
}
} void MyFrame::OnTimerUpdate(wxCommandEvent& evt)
{
cout << "OnTimerUpdate" << endl;
gauge_->SetValue(0);
progress_value_ = 0;
type_ = false;
timer.Start(500);
DoTask(type_);
} void MyFrame::OnEventUpdate(wxCommandEvent& evt)
{
cout << "OnEventUpdate" << endl;
gauge_->SetValue(0);
progress_value_ = 0;
type_ = true;
DoTask(type_);
}

gui.cpp

#include "wx/wxprec.h"

#ifndef WX_PRECOMP
#include "wx/wx.h"
#endif #include "wx/xrc/xmlres.h"
#include <assert.h>
#include <iostream>
#include <stdio.h>
#include <io.h>
#include <fcntl.h>
#include "wx/listctrl.h"
#include "wx/grid.h"
#include "wx/event.h" #include "window/my_frame.h" using namespace std; static void OpenConsole()
{
AllocConsole();
HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);
int hCrt = _open_osfhandle((long)handle,_O_TEXT);
FILE * hf = _fdopen( hCrt, "w" );
*stdout = *hf;
} static wxString GetAppRunDirectory()
{
wxString directory(wxTheApp->argv[0]);
directory.Replace(wxT("\\"), wxT("/"));
wxString str = directory.BeforeLast('/');
if(str.IsEmpty())
{
return wxT(".");
}
return directory.BeforeLast('/');
} static wxString GetInstallDirectory()
{
wxString directory = GetAppRunDirectory();
#ifdef __QXWIN32__
return directory.BeforeLast('/');
#else
return directory;
#endif
} class MyApp : public wxApp
{
public:
virtual bool OnInit();
virtual int OnExit();
}; IMPLEMENT_APP(MyApp) // 'Main program' equivalent: the program execution "starts" here
bool MyApp::OnInit()
{
if (!wxApp::OnInit())
{
return false;
}
OpenConsole();
wxInitAllImageHandlers();
wxXmlResource::Get()->InitAllHandlers(); wxString ui_dir = GetInstallDirectory()+wxT("/Themes");
wxXmlResource::Get()->LoadAllFiles(ui_dir); MyFrame *frame = new MyFrame(NULL);
bool loaded = wxXmlResource::Get()->LoadFrame(frame, NULL, "MyFrame1");
assert(loaded);
frame->Init();
frame->Show(true); return true;
} int MyApp::OnExit()
{
return 0;
}

截图:

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvaW5mb3dvcmxk/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="">

完整代代码下载:

http://download.csdn.net/detail/infoworld/8105011

[wxWidgets]_[0基础]_[经常更新进度条程序]的更多相关文章

  1. [Zlib]_[0基础]_[使用zlib库压缩文件]

    场景: 1. WIndows上没找到系统提供的win32 api来生成zip压缩文件, 有知道的大牛麻烦留个言. 2. zlib比較经常使用,编译也方便,使用它来做压缩吧. MacOSX平台默认支持z ...

  2. [libcurl]_[0基础]_[使用libcurl下载大文件]

    场景: 1. 在Windows编程时, 下载http页面(html,xml)能够使用winhttp库,可是并非非常下载文件,由于会失败. 由此引出了WinINet库,无奈这个库的稳定性比較低,使用样例 ...

  3. [wxWidgets]_[0基础]_[不常见但有用的类wxStandardPaths]

    场景: 1.wxStandardPaths   用来获取各种系统路径.能够用于存放app的配置数据.比方文档文件夹,appData等. 代码: #include "wx/wxprec.h&q ...

  4. [wxWidgets]_[0基础]_[不常见但有用的类wxCmdLineParser]

    场景: 1. 有时候须要构造命令行字符串传递給函数调用,比方CreateProcess,假设參数是动态的,那么就得使用类似std::vector<string>加入单个參数,之后拼接为一个 ...

  5. [C/C++标准库]_[0基础]_[交集和补集]

    场景: 1. 计算std::vector A和 std::vector B里的同样的元素, 用于保留不删除. 2. 计算std::vector A和 std::vector B里各自的补集, 用于删除 ...

  6. [Windows]_[0基础]_[Release程序的崩溃报告minidump解决方式]

    场景: 1. Release的程序崩溃时,崩溃报告能够让开发者查明代码哪里出了问题,用处大大的. 2. 仅仅实用VS的编译器才支持,所以MinGW就无缘了. 3. 使用了未处理异常过滤处理函数. 4. ...

  7. [C/C++标准库]_[0基础]_[使用fstream合并文本文件]

    场景: 1. 就是合并文本文件,而且从第2个文件起不要合并第一行. 2. 多加了一个功能,就是支持2个以上的文件合并. 3. 问题: http://ask.csdn.net/questions/192 ...

  8. [ATL/WTL]_[0基础]_[CBitmap复制图片-截取图片-平铺图片]

    场景: 1.当你须要截取图片部分区域作为某个控件的背景. 2.须要平铺图片到一个大区域让他自己主动放大时. 3.或者须要合并图片时. 代码: CDC sdc; CDC ddc; sdc.CreateC ...

  9. [C/C++标准库]_[0基础]_[优先队列priority_queue的使用]

    std::priority_queue 场景: 1. 对于一个任务队列,任务的优先级由任务的priority属性指明,这时候就须要优先级越高的先运行.而queue并没有排序功能,这时priority_ ...

随机推荐

  1. 牟大哥:《App自我促销》连载2 直立人迁移走

    [谋哥每天一干货,第六十九篇] 前篇说到声音在远古时代.是一个奇妙的东西,它可以非常快地把信息传播到其它地方,突破了短距离. 然而能人的后代直立人学会了直立行走,他们開始走出非洲,到达遥远的中东.中国 ...

  2. Sliverlight之 控件模板

    1,控件模板 (见Project22) (1) 什么是控件模板,查中文帮助 说明:当控件自身属性已经无法达到你对控件外观设置的要求时(比如将按钮作成圆形),此时控件模板就发挥了很大的作用 使用: &l ...

  3. 玩转html5(三)---智能表单(form),使排版更加方便

    <!DOCTYPE html> <head> <meta http-equiv="Content-Type" content="text/h ...

  4. sails中文文档地址

    http://sailsdoc.swift.ren/ Sails.js是一个Web框架,可以于轻松构建自定义,企业级Node.js Apps.它在设计上类似于像Ruby on Rails的MVC架构的 ...

  5. 【Linux探索之旅】第二部分第四课:文件操纵,鼓掌之中

    内容简介 1.第二部分第四课:文件操纵,鼓掌之中 2.第二部分第五课预告:用户和权限 文件操纵,鼓掌之中 既然上一课我们学习了Linux中的文件组织方式,那么现在就该是玩弄,啊不,是操纵它们的时候了. ...

  6. 认识Backbone (三)

    Backbone.Collection(集合)  collection是model对象的一个有序的组合,我们可以在集合上绑定 "change" 事件,从而当集合中的模型发生变化时f ...

  7. [LeetCode62]Unique Paths

    题目: A robot is located at the top-left corner of a m x n grid (marked 'Start' in the diagram below). ...

  8. 简单的dialog菜单

    本文介绍的是我自己做的一个简单的dialog菜单,可以直接植入到类中. 方法代码: /** 显示一个靠右上的dialog列表菜单*/private void showTopBarRightButton ...

  9. Chapter 1 Securing Your Server and Network(1):选择SQL Server运行账号

    原文:Chapter 1 Securing Your Server and Network(1):选择SQL Server运行账号 原文出处:http://blog.csdn.net/dba_huan ...

  10. HDU4540+DP

    简单题... dp[ i ][ j ] 表示第 i 行取第 j 个数的MinVal /* DP&简单题 */ #include<stdio.h> #include<strin ...