[wxWidgets]_[0基础]_[经常更新进度条程序]
场景:
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="">
完整代代码下载:
[wxWidgets]_[0基础]_[经常更新进度条程序]的更多相关文章
- [Zlib]_[0基础]_[使用zlib库压缩文件]
场景: 1. WIndows上没找到系统提供的win32 api来生成zip压缩文件, 有知道的大牛麻烦留个言. 2. zlib比較经常使用,编译也方便,使用它来做压缩吧. MacOSX平台默认支持z ...
- [libcurl]_[0基础]_[使用libcurl下载大文件]
场景: 1. 在Windows编程时, 下载http页面(html,xml)能够使用winhttp库,可是并非非常下载文件,由于会失败. 由此引出了WinINet库,无奈这个库的稳定性比較低,使用样例 ...
- [wxWidgets]_[0基础]_[不常见但有用的类wxStandardPaths]
场景: 1.wxStandardPaths 用来获取各种系统路径.能够用于存放app的配置数据.比方文档文件夹,appData等. 代码: #include "wx/wxprec.h&q ...
- [wxWidgets]_[0基础]_[不常见但有用的类wxCmdLineParser]
场景: 1. 有时候须要构造命令行字符串传递給函数调用,比方CreateProcess,假设參数是动态的,那么就得使用类似std::vector<string>加入单个參数,之后拼接为一个 ...
- [C/C++标准库]_[0基础]_[交集和补集]
场景: 1. 计算std::vector A和 std::vector B里的同样的元素, 用于保留不删除. 2. 计算std::vector A和 std::vector B里各自的补集, 用于删除 ...
- [Windows]_[0基础]_[Release程序的崩溃报告minidump解决方式]
场景: 1. Release的程序崩溃时,崩溃报告能够让开发者查明代码哪里出了问题,用处大大的. 2. 仅仅实用VS的编译器才支持,所以MinGW就无缘了. 3. 使用了未处理异常过滤处理函数. 4. ...
- [C/C++标准库]_[0基础]_[使用fstream合并文本文件]
场景: 1. 就是合并文本文件,而且从第2个文件起不要合并第一行. 2. 多加了一个功能,就是支持2个以上的文件合并. 3. 问题: http://ask.csdn.net/questions/192 ...
- [ATL/WTL]_[0基础]_[CBitmap复制图片-截取图片-平铺图片]
场景: 1.当你须要截取图片部分区域作为某个控件的背景. 2.须要平铺图片到一个大区域让他自己主动放大时. 3.或者须要合并图片时. 代码: CDC sdc; CDC ddc; sdc.CreateC ...
- [C/C++标准库]_[0基础]_[优先队列priority_queue的使用]
std::priority_queue 场景: 1. 对于一个任务队列,任务的优先级由任务的priority属性指明,这时候就须要优先级越高的先运行.而queue并没有排序功能,这时priority_ ...
随机推荐
- REDGATE SQLPROMPT 6.0新功能
原文:REDGATE SQLPROMPT 6.0新功能 REDGATE SQLPROMPT 6.0新功能 下载地址:http://files.cnblogs.com/lyhabc/SQLPrompt6 ...
- ACE定时器
每一秒钟打印一行 http://www.tuicool.com/articles/Zb263e 计时器的打开和关闭封装 http://andylin02.iteye.com/blog/440572 自 ...
- Visual Studio 2010 将网站直接发布到远程站点
原文:Visual Studio 2010 将网站直接发布到远程站点 这次说下如何将web应用程序直接发布到IIS服务器站点!!! 问题的由来 本人每天要发布更新的程序,所以每次更新的时候要做的工作: ...
- ubuntu下安装wine
直接在终端里面输入“sudo apt-get install wine”不要引号,即可安装wine.至于使用它,终端命令就是“wine ....”举个例子,你现在要运行魔兽, 然后你的魔兽的文件夹的位 ...
- dbus 和 policykit 实例篇(python) ()转
使用policykit 的程序一般都有一个dbus daemon程序来完成相关操作,这个dbus daemon 会在系统注册一个system bus 服务名,用于响应要求root privileged ...
- 打开 chm 帮助文件显示空白及解决方法
有个很奇葩的解决方法:把 chm 文件用压缩软件压缩,然后用压缩软打开此压缩包,直接双击压缩包里面的 chm 文件 这虽然解决了问题,但是这不科学…… 分析:直接打开压缩包里面的文件,压缩包的文件是临 ...
- 公钥\私人 ssh避password登陆
相关概念以前见过,决不要注意,使用公共密钥管理之前,腾讯云主机的备案机,非常头发的感觉,查了一下相关资料,这里总结下: 字符a:192.168.7.188 (ubuntu) 字符b:192.168.7 ...
- 【iOS发展-61】更换plist经过资源,执行iOS一旦数据仍显示在模拟器的外观,如何解决?
(1)案例介绍 --我们首先导入plist文件做项目,模拟的观看效果. --删除plist,更换一个新的plist,CMD+R模拟执行,或者找到该程序界面上显示最后一个数据. (2)原因 是由于第一次 ...
- Handler消息源代码分析
public static final Looper myLooper() { return (Looper)sThreadLocal.get(); } 首先到Handler运行过程的总结: 1. L ...
- jQuery
代码的层定位滑动动画效果
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...