2013-02-04 73 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將光標暫時更改爲微調器。 –