2013-02-04 69 views
14

我正在MATLAB的GUI中工作,并使用选项卡来组织信息。由于这些选项卡在MATLAB GUIDE中不受支持,我只是创建了几个uipanel s并更改它们的'Visible'字段。但是,如果每个面板中的控件数量很大,则需要一段时间才能在面板之间切换。有没有人知道一种方法来更快地切换制表符?在MATLAB GUI中优化的选项卡

我包括基于选项卡的界面的一个简单的例子。

tab_example_gui.m

% Figure 
handles.figure_window = figure(... 
    'Units','characters',... 
    'Tag','figure_window',... 
    'Position',[50 50 80 25],... 
    'Name','Tab Example',... 
    'DockControls','off',... 
    'IntegerHandle','off',... 
    'MenuBar','none',... 
    'NumberTitle','off',... 
    'Resize','off'); 

% Buttons 
handles.tab_panel = uibuttongroup(... 
    'Parent',handles.figure_window,... 
    'Tag','tab_panel',... 
    'Units','characters',... 
    'Position',[0 23 80 2],... 
    'SelectionChangeFcn',@(hObject,eventdata)tab_example_callback(hObject,eventdata,guidata(hObject)),... 
    'BorderType','none'); 
handles.tab_a = uicontrol(... 
    'Parent',handles.tab_panel,... 
    'Tag','tab_a',... 
    'Units','characters',... 
    'Position',[0 0 40 2],... 
    'Style','togglebutton',... 
    'String','Tab A'); 
handles.tab_b = uicontrol(... 
    'Parent',handles.tab_panel,... 
    'Tag','tab_b',... 
    'Units','characters',... 
    'Position',[40 0 40 2],... 
    'Style','togglebutton',... 
    'String','Tab B'); 


% Panel A 
handles.panel_a = uipanel(... 
    'Parent',handles.figure_window,... 
    'Tag','panel_menu',... 
    'Units','characters',... 
    'Position',[0.1 0 79.8 23],... 
    'Visible','On'); 
handles.panel_a_text = uicontrol(... 
    'Parent',handles.panel_a,... 
    'Tag','panel_menu_load_id_text',... 
    'Units','characters',... 
    'Position',[0 0 77 22],... 
    'Style','text',... 
    'String','This is the tab A'); 

% Panel B 
handles.panel_b = uipanel(... 
    'Parent',handles.figure_window,... 
    'Tag','panel_menu',... 
    'Units','characters',... 
    'Position',[0.1 0 79.8 23],... 
    'Visible','Off'); 
handles.panel_b_text = uicontrol(... 
    'Parent',handles.panel_b,... 
    'Tag','panel_menu_load_id_text',... 
    'Units','characters',... 
    'Position',[0 0 77 22],... 
    'Style','text',... 
    'String','This is the tab B'); 

guidata(handles.figure_window, handles); 

tab_example_callback.m

function tab_example_callback(hObject,eventdata,handles) 
    switch get(get(hObject,'SelectedObject'),'Tag') 
     case 'tab_a', set(handles.panel_a,'Visible','On'); set(handles.panel_b,'Visible','Off'); 
     case 'tab_b', set(handles.panel_a,'Visible','Off'); set(handles.panel_b,'Visible','On'); 
    end 
    guidata(handles.figure_window, handles); 
end 

注意:GUI是介绍参数为在5个选项卡的模拟。在每个标签中,我有大约15行;每行有一个text,1个checkbox和三个edit s。它看起来并不拥挤。此外,我用最少的代码和开销自行完成了布局和回调。但是,它仍然有非常恼人的标签转换。

+1

我在想所有的面板都可以看到,但是他们的位置放在主图的外面。因此,当选中标签时,旧标签将被移开,并且新标签被带入。通过这种方式,可能所有面板都被缓存在GPU内存中,并且转换速度更快...... – tashuhka

+1

我认为渲染的默认值足够快,即'DoubleBuffer','on','Renderer','画家','RendererMode','auto'。任何其他组合可能会更快? – tashuhka

+0

我试图使用“位置”而不是“可见”作为切换标签页的参数,但我无法理解任何改进。我也尝试了不同的渲染组合,结果相同。 – tashuhka

回答

3

也许如果你把手柄在数组中。这样你就不必经历其中的每一个。这似乎快给我,但“快”可以意味着很多东西:)

我去掉了一些特性,使的例子更短......

function test(N) % N is the number of tabs 
if nargin == 0 
    N = 3; 
