【IDL】滑鼠資訊顯示介面(同理可實現鷹眼圖等)

地理遥感生态网平台發表於2024-06-28

IDL實現程式介面時,很多時候需要實現滑鼠當前值的顯示,即那個滑鼠資訊時時顯示小窗體。

很多時候初學者想不明白,咋著能時時顯示那個滑鼠資訊呢。

參考下面的程式碼,知識點如下:

1、介面構建(選單、按鈕、文字框、顯示區域)

2、介面中滑鼠與鍵盤的事件響應(事件判斷)

3、介面由滑鼠修改大小(位置計算,元件修改)

4、介面關閉確認(判斷關閉事件,確認是否關閉)

5、滑鼠資訊顯示功能(時時顯示滑鼠位置座標)

【IDL】滑鼠資訊顯示介面(同理可實現鷹眼圖等)

附程式碼:

;+
;2010年7月北京IDL培訓班-示例程式碼
;
;
; Author: DYQ 2010-7-8;
;  Modified By DYQ:2011年12月15日
;          新增滑鼠資訊顯示介面
; BBS: http://bbs.esrichina-bj.cn/ESRI/forum-28-1.html
; E-Mail: dongyq@esrichina-bj.cn
; Blog: http://hi.baidu.com/dyqwrp
;-
 
; 事件響應程式
PRO  TEST_EVENTS_EVENT, event
  ;獲得頂base的uvalue,即元件資訊指標結構體
  WIDGET_CONTROL,event.TOP,get_uvalue=pstate 
  CASE TAG_NAMES(event,/STRUCTURE_NAME) OF
   ;關閉事件
   'WIDGET_KILL_REQUEST': BEGIN
     tmp = DIALOG_MESSAGE('確認關閉?',$
       title ='關閉系統',/question)
     IF tmp EQ 'Yes' THEN BEGIN
       ;注意銷燬之前建立的指標
       WIDGET_CONTROL,event.TOP,get_uValue = pState
       PTR_FREE, pState
       ;銷燬介面
       WIDGET_CONTROL,event.TOP,/destroy
       RETURN
     ENDIF
     RETURN
   END
   ;draw區域
   'WIDGET_DRAW': BEGIN   
     CASE event.TYPE OF
       ;注意不同的型別對應的不同的事件
       ;鍵盤和滑鼠等各自事件的結構體內容不一定一致的
       0: BEGIN
         PRINT,event.PRESS
         IF(event.PRESS AND 1) NE 0 THEN BEGIN
           WIDGET_CONTROL,(*pstate).TEXT1,set_value='左鍵按下'
         ENDIF
         IF(event.PRESS AND 2) NE 0 THEN BEGIN
           WIDGET_CONTROL,(*pstate).TEXT1,set_value='中鍵按下'
         ENDIF
         IF(event.PRESS AND 4) NE 0 THEN BEGIN
           WIDGET_CONTROL,(*pstate).TEXT1,set_value='右鍵按下'
         ENDIF
       END
       1: BEGIN
         IF(event.RELEASE AND 1) NE 0 THEN BEGIN
           WIDGET_CONTROL,(*pstate).TEXT1,set_value='左鍵釋放'
         ENDIF
         IF(event.RELEASE AND 2) NE 0 THEN BEGIN
           WIDGET_CONTROL,(*pstate).TEXT1,set_value='中鍵釋放'
         ENDIF
         IF(event.RELEASE AND 4) NE 0 THEN BEGIN
           WIDGET_CONTROL,(*pstate).TEXT1,set_value='右鍵釋放'
         ENDIF
       END
       2: BEGIN
         WIDGET_CONTROL,(*pstate).TEXT1,set_value='滑鼠移動'
         ;滑鼠位置
         WIDGET_CONTROL,(*pState).WSHOWXY, set_Value = ' 滑鼠位置:X'+STRTRIM(event.X,2)+' Y'+STRTRIM(event.Y,2)
       END
       3: BEGIN
       
       END
       
       4: BEGIN
         WIDGET_CONTROL,(*pstate).TEXT1,set_value='暴露事件'
       END
       5: BEGIN
         WIDGET_CONTROL,(*pstate).TEXT1,set_value = 'ch = ' +STRTRIM(STRING(event.CH),2)
       END
       6: BEGIN
         IF event.KEY EQ 1 THEN BEGIN
           PRINT,event.CH
         END
       END
       7: BEGIN
         IF event.CLICKS GT 0 THEN WIDGET_CONTROL,(*pstate).TEXT1,set_value='滾輪前滾' $
         ELSE  WIDGET_CONTROL,(*pstate).TEXT1,set_value='滾輪後滾'
       END
       ELSE: PRINT,event.TYPE
     ENDCASE
   END
   ELSE:
  ENDCASE
  uName = WIDGET_INFO(event.ID,/uname)
 
  IF uName EQ 'button' THEN BEGIN
   ;tmp = DIALOG_MESSAGE('資訊', /Info)
   tmp = DIALOG_MESSAGE((*pState).TESTSTR,/Infor)
  ENDIF
  ;設定大小
  IF uName EQ 'tlb' THEN BEGIN
   ;顯示元件大小適應程式大小
   drawXSize = event.X -(*pState).DRAWSPACE[0]
   drawYSize = event.Y -(*pState).DRAWSPACE[1]
   ;設定tlb大小(可忽略,因Draw元件後面已經設定了大小)
   WIDGET_CONTROL,event.TOP,xSize = event.X,ySize = event.Y
   ;設定顯示元件的大小
   WIDGET_CONTROL,(*pState).MYDRAW,xsize = drawXSize, ySize = drawYSize
   ;適應性顯示
   TVSCL,CONGRID(DIST(400),drawXSize,drawYSize)
  ENDIF
