在长时间处理期间与GUI交互

时间:2012-11-01 13:45:14

标签: c++ user-interface mfc

我有一个类的层次结构:

class BaseProcess
{
    public virtual void Execute() = 0;  

};

class SubProcess : BaseProcess
{
    public virtual void Execute()
    {
        //Do Something

        //Need to call back to the GUI here, maybe to get a file path from a file selector

        //Do Something Else

        //Now want to update the GUI with the progress of the operation perhaps

        //More processing   
    }
};

假设从GUI按钮事件处理程序创建并调用了一个SubProcess对象......

我的问题是在Execute()函数中与GUI交互的最佳方式是什么? (还假设Execute()可能在不同的线程上运行)

我的想法是将Callback传递给SubProcess对象,因为这将允许我向GUI发送信息,但是在文件选择器的情况下,什么是将数据恢复到最佳的方式SubProcess对象?我希望解决方案尽可能通用,以便根据请求返回不同类型的数据。

注意:请忽略任何代码错误,我快速将样本拼凑起来只是为了说明问题

更新

很抱歉要明确,这将是Windows,MFC。我不确定这有多重要,因为我认为整体设计应该适用于大多数GUI框架?

4 个答案:

答案 0 :(得分:2)

class SubProcess : BaseProcess
{
    public virtual void Execute()
    {
        //Do Something

        char file_name[MAX_PATH +1];
        myWindow->SendMessage(WM_GETFILE, max_path, (LPARAM)file_name); 

        //Do Something Else

        myWindow->SendMessage(WM_UPDATE, 50);

        //More processing   
    }
};

在窗口类中:

#define WM_GETFILE (WM_USER+1)
#define WM_UPDATE (WM_USER+2)

BEGIN_MESSAGE_MAP(CMyWindow, CWnd)
    ON_MESSAGE(WM_GETFILE, MyGetFileHandler)
    ON_MESSAGE(WM_UPDATE, MyUpdateHandler)
END_MESSAGE_MAP()

LRESULT CMyWindow::MyGetFileHandler(WPARAM wParam, LPARAM lParam)
{
}
LRESULT CMyWindow::MyUpdateHandler(WPARAM wParam, LPARAM lParam)
{
}

答案 1 :(得分:1)

我前段时间使用的MFC技术基于标准Idle Loop处理。

这是一种简单的方法,因为在主线程中运行,您的工作人员可以直接对GUI对象执行操作。

如果您“充分经常”从工作进程调用消息循环,GUI将继续顺利运行。

如果你在开发周期中可以承受一些复杂性,你可以使用线程,但根据我的经验,它“更难。”

答案 2 :(得分:0)

取决于GUI。如果您使用的GUI允许您从不同的线程控制它,那么您可以从Execute()内部进行直接的GUI调用。如果GUI不允许这样做,那么你可以通过消息与主线程进行通信,在那里进行GUI调用,并将结果发送回Execute()线程。

使用Qt signals and slots mechanism的{{3}}是一个简单易用的GUI框架。

答案 3 :(得分:0)

class GuiCallback
{
 public:
     string getFilePath () {/*show the dialog and return the path*/}
     void update (/*arguments with data*/) {}
};
class BaseProcess
{
    public virtual void Execute(GuiCallback*) = 0;  

};

class SubProcess : BaseProcess
{
    public virtual void Execute(GuiCallback* callback)
    {
        //Do Something

        string path = callback->getFilePath ();

        //Do Something Else

        callback->update (...);

        //More processing   
    }
};

getFilePathupdate的实施将取决于您使用的平台/ gui框架