如何使用WxWidgets关闭Erlang中的程序?

时间:2015-12-16 18:57:12

标签: erlang wxwidgets

我在Erlang中关闭程序时遇到问题。我使用wxWidgets。

public class AsOfdates
{
    public string DisplayDate { get; set; }
    private DateTime TheDate;
    public DateTime DateValue { get { return TheDate.Date; } set { TheDate = value; } }

}

但该计划并没有结束;退出图标或退出菜单都不做任何事情。

2 个答案:

答案 0 :(得分:1)

你差不多了,但是有一些错误。

首先,您提交的退出选择永远不会生成任何事件,您需要再次使用connect,如下所示:

Quit = wxMenuItem:new ([{id,400},{text, "&Quit"}]),
wxFrame:connect(Frame, command_menu_selected),

现在每个quit方法都有一个事件,但它们都没有工作。

您的退出图标的事件不匹配,因为您的模式匹配中的事件类型错误,并且菜单退出选择的事件不匹配,因为您正在寻找ID为“EXIT”的ID,定义为?wxID_EDIT,定义为..显然不是400,即创建退出菜单项时使用的ID。因此,您的接收条款需要更改为:

receive
    #wx{event=#wxClose{type=close_window}} ->
        io:format("quit icon"),
        wxFrame:destroy(Frame);
    #wx{id=400, event=#wxCommand{type=command_menu_selected}} ->
        io:format("quit file menu"),
        wxFrame:destroy(Frame)
    end.

答案 1 :(得分:1)

除了迈克尔关于使用connect/3监听菜单命令的答案之外,几乎任何一个框架都需要一些标准的事件连接来表现你期望它们关闭的方式以及任何特定的你发生的事情。请注意,这是连接到close_window事件并使用选项{skip, true}。这样信号就不会在它到达Wx的部分之前停止传播,Wx将以你期望的方式处理它(一次点击关闭),而不是在某些平台上需要两次点击来关闭帧。

基本骨架通常如下所示:

init(Args) ->
    Wx = wx:new(),
    Frame = wxFrame:new(Wx, ?wxID_ANY, ""),

    % Generate whatever state the process represents
    State = some_state_initializer(Args),

    % Go through the steps to create your widget layout, etc.
    WidgetReferences = make_ui(Frame),

    % The standardish connects nearly any frame will need.
    ok = wxFrame:connect(Frame, close_window, [{skip, true}]),
    ok = wxFrame:connect(Frame, command_button_clicked),
    ok = wxFrame:connect(Frame, command_menu_selected),
    % Add more connects here depending on what you need.

    % Adjust the frame size and location, if necessary
    Pos = initial_position(Args),
    Size = initial_size(Args),
    ok = wxFrame:move(Frame, Pos),
    ok = wxFrame:setSize(Frame, Size),

    wxFrame:show(Frame),

    % Optional step to add this frame to a UI state manager if you're
    % writing a multi-window application.
    ok = gui_manager:add_live(self()),

    % Required return for wx_object behavior
    {Frame, State}.

从原版中删除一点,但强烈相关......

许多wxWidgets应用程序都有类似于此的非常,根据需要进行自定义,而不是通过再次编写所有内容,而是通过定义自己的回调模块并将其作为参数传递:

init({Mod, Args}) ->
    % ...
    PartialState = blank_state([{mod, Mod}, {frame, Frame}, {wx, Wx}]),
    State = Mod:finalize(PartialState, Args),

blank_state/1接受一个proplist并返回实际数据结构稍后的内容(通常是此级别的记录,看起来像#s{mod, frame, wx, widgets, data}),而Mod:finalize/2则不完整state和初始args并返回一个完整的GUI框架以及它应该管理的任何程序状态 - 特别是widgets数据结构,它带有对你需要监听,匹配或者需要的任何GUI元素的引用稍后操纵。

稍后你有一些非常基本的通用处理程序,所有框架可能需要处理,并将任何其他消息传递给特定的Mod

handle_call(Message, From, State = #s{mod = Mod}) ->
    Mod:handle_call(Message, From, State).

handle_cast(blit, State) ->
    {ok, NewState} = do_blit(State),
    {noreply, NewState};
handle_cast(show, State) ->
    ok = do_show(State),
    {noreply, State};
handle_cast(Message, State = #s{mod = Mod}) ->
    Mod:handle_cast(Message, State).

在这种情况下,do_blit/1最终会在回调模块中调用Mod:blit/1来重建和刷新GUI,通过调用在wx:batch/1内执行此操作的函数从零重建它以使其成为对用户来说是即时的:

blit(State) ->
    wx:batch(fun() -> freshen_ui(State) end).

如果您要在GUI中同时更改很多元素,那么从用户的角度来看,blitting更加顺畅和快速,而不是逐步改变事物或隐藏/显示元素 - 并且< em>很多更确定在平台和各种计算机速度和用户空间负载下感觉相同(一些Wx后端会产生很多闪烁或中间显示的怪异,否则)。

do_show/1函数通常类似于

do_show(#s{frame = Frame}) ->
    ok = wxFrame:raise(Frame),
    wxFrame:requestUserAttention(Frame).

(我的意思是写一个基本的&#34;这是构建一个多窗口wxErlang应用程序的一种方法&#34;教程/示例但是还没有找到它,所以很多这里缺少详细信息,但在您编写了几个程序之后,您将自己偶然发现它们。)