zoukankan      html  css  js  c++  java
  • [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;
    }
    
    
    
    
    

    截图:


    完整代代码下载:

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


  • 相关阅读:
    .NET Core 调用百度 PaddleOCR 识别图文
    ASP.NET Core 查看应用状态和统计
    锐浪报表 winform程序 数据源设置为excel时提示用户名密码隐藏
    单例
    WPF 设计器一直加载一分钟才显示
    .net 5 SignalR WPF 服务端+客户端
    WPF 使用Image 捕获摄像头数据,并将image改为圆形
    Vue Element-ui Table实现动态新增和删除
    Element-UI 中使用rules验证
    @Value读取不到配置文件的值
  • 原文地址:https://www.cnblogs.com/mengfanrong/p/5042319.html
Copyright © 2011-2022 走看看