[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_ ...
随机推荐
- BrowserSync使用
在Gulp中使用BrowserSync 2016-02-24 23:47 by 那时候的我, 116 阅读, 0 评论, 收藏, 编辑 博客已迁移至http://lwzhang.github.io. ...
- 重新想象 Windows 8 Store Apps (15) - 控件 UI: 字体继承, Style, ControlTemplate, SystemResource, VisualState, VisualStateManager
原文:重新想象 Windows 8 Store Apps (15) - 控件 UI: 字体继承, Style, ControlTemplate, SystemResource, VisualState ...
- 【Leetcode】Pascal's Triangle II
Given an index k, return the kth row of the Pascal's triangle. For example, given k = 3, Return [1,3 ...
- Maven搭建SpringMVC+Hibernate项目详解(转)
前言 今天复习一下SpringMVC+Hibernate的搭建,本来想着将Spring-Security权限控制框架也映入其中的,但是发现内容太多了,Spring-Security的就留在下一篇吧,这 ...
- 返璞归真 asp.net mvc (9) - asp.net mvc 3.0 新特性之 View(Razor)
原文:返璞归真 asp.net mvc (9) - asp.net mvc 3.0 新特性之 View(Razor) [索引页][源码下载] 返璞归真 asp.net mvc (9) - asp.ne ...
- 开源Math.NET基础数学类库使用(02)矩阵向量计算
原文:[原创]开源Math.NET基础数学类库使用(02)矩阵向量计算 开源Math.NET基础数学类库使用系列文章总目录: 1.开源.NET基础数学计算组件Math.NET(一)综合介绍 ...
- 开源Math.NET基础数学类库使用(01)综合介绍
原文:[原创]开源Math.NET基础数学类库使用(01)综合介绍 开源Math.NET基础数学类库使用系列文章总目录: 1.开源.NET基础数学计算组件Math.NET(一)综合介绍 2. ...
- C# 读取IE缓存文件(2)
private void button1_Click(object sender, EventArgs e) { , nBufSize; IntPtr buf; INTERNET_CACHE_ENTR ...
- LayoutDemo
package swing.ui; import java.awt.BorderLayout; import java.awt.GridLayout; import javax.swing.JButt ...
- HDU 1541 Stars (树状数组)
Problem Description Astronomers often examine star maps where stars are represented by points on a p ...