END
;
PRO TEST_MOUSE_EVENTS
 
  ; 建立一個主Base窗體
  tlb = WIDGET_BASE(TITLE='視窗事件演示', $
   xoffset =200, $
   yOffset =100, $
   mBar = mBar , $
   uname ='tlb', $
   /COLUMN, $
   ;重設定大小時產生事件
   /TLB_SIZE_EVENTS,$
   ;關閉時產生事件
   /TLB_KILL_REQUEST_EVENTS)
  ;建立系統選單
  wFile = WIDGET_BUTTON(mbar,value = '檔案(&F)')
  ; 建立一個按鈕
  base1=WIDGET_BASE(tlb,/row)
  label1=WIDGET_LABEL(base1,$
   value='當前視窗事件:')
  text1=WIDGET_TEXT(base1, $
   xSize =10)
  button = WIDGET_BUTTON(base1,$
   value ='按鈕', $
   uName ='button')
  mydraw=WIDGET_DRAW(tlb,$
   retain=1,$
   ;設定大小
   xsize=400,$
   ysize=400,$
   ;滾輪時產生事件
   /wheel_events,$
   ;按鈕時產生事件
   /button_events,$
   ;暴露(從遮擋到最前顯示時)時產生事件
   /expose_events,$
   ;滑鼠移動時產生事件
   /motion_events,$
   ;鍵盤敲擊時事件
   keyboard_events = 2,$
   ;設定元件的uName,及名字,以便元件的區分及呼叫。
   uname='mydraw')
  WIDGET_CONTROL, tlb, /REALIZE
  ;建立滑鼠資訊窗體
  wInfoBase = WIDGET_BASE($
   group_leader =tlb,$
   xsize = 200, $
   /floating,$
   title = '資訊介面',$
   ySize = 25 )
  wShowXY = WIDGET_LABEL(wInfoBase,$
   xsize = 190,$
   value=' 滑鼠位置:')
  ; 初始化它們
  WIDGET_CONTROL, wInfoBase, /REALIZE
  ;獲取元件的大小資訊
  sz = WIDGET_INFO(tlb,/geom)
  PRINT,sz.XSIZE
  PRINT,sz.YSIZE
  drawSZ = WIDGET_INFO(myDraw,/geom)
  ;顯示區域與主介面的邊界間隔
  drawSpace = [sz.XSIZE,sz.YSIZE] - [drawSZ.XSIZE,drawSZ.YSIZE]
  ;是否顯示偽彩色 
  DEVICE, decomposed =0
  ;載入系統顏色表
  LOADCT,23
  ;顯示一個400*400的方形影像
  TVSCL,DIST(400)
  ;建立結構體,包含各個元件ID
  state={label1:label1,$
   text1:text1,$
   drawSpace: drawSpace, $
   testStr  : '程式初始字串,',$
   wShowXY: wShowXY,$
   mydraw:mydraw}
  ;建立指標
  pstate=PTR_NEW(state,/no_copy)
  ;將指標資訊存到tlb的uvalue中儲存
  WIDGET_CONTROL,tlb,set_uvalue=pstate
  ;關聯產生事件
  XMANAGER, 'test_events', tlb,/NO_BLOCK
;也可用這個方式:直接指定事件程式,event_handler ='abc'
END

相關文章