How to update guidata in the addlistener callback function?
現在この質問をフォロー中です
- フォローしているコンテンツ フィードに更新が表示されます。
- コミュニケーション基本設定に応じて電子メールを受け取ることができます。
エラーが発生しました
ページに変更が加えられたため、アクションを完了できません。ページを再度読み込み、更新された状態を確認してください。
古いコメントを表示
I am developing a program for a company.
In the GUI I first grouped a number of checkboxes into one handle object (for instance I have 10 checkboxes).
for i = 1 : 10
checkboxes(i-1) = handles.(sprintf('checkbox%d', i));
end
handles.checkboxes= checkboxes;
Then I used the addlistener function to detect any changes for the group of checkboxes.
addlistener(handles.checkboxes, 'Value', 'PostSet', @(hObject, eventdata, handles) callback(hObject, eventdata, handles));
In the callback function, I wanted to update the value for 'anyObject' and in the end of the function I updated the handles structure so that the value of the 'anyObject' can be used by other functions.
function handles = callback(hObject, eventdata, handles)
handles.anyObject = get(handles.checkbox1,'Value');
% Update handles structure
guidata(hObject, handles);
The problem I have is that the program always throws me this error whenever I click the checkbox button:
Warning: Error executing listener callback for PostSet event on Value dynamic property in object of
matlab.ui.control.UIControl class:
Not enough input arguments.
採用された回答
Guillaume
2017 年 3 月 21 日
Note:
for i = 1:10
checkbox(i-1) = ...
will error on the first iteration, since checkbox(1-1=0) is not a valid index.
Note 2:
@(hObject, eventdata, handles) callback(hObject, eventdata, handles)
Since this anonymous function only job is to pass all its inputs to another function unchanged, it could just be skipped. That is
@callback
would do the same.
Note 3:
function handle = callback(...)
A proper callback never returns anything since there is no mechanism for getting that return value.
Now for your question, the immediate problem comes from the anonymous function you've defined. An listener callback must have two inputs arguments and only two. These are, the object generating the event, and some event data. Therefore, the inputs to your anonymous function can only be:
@(hobject, eventdata) ...
handles cannot be an input since it won't be sent by the event. Now, if you wanted handles to be passed to your callback function, you could define your anonymous function as:
@(hobject, eventdata) callback(hobject, eventdata, handle)
This would work with you example, but I wouldn't recommend that. The anonymous function captures the content of the handle structure at the point it is defined, so any change to that handle structure after that line won't be seen by your callback, e.g.:
lh = addlistener(handles.checkboxes, 'Value', 'PostSet', @(hObject, eventdata) callback(hObject, eventdata, handles));
handles.text = uicontrol('Style', 'text', 'String', 'some new control'); %add a new control to handle
The handle received by your callback will not contain the text field as it was created after handle was captured.
A safer way is simply to get the handle structure with guidata inside your callback, so:
lh = addlistener(handles.checkboxes, 'Value', 'PostSet', @callback); %not passing handle to callback
function callback(hObject, eventdata) %not receiving handle
handle = guidata(hobject); %get handle inside the callback.
%...
11 件のコメント
Hi Guillaume,
Thanks so much for your swift reply.
I have made an update to the mistakes but I still received this error message:
Warning: Error executing listener callback for PostSet event on Value dynamic property in object of
matlab.ui.control.UIControl class:
Not enough input arguments.
Is there any way to update the handles inside the callback function?
Adam
2017 年 3 月 21 日
What is the exact code you now have for the function signature and the addlistener line?
for i = 1:10
checkboxes(i) = handles.(sprintf('checkbox%d', i));
end
handles.checkboxes= checkboxes;
addlistener(handles.checkboxes, 'Value', 'PostSet', @callback);
%=============================================================
function callback(hObject, eventdata)
handles = guidata(hObject);
handles.text = 'testing';
guidata(hObject,handles);
return
After that the below error message is thrown:
Warning: Error executing listener callback for PostSet event on Value dynamic property in object of
matlab.ui.control.UIControl class:
Error using guidata (line 87)
H must be the handle to a figure or figure descendent.
Error in GUI>callback (line 189)
handle = guidata(hObject);
Ah ok, well that is a different error message to the one you previously reported which seemed more odd.
If you put a breakpoint on that line what is
hObject
?
Woen Yon Lai
2017 年 3 月 21 日
Sorry... on which line?
The line giving the error:
handles = guidata( object );
The error remains the same:
Warning: Error executing listener callback for PostSet event on Value dynamic property in object of
matlab.ui.control.UIControl class:
Error using guidata (line 87)
H must be the handle to a figure or figure descendent.
Error in GUI>callback (line 189)
handle = guidata(hObject);
Well, of course, nothing changed, I'm asking what hObject is when you put a breakpoint on that line and you then type
hObject
on the command line.
Right, that particular problem is due to the fact that you're listening to a PostSet event on the Value of a UIControl. That's not really the normal way to get informed of changes to UIControl.
The proper way to do this, is to give a callback function to the Callback property of the UIControl. So instead of your addlistener, you'd have:
[handles.checkboxes.CallBack] = deal(@callback);
%or assign the Callback property in a loop to avoid the strange bracket syntax and the deal
And the callback would be, as previously shown:
function callback(hObject, eventdata)
%hobject is the UIControl triggering the event
handle = guidata(hobject); %get handle inside the callback.
%...
You can still do it with a PropSet listener, however, the object generating the event is a GraphicsMetaProperty object that you cannot pass to guidata. You actually get the Control in one of the event property, so if you want to do it with the listener the code has to be:
lh = addlistener(handles.checkboxes, 'Value', 'PostSet', @callback); %same as before
function callback(~, eventdata) %don't care about the source, it's not useful
handle = guidata(eventdata.AffectedObject)
%...
To reply @Adam: Sorry for the misunderstanding. After I type hObject the console printed out this:
hObject =
GraphicsMetaProperty with properties:
Name: 'Value'
Description: 'Value PropInfo'
DetailedDescription: ''
GetAccess: 'public'
SetAccess: 'public'
Dependent: 1
Constant: 0
Abstract: 0
Transient: 0
Hidden: 0
GetObservable: 1
SetObservable: 1
AbortSet: 1
NonCopyable: 0
GetMethod: []
SetMethod: []
HasDefault: 0
DefiningClass: [1×1 matlab.graphics.internal.GraphicsMetaClass]
Woen Yon Lai
2017 年 3 月 22 日
To reply @Guillaume: Thanks so much for your help! It works like a charm!
その他の回答 (0 件)
カテゴリ
ヘルプ センター および File Exchange で Creating, Deleting, and Querying Graphics Objects についてさらに検索
製品
参考
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!Web サイトの選択
Web サイトを選択すると、翻訳されたコンテンツにアクセスし、地域のイベントやサービスを確認できます。現在の位置情報に基づき、次のサイトの選択を推奨します:
また、以下のリストから Web サイトを選択することもできます。
最適なサイトパフォーマンスの取得方法
中国のサイト (中国語または英語) を選択することで、最適なサイトパフォーマンスが得られます。その他の国の MathWorks のサイトは、お客様の地域からのアクセスが最適化されていません。
南北アメリカ
- América Latina (Español)
- Canada (English)
- United States (English)
ヨーロッパ
- Belgium (English)
- Denmark (English)
- Deutschland (Deutsch)
- España (Español)
- Finland (English)
- France (Français)
- Ireland (English)
- Italia (Italiano)
- Luxembourg (English)
- Netherlands (English)
- Norway (English)
- Österreich (Deutsch)
- Portugal (English)
- Sweden (English)
- Switzerland
- United Kingdom (English)
