《又到毕业季》MATLAB GUI 鼠标键盘交互

眼看六月就要毕业答辩了,你的论文是不是还差一个GUI没有做呢,赶紧学起来。

by 今天不飞了


视频教学地址

《又到毕业季》MATLAB GUI(九)鼠标交互
《又到毕业季》MATLAB GUI(十)键盘交互


一、鼠标交互


1. 基本知识

set(Fig,'WindowButtonDownFcn',@ButtonDown);
set(Fig,'WindowButtonUpFcn',@ButtonUp);
set(Fig,'WindowButtonMotionFcn',@ButtonMotion);
set(Fig,'WindowScrollWheelFcn',@ScrollWheel);


2. 实例

function GUI9()

%% 搭框架
Fig = figure('Position',[600,200,1000,750],'menu','none',...
    'Color','white','NumberTitle','off','Name','GUI9');
% 回调
set(Fig,'WindowButtonDownFcn',@ButtonDown);
set(Fig,'WindowButtonUpFcn',@ButtonUp);
set(Fig,'WindowButtonMotionFcn',@ButtonMotion);
set(Fig,'WindowScrollWheelFcn',@ScrollWheel);
% 面板
Pnl1 = uipanel(Fig,'Position',[0.05,0.05,0.7,0.9]);
Pnl2 = uipanel(Fig,'Position',[0.75,0.05,0.2,0.9]);
% 绘图窗
Axes = axes(Pnl1,'Position',[0.1,0.1,0.8,0.8]);
axis([-1,1,-1,1]),grid on,hold on
% 文本框
str = '';
Text = uicontrol(Pnl2,'style','text',...
    'String',str,'Fontsize',16,...
    'Units','normalized','Position',[0.1,0.1,0.8,0.5]);
% 按钮组
Bt1 = uicontrol(Pnl2,'style','togglebutton',...
    'String','创建新圆形','Fontsize',16,'BackgroundColor',[0.6,1,0.6],...
    'Unit','normalized','Position',[0,0.9,1,0.1],...
    'Callback',@Doit1);
Bt2 = uicontrol(Pnl2,'style','togglebutton',...
    'String','修改已有圆形','Fontsize',16,'BackgroundColor',[0.6,0.6,1],...
    'Unit','normalized','Position',[0,0.8,1,0.1],...
    'Callback',@Doit2);
Bt3 = uicontrol(Pnl2,'style','togglebutton',...
    'String','清除已有圆形','Fontsize',16,'BackgroundColor',[1,0.6,0.6],...
    'Unit','normalized','Position',[0,0.7,1,0.1],...
    'Callback',@Doit3);

%% 成员
% 执行什么任务
task = 0;
state = 0;
tmp = [];% 存临时句柄
% 记录鼠标位置
p1 = [];
p2 = [];
% 圆信息
circleInfo = []; % 存圆心半径
circleList = {}; % 存句柄
circleNum = 0; % 数量
circleIdx = 0; % 当前操作对象
basicCircle = DrawCircle(); % 基本结构

%% 按钮组
    function Doit1(~,~)
        if get(Bt1,'Value')
            set(Bt2,'Value',0)
            set(Bt3,'Value',0)
            task = 1;
            str = '请确定圆心位置';
            set(Text,'String',str)
        else
            task = 0;
        end
    end

    function Doit2(~,~)
        if get(Bt2,'Value')
            set(Bt1,'Value',0)
            set(Bt3,'Value',0)
            task = 2;
            str = '请选择要修改的圆';
            set(Text,'String',str)
        else
            task = 0;
        end
    end

    function Doit3(~,~)
        if get(Bt3,'Value')
            set(Bt1,'Value',0)
            set(Bt2,'Value',0)
            task = 3;
            str = '请选择要删除的圆';
            set(Text,'String',str)
        else
            task = 0;
        end
    end

%% 鼠标组
    function ButtonDown(~,~)
        cp = get(gca,'currentpoint');
        switch task
            case 1
                p1 = [cp(1,1),cp(1,2)];
                tmp = plot(p1(1),p1(2),'r.','Parent',Axes);
                state = 1;
            case 2
                if circleNum>0
                    p1 = [cp(1,1),cp(1,2)];
                    circleIdx = ChooseCircle(circleInfo,p1);
                    set(circleList{circleIdx},'LineStyle','--')
                    state = 1;
                end
            case 3
                if circleNum>0
                    p1 = [cp(1,1),cp(1,2)];
                    circleIdx = ChooseCircle(circleInfo,p1);
                    state = 1;
                end
        end
    end

    function ButtonUp(~,~)
        if state
            cp = get(gca,'currentpoint');
            switch task
                case 1
                    delete(tmp)
                    p2 = [cp(1,1),cp(1,2)];
                    R = norm(p1-p2);
                    [cx,cy] = Updata(basicCircle,[p1,R]);
                    h = plot(cx,cy,'LineWidth',5,'Parent',Axes);
                    
                    circleNum = circleNum+1;
                    circleIdx = circleNum;
                    circleInfo(circleNum,:) = [p1,R];
                    circleList{circleNum} = h;
                case 2
                    set(circleList{circleIdx},'LineStyle','-')
                case 3
                    delete(circleList{circleIdx})
                    circleList(circleIdx) = [];
                    circleInfo(circleIdx,:) = [];
                    circleNum = circleNum-1;
            end
            state = 0;
        end
    end

    function ButtonMotion(~,~)
        if task==2 && state
            cp = get(gca,'currentpoint');
            p2 = [cp(1,1),cp(1,2)];
            dp = p2-p1;
            if norm(dp)>0.01
                circleInfo(circleIdx,1:2) = circleInfo(circleIdx,1:2)+dp;
                [cx,cy] = Updata(basicCircle,circleInfo(circleIdx,:));
                circleList{circleIdx}.XData = cx;
                circleList{circleIdx}.YData = cy;
                p1 = p2;
            end
        end
    end

    function ScrollWheel(~,event)
        if task==2 
            cp = get(gca,'currentpoint');
            p2 = [cp(1,1),cp(1,2)];
            circleIdx = ChooseCircle(circleInfo,p2);
            
            value = event.VerticalScrollCount; % 关键句
            circleInfo(circleIdx,3) = max(circleInfo(circleIdx,3)+value*0.01,0.01);
            [cx,cy] = Updata(basicCircle,circleInfo(circleIdx,:));
            circleList{circleIdx}.XData = cx;
            circleList{circleIdx}.YData = cy;
            
        end
    end

