如何使用WxWidgets关闭Erlang中的程序?
我在关闭Erlang中的程序时遇到问题。我使用wxWidgets如何使用WxWidgets关闭Erlang中的程序?,erlang,wxwidgets,Erlang,Wxwidgets,我在关闭Erlang中的程序时遇到问题。我使用wxWidgets -module(g). -compile(export_all). -define(height, 500). -define(width, 500). -include_lib("wx/include/wx.hrl"). -define(EXIT,?wxID_EXIT). init() -> start(). start() -> Wx = wx:new(), Frame = wxFr
-module(g).
-compile(export_all).
-define(height, 500).
-define(width, 500).
-include_lib("wx/include/wx.hrl").
-define(EXIT,?wxID_EXIT).
init() ->
start().
start() ->
Wx = wx:new(),
Frame = wxFrame:new(Wx, -1, "Line", [{size, {?height, ?width}}]),
setup(Frame),
wxFrame:show(Frame),
loop(Frame).
setup(Frame) ->
menuBar(Frame),
wxFrame:connect(Frame, close_window).
menuBar(Frame) ->
MenuBar = wxMenuBar:new(),
File = wxMenu:new(),
wxMenuBar:append(MenuBar,File,"&Fichier"),
wxFrame:setMenuBar(Frame,MenuBar),
Quit = wxMenuItem:new ([{id,400},{text, "&Quit"}]),
wxMenu:append (File, Quit).
loop(Frame) ->
receive
#wx{event=#wxCommand{type=close_window}} ->
io:format("quit icon"),
wxWindow:close(Frame,[]);
#wx{id=?EXIT, event=#wxCommand{type=command_menu_selected}} ->
io:format("quit file menu"),
wxWindow:close(Frame,[])
end.
但是这个项目没有结束;退出图标和退出菜单都不起任何作用。您就快到了,但是有一些错误 首先,您提到的退出选择从未生成任何事件,您需要再次使用
connect
,如下所示:
Quit = wxMenuItem:new ([{id,400},{text, "&Quit"}]),
wxFrame:connect(Frame, command_menu_selected),
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.
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}.
现在,每个quit方法都有一个事件,但它们都不能正常工作
退出图标的事件不匹配,因为模式匹配中的事件类型错误,而菜单退出选择的事件不匹配,因为您正在查找?EXIT的ID,该ID定义为?wxID_EDIT,该ID定义为。。显然不是400,你创建退出菜单项时使用的ID。因此,您的receive子句需要更改为如下内容:
Quit = wxMenuItem:new ([{id,400},{text, "&Quit"}]),
wxFrame:connect(Frame, command_menu_selected),
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.
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}.
除了Michael关于使用监听菜单命令的回答外,几乎任何帧都需要一些标准的事件连接,以便在结束时按照您所期望的方式进行操作,此外,还需要进行任何特定的操作。请注意,这是连接到
close_窗口
事件并使用选项{skip,true}
。这是为了在信号到达Wx部分之前不会停止传播,Wx部分将按照您期望的方式处理信号(单击一次即可关闭),而不是在某些平台上单击两次即可关闭帧
基本骨架通常如下所示:
Quit = wxMenuItem:new ([{id,400},{text, "&Quit"}]),
wxFrame:connect(Frame, command_menu_selected),
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.
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
获取不完整状态和初始参数,并返回一个完整的GUI框架加上它应该管理的任何程序状态——特别是小部件
数据结构,该结构包含对您以后需要侦听、匹配或操作的任何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
中执行此操作的函数,从零开始重建GUI,以使用户即时看到:
blit(State) ->
wx:batch(fun() -> freshen_ui(State) end).
如果一次在GUI中有很多元素需要更改,那么从用户的角度来看,blitting要比渐进式地四处移动或隐藏/显示元素更平滑、更快,而且在不同的平台、不同的计算机速度和用户负载中,blitting肯定会有相同的感受(有些Wx后端会出现大量闪烁或中间显示异常)
do_show/1
函数通常看起来像
do_show(#s{frame = Frame}) ->
ok = wxFrame:raise(Frame),
wxFrame:requestUserAttention(Frame).
(我一直想写一个基本的“这是构造多窗口wxErlang应用程序的一种方法”教程/示例,但还没有开始,所以这里缺少很多细节,但在编写了几个程序后,您会自己偶然发现它们。)非常感谢您的回答,我从中学到了很多!但在这里,“退出文件”菜单工作正常,但图标关闭windoe,但程序不关闭,提示被阻止。好的,我还认为问题一定来自我的代码的其余部分,但我不认为是哪里:是的,我忘了取消此功能,但这不是问题所在m、 如果我打开窗口,通过图标或菜单退出,效果很好,但是如果我在菜单图形中单击,然后在第一个项目中单击Ajour-sommet,那么我既不能通过图标退出,也不能通过退出菜单退出。