end 

% Figure 
handles.figure_window = figure(... 
    'Units','characters',... 
    'Position',[50 50 80 25]); 
% Buttons 
handles.tab_panel = uibuttongroup(... 
    'Parent',handles.figure_window,... 
    'Units','characters',... 
    'Position',[0 23 80 2]); 

alpha = 'ABCDEFGHIJKLMNOPQRSTUVXYZ'; 
for i_tab=1:N 
    % button 
    handles.tabs(i_tab) = uicontrol(... 
     'Parent',handles.tab_panel,... 
     'Units','characters',... 
     'Position',[80/N*(i_tab-1) 0 80/N 2],... 
     'Style','togglebutton',... 
     'String',['Tab ' alpha(i_tab)]); 

    % Panel i 
    handles.panels(i_tab) = uipanel(... 
     'Parent',handles.figure_window,... 
     'Units','characters',... 
     'Position',[0.1 0 79.8 23],... 
     'Visible','Off'); 
    handles.panel_a_text = uicontrol(... 
     'Parent',handles.panels(i_tab),... 
     'Units','characters',... 
     'Position',[0 0 77 22],... 
     'Style','text',... 
     'String',['This is the tab ', alpha(i_tab)]); 
end 
% set callback for all buttons 
set(handles.tabs, 'callback', {@tab_example_callback handles}) 
% choose tab 1 as active 
set(handles.panels(1), 'Visible','On'); 
guidata(handles.figure_window, handles); 

function tab_example_callback(hObject,eventdata,handles) 
% set everything invisible 
set(handles.panels,'Visible','Off'); 
% turn on selected panel 
set(handles.panels(handles.tabs == hObject), 'Visible','On'); 
guidata(handles.figure_window, handles); 

是否帮助你呢?

+1

这是一个有趣的想法。 Profiler实际上显示出稍好的计算时间。不幸的是,它对于人眼的感觉不够重要。但是,谢谢你的时间和代码,它看起来很整齐,并提出了一些很好的想法来提高我的编码:) – tashuhka

1

如果你可以自由地使用无证的功能,我建议使用uitabtabdlg。见this post on undocumentedmatlab.com

+1

谢谢你的建议。似乎Mathworks实际上在制表符上工作,这非常棒。不幸的是,我不能部署代码,这可能不会在近期发挥作用。 – tashuhka

2

我强烈建议,如果你正在创建一个任何复杂的GUI,你可以看看GUI Layout Toolbox,不要使用GUIDE--它不适合用于创建复杂GUI的目的(这不是一种批评,它只是它仅用于制作快速,简单的GUI)。

GUI布局工具箱使得它大大方便地创建专业标准的图形用户界面,并包括标签功能,以及很多其他如易调整大小和额外的小部件。

为了解决一些你在评论其他答案提出的关注。 GUI布局工具箱不使用MATLAB的未公开/不支持/隐藏的特征。虽然它不是官方的MathWorks产品,但它是由MathWorks咨询小组的Ben Tordoff和David Sampson开发的,并且可以根据许可证免费获得,这意味着您可以使用并包含在已部署的产品中。

作为一个方面说明,你在一个评论,你的每个选项卡包含约50控制不在话下。我想知道真正的解决方案是否可能重新设计您的GUI?当然,你最好知道什么适合你的应用程序,但是用户可以立即看到50个控件,似乎从可用性的角度来看可能是一个坏主意,并且会给GUI重绘时间带来困难。

+0

谢谢您的详细回复,@Sam Roberts。我看了一下GUI布局工具箱,它的确做了很棒的工作。在文件* CardPanel.m *中,它包含处理标签可见性的函数* showSelectedChild *。他们通过将2500个像素移开不可见的面板来改变标签的位置。过去我尝试过这个选项,闪烁和冻结仍然存在。 – tashuhka

+0

顺便说一句,我完全同意你的GUIDE对于复杂的GUI没有用。实际上,我自己编写布局以控制所有模块。 – tashuhka

+3

如果面板上有〜50个控件,我认为有些闪烁或缺乏GUI响应可能是不可避免的。我之前曾经通过禁用一个小组的所有孩子,进行过渡,添加一个“暂停(0.5)”,然后重新启用孩子来解决类似的情况。有一个延迟,但没有闪烁,我发现人们觉得它更容易接受,因为禁用会导致控件变灰,所以他们“知道发生了什么”。如果它真的很糟糕,您也可以使用一些Java将光标暂时更改为微调器。 –