Changeset 2168 for trunk/python
- Timestamp:
- 05/17/11 14:37:34 (14 years ago)
- Location:
- trunk/python
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/python/asapplotter.py
r2155 r2168 90 90 def _newcasabar(self): 91 91 backend=matplotlib.get_backend() 92 if self._visible and backend == "TkAgg": 92 if not self._visible: 93 return None 94 elif backend == "TkAgg": 93 95 from asap.customgui_tkagg import CustomToolbarTkAgg 94 96 return CustomToolbarTkAgg(self) 95 97 #from asap.casatoolbar import CustomFlagToolbarTkAgg 96 98 #return CustomFlagToolbarTkAgg(self) 99 elif backend == "Qt4Agg": 100 from asap.customgui_qt4agg import CustomToolbarQT4Agg 101 return CustomToolbarQT4Agg(self) 97 102 return None 98 103 -
trunk/python/customgui_qt4agg.py
r2155 r2168 9 9 import PyQt4 as qt 10 10 11 ###################################### 12 ## Add CASA custom toolbar ## 13 ###################################### 11 14 class CustomToolbarQT4Agg(CustomToolbarCommon, qt.QtGui.QToolBar): 12 15 def __init__(self,parent): … … 23 26 self.pagecount = None 24 27 CustomToolbarCommon.__init__(self,parent) 25 #self.notewin = NotationWindowQT4Agg(master=self.canvas)28 self.notewin = NotationWindowQT4Agg(master=self.canvas) 26 29 self._add_custom_toolbar() 27 30 … … 31 34 self.bNote = self._NewButton(master=self, 32 35 text='notation', 33 command=self.modify_note) 36 command=self.modify_note, 37 balloon="Add note") 34 38 self.bNote.setCheckable(True) 35 39 36 40 self.bStat = self._NewButton(master=self, 37 41 text='statistics', 38 command=self.stat_cal) 42 command=self.stat_cal, 43 balloon="Calculate statistics") 39 44 self.bStat.setCheckable(True) 40 45 … … 54 59 self.bNext = self._NewButton(master=frPage, 55 60 text=' + ', 56 command=self.next_page,addparent=False) 61 command=self.next_page, 62 addit=False) 57 63 loPage.addWidget(self.bNext) 58 64 self.bPrev = self._NewButton(master=frPage, 59 65 text=' - ', 60 command=self.prev_page,add parent=False)66 command=self.prev_page,addit=False) 61 67 loPage.addWidget(self.bPrev) 62 68 frPage.setLayout(loPage) … … 65 71 self.bQuit = self._NewButton(master=self, 66 72 text='Quit', 67 command=self.quit) 68 69 # if os.uname()[0] != 'Darwin': 70 # self.bPrev.config(padx=5) 71 # self.bNext.config(padx=5) 73 command=self.quit, 74 balloon="Close window") 72 75 73 76 self.pagecount.setText(' '*4) … … 76 79 return 77 80 78 def _NewButton(self, master, text, command, addparent=True):81 def _NewButton(self, master, text, command, balloon=None,addit=True): 79 82 b = qt.QtGui.QPushButton(text,parent=master) 80 if addparent: master.addWidget(b) 83 if balloon: b.setToolTip(balloon) 84 if addit: master.addWidget(b) 81 85 master.connect(b,qt.QtCore.SIGNAL('clicked()'),command) 82 # if os.uname()[0] == 'Darwin':83 # b = Tk.Button(master=master, text=text, command=command)84 # else:85 # b = Tk.Button(master=master, text=text, padx=2, pady=2,86 # command=command)87 86 return b 88 87 … … 95 94 if self.mode == 'spec': return 96 95 self.mode = 'spec' 97 #self.notewin.close_widgets()96 self.notewin.close_widgets() 98 97 self.__disconnect_event() 99 98 self._p.register('button_press',self._select_spectrum) … … 107 106 # go back to spec mode 108 107 self.bStat.setChecked(False) 108 self.bStat.setToolTip("Calculate statistics") 109 109 self.spec_show() 110 110 return 111 111 self.figmgr.toolbar.set_message('statistics: select a region') 112 112 self.bStat.setChecked(True) 113 self.bStat.setToolTip("Back to spec value mode") 113 114 self.bNote.setChecked(False) 114 115 self.mode = 'stat' 115 #self.notewin.close_widgets()116 self.notewin.close_widgets() 116 117 self.__disconnect_event() 117 118 self._p.register('button_press',self._single_mask) … … 125 126 if self.mode == 'note': 126 127 self.bNote.setChecked(False) 128 self.bNote.setToolTip("Add note") 127 129 self.mode = 'none' 128 130 self.spec_show() … … 130 132 self.bStat.setChecked(False) 131 133 self.bNote.setChecked(True) 134 self.bNote.setToolTip("Back to spec value mode") 132 135 self.mode = 'note' 133 136 self.__disconnect_event() … … 185 188 186 189 190 191 192 ###################################### 193 ## Notation box window ## 194 ###################################### 195 class NotationWindowQT4Agg(NotationWindowCommon): 196 """ 197 Backend based class to create widgets to add, modify, or delete 198 note on the plot. 199 200 Note: 201 Press LEFT-mouse button on the plot to ADD a note on the canvas. 202 A notation window will be loaded for specifying note string and 203 anchor. The note will be anchored on a position in whether figure- 204 (0-1 relative in a figure), panel- (0-1 relative in a plot axes), 205 or data-coordinate (data value in a plot axes). 206 Press RIGHT-mouse button on a note to MODIFY/DELETE it. A cascade 207 menu will be displayed and you can select an operation. 208 """ 209 def __init__(self,master=None): 210 self.parent = master 211 NotationWindowCommon.__init__(self,master=master) 212 self.anchval = None 213 self.textwin = self._create_textwindow(master=None) 214 self.menu = self._create_modmenu(master=self.parent) 215 216 ### Notation window widget 217 def _create_textwindow(self,master=None): 218 """Create notation window widget and iconfy it""" 219 #twin = qt.QtGui.QWidget(parent=master, flags=qt.QtCore.Qt.Popup) 220 twin = qt.QtGui.QWidget(parent=master, flags=qt.QtCore.Qt.Dialog) 221 twin.setWindowTitle("Notation") 222 self.textbox = self._NotationBox(parent=twin) 223 radiobox = self._AnchorRadio(parent=twin) 224 self.actionbs = self._ActionButtons(parent=twin) 225 vbox = qt.QtGui.QVBoxLayout(twin) 226 vbox.addWidget(self.textbox) 227 vbox.addWidget(radiobox) 228 vbox.addLayout(self.actionbs) 229 twin.setLayout(vbox) 230 #twin.setCentralWidget(self.textbox) 231 twin.hide() 232 return twin 233 234 def _NotationBox(self,parent=None): 235 textbox = qt.QtGui.QPlainTextEdit(parent=parent) 236 textbox.setStyleSheet("background-color: white") 237 fmetric = qt.QtGui.QFontMetrics(textbox.currentCharFormat().font()) 238 textbox.resize(fmetric.width("A")*20+fmetric.leading()*2, 239 fmetric.height()*2+fmetric.ascent()+fmetric.descent()) 240 del fmetric 241 textbox.setMinimumSize(textbox.size()) 242 textbox.setUndoRedoEnabled(True) 243 textbox.setMidLineWidth(3) 244 textbox.setFrameShadow(qt.QtGui.QFrame.Sunken) 245 textbox.setCursor(qt.QtCore.Qt.IBeamCursor) 246 textbox.setFocus() 247 return textbox 248 249 def _AnchorRadio(self,parent=None): 250 # Returns a QGoupBox object which includes radio butons to 251 # select an anchor 252 anchbox = qt.QtGui.QGroupBox("anchor",parent=parent) 253 self.radio = qt.QtGui.QButtonGroup(parent=anchbox) 254 self.rFig = self._NewRadioButton(anchbox,"figure",\ 255 bgr=self.radio,value=0,\ 256 balloon="a fixed position in figure") 257 self.rAxis = self._NewRadioButton(anchbox,"panel",\ 258 bgr=self.radio,value=1,\ 259 balloon="a fixed realtive position in subplot") 260 self.rData = self._NewRadioButton(anchbox,"data",\ 261 bgr=self.radio,value=2,\ 262 balloon="a fixed data position in subplot") 263 hbox = qt.QtGui.QHBoxLayout(anchbox) 264 hbox.addWidget(self.rFig) 265 hbox.addWidget(self.rAxis) 266 hbox.addWidget(self.rData) 267 anchbox.setLayout(hbox) 268 # set initial selection "figure" 269 self.rFig.setChecked(True) 270 self.radio.setExclusive(True) 271 self.anchval = self.radio.checkedId() 272 return anchbox 273 274 def _NewRadioButton(self,parent,text,balloon=None,bgr=None,value=None): 275 rb= qt.QtGui.QRadioButton(text,parent=parent) 276 if bgr: 277 if value is not None: 278 bgr.addButton(rb,value) 279 else: 280 bgr.addButton(rb) 281 if balloon: rb.setToolTip(balloon) 282 return rb 283 284 def _enable_radio(self): 285 """Enable 'panel' and 'data' radio button""" 286 self.rAxis.setEnabled(True) 287 self.rData.setEnabled(True) 288 # select Figure as the default value 289 self.rFig.setChecked(True) 290 self.anchval = self.radio.checkedId() 291 292 def _reset_radio(self): 293 """Disable 'panel' and 'data' radio button""" 294 self.rAxis.setDisabled(True) 295 self.rData.setDisabled(True) 296 self.rFig.setEnabled(True) 297 # select Figure as the default value 298 self.rFig.setChecked(True) 299 self.anchval = self.radio.checkedId() 300 301 def _select_radio(self,selection): 302 """Select a specified radio button""" 303 if not selection in self.anchors: 304 return 305 if selection == "data": 306 self.rData.setChecked(True) 307 elif selection == "axes": 308 self.rAxis.setChecked(True) 309 else: 310 self.rFig.setChecked(True) 311 self.anchval = self.radio.checkedId() 312 313 def _get_anchval(self): 314 """Returns a integer of a selected radio button""" 315 self.anchval = self.radio.checkedId() 316 return self.anchval 317 318 def _get_note(self): 319 """Returns a note string specified in the text box""" 320 return str(self.textbox.toPlainText()) 321 322 def _clear_textbox(self): 323 """Clear the text box""" 324 self.textbox.clear() 325 326 def _set_note(self,note=None): 327 """Set a note string to the text box""" 328 self._clear_textbox() 329 if len(note) >0: 330 self.textbox.setPlainText(note) 331 332 def _ActionButtons(self,parent=None): 333 # Returns a layout object which includes "cancel" and "print" buttons 334 actbuts = qt.QtGui.QHBoxLayout() 335 bCancel = self._NewButton(parent,"cancel",self._cancel_text,\ 336 addit=False,\ 337 balloon="cancel printing/modifying") 338 bPrint = self._NewButton(parent,"print", self._print_text,\ 339 addit=False,\ 340 balloon="print text on plot") 341 actbuts.addWidget(bCancel) 342 actbuts.addWidget(bPrint) 343 return actbuts 344 345 def _NewButton(self, parent, text, command, balloon=None, addit=True): 346 b = qt.QtGui.QPushButton(text,parent=parent) 347 if balloon: b.setToolTip(balloon) 348 if addit: parent.addWidget(b) 349 parent.connect(b,qt.QtCore.SIGNAL('clicked()'),command) 350 return b 351 352 def _cancel_text(self): 353 """ 354 Cancel adding/modifying a note and close notaion window. 355 called when 'cancel' is selected. 356 """ 357 self.close_textwindow() 358 359 def _print_text(self): 360 """ 361 Add/Modify a note. Called when 'print' is selected on the 362 notation window. 363 """ 364 self.print_text() 365 self.close_textwindow() 366 367 def load_textwindow(self,event): 368 """ 369 Load text window at a event position to add a note on a plot. 370 Parameter: 371 event: an even object to specify the position to load 372 text window. 373 """ 374 self.close_modmenu() 375 if event.canvas != self.parent: 376 raise RuntimeError, "Got invalid event!" 377 378 self.event = event 379 is_ax = (event.inaxes != None) 380 (xpix, ypix) = self._disppix2screen(event.x, event.y) 381 offset = 5 382 self.show_textwindow(xpix+offset,ypix+offset,enableaxes=is_ax) 383 384 def show_textwindow(self,xpix,ypix,basetext=None,enableaxes=False): 385 """ 386 Load text window at a position of screen to add a note on a plot. 387 Parameters: 388 xpix, ypix: a pixel position from Upper-left corner 389 of the screen. 390 basetext: None (default) or any string. 391 A string to be printed on text box when loaded. 392 enableaxes: False (default) or True. 393 If True, 'panel' & 'data' radio button is enabled. 394 """ 395 if not self.textwin: return 396 self._reset_radio() 397 if enableaxes: 398 self._enable_radio() 399 self.textwin.activateWindow() 400 h = self.textwin.minimumHeight() 401 w = self.textwin.minimumWidth() 402 self.textwin.resize(w,h) 403 self.textwin.move(xpix,ypix) 404 self.textbox.setFocus() 405 self.textwin.raise_() 406 self.textwin.show() 407 if w*h <= 1: # Initial load 408 self.textwin.setMinimumSize(self.textwin.size()) 409 410 def close_textwindow(self): 411 """Close text window.""" 412 self.seltext = {} 413 self._reset_radio() 414 self._clear_textbox() 415 self.textwin.hide() 416 417 418 ### Modify/Delete menu widget 419 def _create_modmenu(self,master=None): 420 """Create modify/delete menu widget""" 421 if master: 422 self.parent = master 423 if not self.parent: 424 return False 425 menu = qt.QtGui.QMenu(parent=self.parent) 426 menu.setTearOffEnabled(False) 427 menu.addAction("Modify",self._modify_note) 428 menu.addAction("Delete",self._delnote_dialog) 429 return menu 430 431 def load_modmenu(self,event): 432 """ 433 Load cascade menu at a event position to modify or delete 434 selected text. 435 Parameter: 436 event: an even object to specify the position to load 437 text window. 438 """ 439 self.close_textwindow() 440 self.seltext = self._get_selected_text(event) 441 if len(self.seltext) == 3: 442 canvas = event.canvas 443 corig = canvas.mapToGlobal(qt.QtCore.QPoint(0,0)) 444 xpixs = corig.x() + int(event.x) 445 ypixs = corig.y() + canvas.height() - int(event.y) 446 self.menu.activateWindow() 447 self.menu.move(xpixs,ypixs) 448 self.menu.show() 449 450 def close_modmenu(self): 451 """Close cascade menu.""" 452 self.seltext = {} 453 self.menu.hide() 454 455 ### load text window for modification 456 def _modify_note(self): 457 """helper function to load text window to modify selected note""" 458 textobj = self.seltext['textobj'] 459 (xtx, ytx) = textobj._get_xy_display() 460 is_ax = (self.seltext['anchor'] != 'figure') 461 if not is_ax: 462 # previous anchor is figure 463 pos = textobj.get_position() 464 is_ax = (self._get_axes_from_pos(pos,self.canvas) != None) 465 466 (xpix, ypix) = self._disppix2screen(xtx,ytx) 467 offset = int(textobj.get_size())*2 468 self.show_textwindow(xpix,ypix+offset,basetext=textobj.get_text(),\ 469 enableaxes=is_ax) 470 self._select_radio(self.seltext['anchor']) 471 self._set_note(textobj.get_text()) 472 473 ### close all widgets 474 def close_widgets(self): 475 """Close note window and menu""" 476 self.close_textwindow() 477 self.close_modmenu() 478 479 ### dialog to confirm deleting note 480 def _delnote_dialog(self): 481 """Load dialog to confirm deletion of the text""" 482 remind = "Delete text?\n '"+self.seltext['textobj'].get_text()+"'" 483 from PyQt4.QtGui import QMessageBox as mbox 484 answer = mbox.question(self.parent,"Delete?",remind, 485 buttons = mbox.Ok | mbox.Cancel, 486 defaultButton=mbox.Cancel) 487 if answer == mbox.Ok: 488 self.delete_note() 489 else: 490 self.cancel_delete() 491 492 ### helper functions 493 def _disppix2screen(self,xpixd,ypixd): 494 """ 495 helper function to calculate a pixel position form Upper-left 496 corner of the SCREEN from a pixel position (xpixd, ypixd) 497 from Lower-left of the CANVAS (which, e.g., event.x/y returns) 498 499 Returns: 500 (x, y): pixel position from Upper-left corner of the SCREEN. 501 """ 502 corig = self.parent.mapToGlobal(qt.QtCore.QPoint(0,0)) 503 xpixs = corig.x() + xpixd 504 ypixs = corig.y() + self.parent.height() - ypixd 505 return (int(xpixs), int(ypixs)) 506 507 508 509 510 511 512 ########################################### 513 ## Add CASA custom Flag toolbar ## 514 ###########################################
Note:
See TracChangeset
for help on using the changeset viewer.