%% 子函数
% 计算距离
    function idx = ChooseCircle(circleInfo,C)
        dis = sum((circleInfo(:,1:2)-C).^2,2);
        [~,idx] = min(dis);
    end

% 更新圆
    function [cx,cy] = Updata(basicCircle,w)
        cx = w(3)*basicCircle(:,1)+w(1);
        cy = w(3)*basicCircle(:,2)+w(2);
    end

% 生成圆形
    function out = DrawCircle()
        t = 0:pi/32:2*pi;
        cx = cos(t');
        cy = sin(t');
        out = [cx,cy];
    end

end

二、键盘交互

持续更新中


1. 基本知识

set(Fig,'WindowKeyPressFcn',@KeyDown);
set(Fig,'WindowKeyReleaseFcn',@KeyUp);


2. 实例

clear; close all; clc

GUI10();

function GUI10()

%% 搭框架
Fig = figure('Position',[600,500,1000,500],'menu','none',...
    'Color','white','NumberTitle','off','Name','GUI10');
set(Fig,'WindowKeyPressFcn',@KeyDown);
set(Fig,'WindowKeyReleaseFcn',@KeyUp);

% 绘图窗
Axes = axes(Fig,'Position',[0.1,0.1,0.8,0.8]);
axis(10*[-1,1,0,1]),grid on,hold on
plot([-20,20],[0,0],'k-','LineWidth',3,'Parent',Axes);

% 初始化
state = 0;
r = 1;
cir = DrawCircle(r);
p = [0,r];      % 当前位置
v = [0,0];      % 当前速度
dv = [5,10];    % 速度改变值
a = [0,0];      % 当前加速度
da = [-5,-20];  % 加速度改变值
H = plot(cir(:,1)+p(1),cir(:,2)+p(2),'r-','LineWidth',3,'Parent',Axes);
drawnow

%% 执行
dt = 0.01;
t = zeros(2,2);
while 1
   
    if isvalid(Axes)
        xalim = get(Axes,'xlim');
        yalim = get(Axes,'ylim');
    else
        break
    end

     if state
        % 速度检测
        tmp = v;
        v = v+a*dt;
        if (tmp(1)*v(1))<=0
            v(1) = 0;
        end
        % 落地碰撞检测
        p = p+v*dt;
        if p(2)<r
            p(2) = r;
            v(2) = 0;
        end
        if norm(v)==0
            state = 0;
        end
        H.XData = cir(:,1)+p(1);
        H.YData = cir(:,2)+p(2);
     end
    
    drawnow
end

    function KeyDown(~,~)
        pt = get(gcf,'CurrentCharacter');
        if strcmpi(pt,'a') %v(1) = -dv(1);
            a(1) = -da(1);
            state = 1;
        end
        if strcmpi(pt,'d') %v(1) = dv(1);
            a(1) = da(1);
            state = 1;
        end
        if strcmpi(pt,'w') %v(2) = dv(2);
            a(2) = da(2);
            state = 1;
        end
    end

    function KeyUp(~,~)
        pt = get(gcf,'CurrentCharacter');
        if strcmpi(pt,'a') %if t(1,1)==0
                t(1,1) = now;
            else
                t(1,2) = now;
                if (t(1,2)-t(1,1))*86400<0.5
                    p(1) = p(1)-dv(1)*0.5;
                    t(1,1) = 0;
                else
                    t(1,1) = t(1,2);
                end
            end
        end
        
        if strcmpi(pt,'d') %if t(2,1)==0
                t(2,1) = now;
            else
                t(2,2) = now;
                if (t(2,2)-t(2,1))*86400<0.5
                    p(1) = p(1)+dv(1)*0.5;
                    t(2,1) = 0;
                else
                    t(2,1) = t(2,2);
                end
            end
        end
        
    end

    function out = DrawCircle(r)
        t = 0:pi/16:2*pi;
        cx = r*cos(t');
        cy = r*sin(t');
        out = [cx,cy];
    end

end


其他

此文为《又到毕业季》MATLAB GUI系列视频的代码。
持续更新中—

  • 8
    点赞
  • 34
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值