Module gpanel
[hide private]
[frames] | no frames]

Source Code for Module gpanel

   1  # gpanel.py 
   2  # Version 1.06; Feb 22, 2017 
   3   
   4  ''' 
   5  Module to create a graphics window of default size 501x501 pixels (client drawing area) 
   6  using a coordinate system with x-axis from left to right, y-axis from bottom to top 
   7  (called user coordinates, default range 0..1, 0..1). 
   8   
   9  The module provides a global namespace for GPanel class methods. It also contaisn 
  10  the class GPane that can be used to embed a GPanel graphics window together with 
  11  other widgets in a GUI application. 
  12   
  13  The drawing methods perform drawing operation in an offscreen buffer (QPixmap) 
  14  and automatically renders it on the screen, so the graphics is shown step-by-step. 
  15   
  16  User coordinates:  (ux, uy) 
  17  Pixel coordinates: (px, py) (screen pixels) 
  18  Transformation: px = px(ux), py = py(uy) 
  19  Pixel coordinate range: 0..winWidth - 1 (inclusive), 0..winHeight - 1 (inclusive); (0,0) upper left corner, x to the right, y downwards 
  20  User coordinate range: xmin..xmax (inclusive), ymin..ymax (inclusive); (0,0) lower left corner, x to the right, y upwards. 
  21   
  22  Transformation: user(ux, uy) to pixel(px, py): 
  23  (width = winWidth - 1, height = winHeight - 1) 
  24  px = a * ux + b 
  25  py = c * uy + d 
  26  with a = width / (xmax - xmin) 
  27  b = width * xmin / (xmin - xmax) 
  28  c = height / (ymin - ymax) 
  29  d = height * ymax / (ymax - ymin) 
  30   
  31  Inverse: 
  32  ux = (px - b) / a 
  33  uy = (py - d) / c 
  34   
  35  Because of the transformation from float to pixel coordinates, some rounding errors 
  36  may happen. If you need pixel accuracy, define a GPanel window with some user defined width x height, 
  37  e.g. makeGPanal(Size(501, 401)). Define then user coordinates in the range 0..width-1, 0..height-1, e.g. 
  38  window(0, 500, 0, 400). Now pixels in the range 0..500 x 0..400 (inclusive) may be addressed with no 
  39  rounding errors. (This is a total of 501 x 401 pixels.) 
  40   
  41  If you prefer a coordinate system with the origin at the upper left corner, define the y-range in reverse 
  42  order, e.g. window(0, 500, 400, 0). 
  43   
  44  WARNING: Because PyQt is not thread-safe, in principle all graphics drawings should be 
  45  executed in the GUI thread (for GPanel the main thread or a GUI callback). 
  46   
  47  In order to get notifications for keyboard and mouse callbacks, the main thread should 
  48  not be blocked otherwise than within the keep() function. 
  49   
  50  Typical program: 
  51   
  52  from pygpanel import * 
  53   
  54  makeGPanel(0, 10, 0, 10) 
  55  for ypt in range(0, 11, 1): 
  56      line(0, ypt, 10 - ypt, 0) 
  57      time.sleep(0.1) # to see what happens 
  58  keep() 
  59   
  60  keep() is blocking and keeps the graphics window open until the close button is hit or the 
  61  Python process terminates. 
  62  ''' 
  63   
  64  from __future__ import division 
  65  from PyQt4 import QtGui, QtCore 
  66  from PyQt4.QtGui import * 
  67  from PyQt4.QtCore import * 
  68  import thread 
  69  import sys, time, math 
  70  import random 
  71   
  72  _p = None 
  73  isTigerJython = False 
74 75 -class _WindowNotInitialized(Exception): pass
76
77 -def _isGPanelValid():
78 if _p == None: 79 raise _WindowNotInitialized("Use \"makeGPanel()\" to create the graphics window before calling GPanel methods.")
80
81 -def makeGPanel(*args, **kwargs):
82 ''' 83 Constructs a GPanel and displays a non-resizable graphics window. 84 Defaults with no parameter: 85 Window size: 501x501 pixels 86 Window title: "GPanel". 87 User coordinates: 0, 1, 0, 1. 88 Background color: white. 89 Pen color: black. 90 Pen size: 1. 91 92 1 Parameter: Size(window_width, window_height). 93 4 Parameters: xmin, xmax, ymin, ymax. 94 95 KEEP IN MIND: To use GUI callbacks, the main program must block in the keep() function. 96 @param Size: a Size reference to define the dimension of the graphics windows. 97 @param xmin: left x user coordinate 98 @param xmax: right x user coordinate 99 @param ymin: lower y user coordinate 100 @param ymax: upper y user coordinate 101 @param kwargs: mousePressed, mouseReleased, mouseDragged, keyPressed, keyReleased, closed 102 ''' 103 global _p 104 105 if _p == None: 106 _p = GPanel(*args) 107 108 for key in kwargs: 109 if key == "mousePressed": 110 _p.addMousePressListener(kwargs[key]) 111 elif key == "mouseReleased": 112 _p.addMouseReleaseListener(kwargs[key]) 113 elif key == "mouseDragged": 114 _p.addMouseDragListener(kwargs[key]) 115 elif key == "keyPressed": 116 _p.addKeyPressListener(kwargs[key]) 117 elif key == "keyReleased": 118 _p.addKeyReleaseListener(kwargs[key]) 119 elif key == "closed": 120 _p.addCloseListener(kwargs[key]) 121 return _p
122
123 -def addCloseListener(closeListener):
124 ''' 125 Registers the given function that is called when the title bar 126 close button is hit. 127 128 If a listener (!= None) is registered, the automatic closing is disabled. 129 To close the window, call sys.exit(). 130 131 KEEP IN MIND: To use GUI callbacks, the main program must block in the keep() function. 132 @param closeListener: a callback function called when the close button is hit 133 ''' 134 _isGPanelValid() 135 _p.addCloseListener(closeListener)
136
137 -def addKeyPressListener(onKeyPressed):
138 ''' 139 Registers a callback that is invoked when a key is pressed (and the graphics window has the focus). 140 141 KEEP IN MIND: To use GUI callbacks, the main program must block in the keep() function. 142 @param onKeyPressed: a callback function called when a key is pressed 143 ''' 144 _isGPanelValid() 145 _p.addKeyPressListener(onKeyPressed)
146
147 -def addKeyReleaseListener(onKeyReleased):
148 ''' 149 Registers a callback that is invoked when a key is released (and the graphics window has the focus). 150 151 KEEP IN MIND: To use GUI callbacks, the main program must block in the keep() function. 152 @param onKeyReleased: a callback function called when a key is pressed 153 ''' 154 _isGPanelValid() 155 _p.addKeyReleaseListener(onKeyReleased)
156
157 -def addMouseDragListener(onMouseDragged):
158 ''' 159 Registers a callback that is invoked when the mouse is moved while a mouse button is pressed (drag). 160 161 KEEP IN MIND: To use GUI callbacks, the main program must block in the keep() function. 162 @param onMouseDragged: a callback function called when the moused is dragged 163 ''' 164 _isGPanelValid() 165 _p.addMouseMoveListener(onMouseDragged)
166
167 -def addMousePressListener(onMousePressed):
168 ''' 169 Registers a callback that is invoked when a mouse button is pressed. 170 Use isLeftMouseButton() or isRightMouseButton() to check which button used. 171 172 KEEP IN MIND: To use GUI callbacks, the main program must block in the keep() function. 173 @param onMousePressed: a callback function called when a mouse button is pressed 174 ''' 175 _isGPanelValid() 176 _p.addMousePressListener(onMousePressed)
177
178 -def addMouseReleaseListener(onMouseReleased):
179 ''' 180 Registers a callback that is invoked when a mouse button is releases. 181 Use isLeftMouseButton() or isRightMouseButton() to check which button used. 182 183 KEEP IN MIND: To use GUI callbacks, the main program must block in the keep() function. 184 @param onMouseReleased: a callback function called when a mouse button is released 185 ''' 186 _isGPanelValid() 187 _p.addMouseReleaseListener(onMouseReleased)
188
189 -def arc(radius, startAngle, spanAngle):
190 ''' 191 Draws a circle sector with center at the current graph cursor position, 192 given radius and given start and span angles. 193 @param radius: the radius of the arc 194 @param startAngle: starting angle in degrees, zero to east, positive counter-clockwise 195 @param spanAngle: span angle (sector angle) in degrees, positive counter-clockwise 196 ''' 197 _isGPanelValid() 198 _p.arc(radius, startAngle, spanAngle)
199
200 201 -def arrow(*args):
202 ''' 203 Draws an arrow from point pt1 = [x1, y1] to pt2 = [x2, y2] 204 @param pt1 the starting point 205 @param pt2: the ending point (where is the arrowhead) 206 @param size: the length of the arrowhead's triangle (in pixels, default: 10) 207 208 Overloaded versions: points as list/tuple or x, y coordinates 209 ''' 210 _isGPanelValid() 211 _p.arrow(*args)
212
213 -def bgColor(*args):
214 ''' 215 Same as setBgColor(). 216 ''' 217 setBgColor(*args)
218
219 -def chord(radius, startAngle, spanAngle):
220 ''' 221 Draws a circle chord with center at the current graph cursor position, 222 given radius and given start and span angles (in degrees, positive 223 counter-clockwise, zero to east). 224 @param radius: the radius of the arc 225 @param startAngle: starting angle in degrees, zero to east, positive counter-clockwise 226 @param spanAngle: span angle (sector angle) in degrees, positive counter-clockwise 227 ''' 228 _isGPanelValid() 229 _p.chord(radius, startAngle, spanAngle)
230
231 -def circle(radius):
232 ''' 233 Draws a circle with center at the current graph cursor position 234 with given radius in horizontal window coordinates. 235 @param radius: the radius of the circle 236 ''' 237 _isGPanelValid() 238 _p.circle(radius)
239
240 -def clear():
241 ''' 242 Clears the graphics window and the offscreen buffer used by the window 243 (fully paint with background color). 244 Sets the current graph cursor position to (0, 0). 245 If enableRepaint(false) only clears the offscreen buffer. 246 ''' 247 _isGPanelValid() 248 _p.clear()
249
250 -def delay(delayTime):
251 ''' 252 Stop execution for given delay time. 253 @param delayTime: the delay time (in ms) 254 ''' 255 time.sleep(delayTime / 1000.0)
256
257 -def doubleArrow(*args):
258 ''' 259 Draws a double arrow from point pt1 = [x1, y1] to pt2 = [x2, y2] 260 (arrowheads on both ends). 261 @param pt1 one end of the arrow 262 @param pt2: the other end of the arrow 263 @param size: the length of the arrowhead's triangle (in pixels, default: 10) 264 265 Overloaded versions: points as list/tuple or x, y coordinates 266 ''' 267 _isGPanelValid() 268 _p.doubleArrow(*args)
269
270 -def draw(*args):
271 ''' 272 Draws a line form current graph cursor position to (x, y). 273 Sets the graph cursor position to (x, y). 274 Also with one parameter of type complex, list or tuple. 275 @param x: the x coordinate of the target point 276 @param y: the y coordinate of the target point 277 @param target: (alternative) the target point as complex, list or tuple 278 ''' 279 x, y = _getCoords(*args) 280 _isGPanelValid() 281 _p.draw(x, y)
282
283 -def drawGrid(*args):
284 ''' 285 Draws a coordinate system with annotated axes. 286 (You must increase the user coordinate system at least 10% in both directions.) 287 288 Overloaded versions: 289 290 drawGrid(x, y): Grid with 10 ticks in range 0..x, 0..y. Label text depends if x, y or int or float 291 292 drawGrid(x, y, color): same with given grid color 293 294 drawGrid(x1, x2, y1, y2): same with given span x1..x2, y1..y2 295 296 drawGrid(x1, x2, y1, y2, color): same with given grid color 297 298 drawGrid(x1, x2, y1, y2, x3, y3): same with given number of ticks x3, y3 in x- and y-direction 299 ''' 300 _isGPanelValid() 301 _p.drawGrid(*args)
302
303 -def ellipse(a, b):
304 ''' 305 Draws an ellipse with center at the current graph cursor position 306 with given axes. 307 @param a: the major ellipse axis 308 @param b: the minor ellipse axis 309 ''' 310 _isGPanelValid() 311 _p.ellipse(a, b)
312
313 -def enableRepaint(enable):
314 ''' 315 Enables/Disables automatic repaint in graphics drawing methods. 316 @param enable: if True, the automatic repaint is enabled; otherwise disabled 317 ''' 318 _isGPanelValid() 319 _p.enableRepaint(enable)
320
321 -def erase():
322 ''' 323 Same as clear(), but lets the current graph cursor unganged. 324 ''' 325 _isGPanelValid() 326 _p.erase()
327
328 -def fill(x, y, *args):
329 ''' 330 Fills the closed unicolored region with the inner point (x, y) with 331 the replacement color (RGB, RGBA or X11 color string). 332 The old color is not given, the color of the current (x, y) pixel is taken. 333 @param x: the x coordinate of the inner point 334 @param y: the y coordinate of the inner point 335 @param color: the old color (RGB list/tuple or X11 color string) (may be omitted) 336 @param replacementColor: the new color (RGB list/tuple or X11 color string) 337 ''' 338 _isGPanelValid() 339 _p.fill(x, y, *args)
340
341 -def fillArc(radius, startAngle, spanAngle):
342 ''' 343 Draws a filled circle sector with center at the current graph cursor position, 344 given radius and given start and span angles (in degrees, positive 345 counter-clockwise, zero to east). (fill color = pen color) 346 @param radius: the radius of the arc 347 @param startAngle: starting angle in degrees, zero to east, positive counter-clockwise 348 @param spanAngle: span angle (sector angle) in degrees, positive counter-clockwise 349 ''' 350 _isGPanelValid() 351 _p.fillArc(radius, startAngle, spanAngle)
352
353 -def fillChord(radius, startAngle, spanAngle):
354 ''' 355 Draws a filled circle chord with center at the current graph cursor position, 356 given radius and given start and span angles (in degrees, positive 357 counter-clockwise, zero to east). (fill color = pen color) 358 @param radius: the radius of the arc 359 @param startAngle: starting angle in degrees, zero to east, positive counter-clockwise 360 @param spanAngle: span angle (sector angle) in degrees, positive counter-clockwise 361 ''' 362 _isGPanelValid() 363 _p.fillChord(radius, startAngle, spanAngle)
364
365 -def fillCircle(radius):
366 ''' 367 Draws a filled circle with center at the current graph cursor position 368 with given radius in horizontal window coordinates (fill color = pen color). 369 @param radius: the radius of the circle 370 ''' 371 _isGPanelValid() 372 _p.fillCircle(radius)
373
374 -def fillEllipse(a, b):
375 ''' 376 Draws a filled ellipse with center at the current graph cursor position 377 with given axes (fill color = pen color). 378 @param a: the major ellipse axis 379 @param b: the minor ellipse axis 380 ''' 381 _isGPanelValid() 382 _p.fillEllipse(a, b)
383
384 -def fillPath(color):
385 ''' 386 Closes the path started with startPath() and shows a filled polygon from the saved 387 draw() positions with given color. 388 ''' 389 _isGPanelValid() 390 _p.fillPath(color)
391
392 -def fillPolygon(*args):
393 ''' 394 Draws a filled polygon with given list of vertexes (list of [x, y]) 395 (fill color = pen color). 396 1 parameter: a list/tuple of the corners [x, y] 397 2 parameters: two lists/tuples x, y of corresponding x-y pairs 398 ''' 399 _isGPanelValid() 400 _p.fillPolygon(*args)
401
402 -def fillRectangle(*args):
403 ''' 404 Draws a filled rectangle (fill color = pen color). 405 2 parameters: Center at the current graph cursor position 406 and given width and height 407 4 parameters: Given diagonal 408 ''' 409 _isGPanelValid() 410 _p.fillRectangle(*args)
411
412 -def fillTriangle(*args):
413 ''' 414 Draws a filled triangle with given corners. 415 6 parameters: x1, y1, x2, y2, x3, y3 coordinates of corners 416 3 parameters: [x1, y1], [x2, y2], [x3, y3] lists of corners 417 ''' 418 _isGPanelValid() 419 _p.fillTriangle(*args)
420
421 -def getDividingPoint(*args):
422 ''' 423 Returns the tuple of user coordinates of the point on the line through the point pt1 = (x1, y1) 424 and the point pt2 = (x2, y2) that is in distance ratio times the length from pt1 to pt2 from 425 pt1. For ratio < 0 the point is in the opposite direction. 426 3 parameteters: pt1, pt2 (complex/list/tuple), ratio 427 5 parameteters: x1, y1, x2, y2, ratio 428 ''' 429 if len(args) == 5: 430 x1 = args[0] 431 y1 = args[1] 432 x2 = args[2] 433 y2 = args[3] 434 ratio = args[4] 435 elif len(args) == 3: 436 x1, y1, x2, y2 = _get2Coords(args[0], args[1]) 437 ratio = args[2] 438 else: 439 raise ValueError("Illegal number of parameters.") 440 _isGPanelValid() 441 return _p.getDividingPoint(x1, y1, x2, y2, ratio)
442
443 -def getBitmap():
444 ''' 445 Returns the QImage of the complete graphics area. 446 (For compatiblity with TigerJython.) 447 ''' 448 _isGPanelValid() 449 return _p.getFullImage()
450
451 -def getFullImage():
452 ''' 453 Returns the QImage of the complete graphics area. 454 ''' 455 _isGPanelValid() 456 return _p.getFullImage()
457
458 -def getImage(filename):
459 ''' 460 Same as loadImage(filename) 461 (For compatiblity with TigerJython.) 462 ''' 463 return loadImage(filename)
464
465 -def loadImage(filename, pic_format = None):
466 ''' 467 Returns a QImage of the picture loaded from the given file. For pic_format = None, 468 the picture format is guessed from the file data. 469 @param: the file path to the picture file 470 @param pic_format: format of picture, supported: "None" (default), "GIF", "JPG", 471 "BMP", "PNG", "PBM", "PGM", "PPM", "TIFF", "XBM" "XPM". 472 ''' 473 return GPanel.loadImage(filename, pic_format)
474
475 -def getPainter():
476 ''' 477 Returns the QPainter reference used to draw into the offscreen buffer. 478 ''' 479 _isGPanelValid() 480 return _p.getPainter()
481
482 -def getPixelColor(*args):
483 ''' 484 Returns the RGBA color tuple of a pixel with given user coordinates. 485 No params: Returns color at current graph cursor position. 486 ''' 487 _isGPanelValid() 488 return _p.getPixelColor(*args)
489
490 -def getPixelColorStr(*args):
491 ''' 492 Returns the X11 color string of a pixel with given user coordinates. 493 No params: Returns color at current graph cursor position. 494 ''' 495 _isGPanelValid() 496 return _p.getPixelColorStr(*args)
497
498 -def getPos():
499 ''' 500 Returns a tuple with current graph cursor position (tuple, user coordinates). 501 ''' 502 _isGPanelValid() 503 return _p.getPos()
504
505 -def getPosX():
506 ''' 507 Returns the current graph cursor x-position (user coordinates). 508 @return: x coordinate of graph cursor 509 @rtype: float 510 ''' 511 _isGPanelValid() 512 return _p.getPosX()
513
514 -def getPosY():
515 ''' 516 Returns the current graph cursor y-position (user coordinates). 517 @return: y coordinate of graph cursor 518 @rtype: float 519 ''' 520 _isGPanelValid() 521 return _p.getPosY()
522
523 -def getScreenWidth():
524 ''' 525 Returns the width of the screen (in pixels). 526 @return: screen width 527 @rtype: int 528 ''' 529 return GPanel.getScreenWidth()
530
531 -def getScreenHeight():
532 ''' 533 Returns the height of the screen (in pixels). 534 @return: screen height 535 @rtype: int 536 ''' 537 return GPanel.getScreenHeight()
538
539 -def imageFromData(data, pic_format, x, y):
540 ''' 541 Draws the picture with given string data in JPEG format at user coordinates of lower left corner. 542 @param data: picture data stream in string format 543 @param pic_format: format of picture, supported: "GIF", "JPG", "BMP", "PNG", 544 "PBM", "PGM", "PPM", "TIFF", "XBM" "XPM" 545 @param x: x coordinate of lower left corner 546 @param y: y coordinate of lower left corner 547 @return: True, if operation is successful; otherwise false 548 @rtype: boolean 549 ''' 550 _isGPanelValid() 551 img = QImage() 552 rc = img.loadFromData(data, pic_format) 553 if rc: 554 image(img, x, y) 555 return True 556 return False
557
558 -def image(*args):
559 ''' 560 Draws the picture with given file path or given image at given upper-left coordinates. 561 1st parameter: image path (string) or QImage reference 562 2nd, 3rd parameters: llx, lly (lower left corner in user coordinates) 563 ''' 564 _isGPanelValid() 565 _p.showImage(*args)
566
567 -def isLeftMouseButton():
568 ''' 569 Returns True, if the last mouse action was performed with the left mouse button. 570 ''' 571 _isGPanelValid() 572 return _p.isLeftMouseButton()
573
574 -def isRightMouseButton():
575 ''' 576 Returns True, if the last mouse action was performed with the right mouse button. 577 ''' 578 _isGPanelValid() 579 return _p.isRightMouseButton()
580
581 -def keep():
582 ''' 583 Blocks until the title bar's close button is hit. Then cleans up 584 the graphics system. 585 ''' 586 _isGPanelValid() 587 _p.keep()
588
589 -def line(*args):
590 ''' 591 Draws a line with given user start and end coordinates 592 and sets the graph cursor position to the end point. 593 Also with 2 parameters of type complex, list or tuple. 594 4 parameters: x1, y1, x2, y2 595 2 parameters: pt1, pt2 as complex/list/tuple 596 ''' 597 x1, y1, x2, y2 = _get2Coords(*args) 598 _isGPanelValid() 599 _p.line(x1, y1, x2, y2)
600
601 -def lineWidth(width):
602 ''' 603 Sets the current pen size (width) (>=1). 604 Returns the previouis pen size. 605 606 Same as setPenSize(). For TigerJython compatiblity. 607 @param width: the pen width (>=1) 608 ''' 609 setPenSize(width)
610
611 -def makeColor(r, g, b):
612 ''' 613 Returns the tuple (r, g, b). For compatibility with TigerJython. 614 ''' 615 return (r, g, b)
616
617 -def move(*args):
618 ''' 619 Sets the current graph cursor position to given user coordinates. 620 (without drawing anything). 621 Also with 1 parameter of type complex, list or tuple. 622 623 Same as pos(). 624 @param x: the x coordinate of the target point 625 @param y: the y coordinate of the target point 626 @param target: (alternative) the target point as complex, list or tuple 627 ''' 628 pos(*args)
629
630 -def point(*args):
631 ''' 632 Draws a single point with current pen size and pen color at given user coordinates. 633 No params: draws a current graph cursor position 634 @param x: the x coordinate of the target point 635 @param y: the y coordinate of the target point 636 @param target: (alternative) the target point as complex, list or tuple 637 ''' 638 _isGPanelValid() 639 _p.point(*args)
640
641 -def linePlot(*args):
642 ''' 643 Draws a line plot with given x,y data. 644 1 parameter: a list/tuple of subsequent data points [x, y] 645 2 parameters: two lists/tuples x, y of corresponding x-y pairs 646 The graph cursor position remains unchanged. 647 ''' 648 _isGPanelValid() 649 _p.linePlot(*args)
650
651 -def pos(*args):
652 ''' 653 Sets the current graph cursor position to given user coordinates (x, y). 654 (without drawing anything). 655 Also with 1 parameter of type complex, list or tuple. 656 657 Same as move(). 658 @param x: the x coordinate of the target point 659 @param y: the y coordinate of the target point 660 @param target: (alternative) the target point as complex, list or tuple 661 ''' 662 x, y = _getCoords(*args) 663 _isGPanelValid() 664 _p.pos(x, y)
665
666 -def polygon(*args):
667 ''' 668 Draws a filled polygon with given list of vertexes (list of [x, y]) 669 (fill color = pen color). 670 1 parameter: a list/tuple of the corners [x, y] 671 2 parameters: two lists/tuples x, y of corresponding x-y pairs 672 ''' 673 _isGPanelValid() 674 _p.polygon(*args)
675
676 -def rectangle(*args):
677 ''' 678 Draws a rectangle. 679 2 parameters: Center at the current graph cursor position 680 and given width and height. 681 4 parameters: Given diagonal 682 ''' 683 _isGPanelValid() 684 _p.rectangle(*args)
685
686 -def repaint():
687 ''' 688 Renders the offscreen buffer in the graphics window. 689 ''' 690 _isGPanelValid() 691 _p.repaint()
692
693 -def recallGraphics():
694 ''' 695 Restores the saved graphics from the image buffer. Use saveGraphics() 696 to save it. 697 698 Same as restoreGraphics() (for TigerJython compatibility). 699 ''' 700 restoreGraphics()
701
702 703 -def restoreGraphics():
704 ''' 705 Restores the saved graphics from the image buffer. Use saveGraphics() 706 to save it. 707 ''' 708 _isGPanelValid() 709 _p.restoreGraphics()
710
711 -def saveGraphics():
712 ''' 713 Saves the current graphics into a image buffer. Use restoreGraphics() 714 to restore it. 715 ''' 716 _isGPanelValid() 717 _p.saveGraphics()
718
719 -def setBgColor(*args):
720 ''' 721 Sets the background color. All drawings are erased and the current 722 graph cursor is set to (0, 0). 723 1 parameter: value considered as X11 color string 724 3 parameters: values considered as RGB (alpha = 255) 725 4 parameters: values considered as RGBA 726 ''' 727 _isGPanelValid() 728 return _p.setBgColor(*args)
729
730 -def setColor(*args):
731 ''' 732 Sets the current pen color. 733 1 parameter: - string value considered as X11 color string 734 - list considered as [r, b, g] or [r, g, b, a] 735 - tuple considered as (r, b, g) or (r, g, b, a) 736 3 parameters: values considered as RGB (alpha = 255) 737 4 parameters: values considered as RGBA 738 739 Same as setPenColor(). For TigerJython compatiblity. 740 ''' 741 return setPenColor(*args)
742
743 -def setPaintMode():
744 ''' 745 Resets the drawing mode to standard (overwriting). 746 ''' 747 _isGPanelValid() 748 _p.setPaintMode()
749
750 -def setPenColor(*args):
751 ''' 752 Sets the current pen color. 753 1 parameter: - string value considered as X11 color string 754 - list considered as [r, b, g] or [r, g, b, a] 755 - tuple considered as (r, b, g) or (r, g, b, a) 756 3 parameters: values considered as RGB (alpha = 255) 757 4 parameters: values considered as RGBA 758 ''' 759 _isGPanelValid() 760 return _p.setPenColor(*args)
761
762 -def setPenSize(size):
763 ''' 764 Sets the current pen size (width) (>=1). 765 Returns the previouis pen size. 766 Same as lineWidth(). 767 @param width: the pen width (>=1) 768 ''' 769 _isGPanelValid() 770 return _p.setPenSize(size)
771
772 -def setTitle(title):
773 ''' 774 Sets the title in the window title bar. 775 @param title: the title text 776 ''' 777 _isGPanelValid() 778 return _p.setTitle(size)
779
780 -def setUserCoords(xmin, xmax, ymin, ymax):
781 ''' 782 Sets user coordinate system left_x, right_x, bottom_y, top_y (inclusive). 783 Same as window(). 784 785 @param xmin: the x coordinate (of a visible pixel) at left border 786 @param xmax: the x coordinate (of a visible pixel) at right border 787 @param ymin: the y coordinate (of a visible pixel) at bottom border 788 @param ymax: the y coordinate (of a visible pixel) at top border 789 ''' 790 _isGPanelValid() 791 _p.setUserCoords(xmin, xmax, ymin, ymax)
792
793 -def setWindowCenter():
794 ''' 795 Sets the screen position to the center of the screen. 796 ''' 797 _isGPanelValid() 798 _p.setWindowCenter()
799
800 -def setWindowPos(ulx, uly):
801 ''' 802 Sets the screen position of the graphics window. 803 @param ulx: the upper left corner's x-coordinate 804 @param ulx: the upper left corner's y-coordinate 805 ''' 806 _isGPanelValid() 807 _p.setWindowPos(ulx, uly)
808
809 -def setXORMode(*args):
810 ''' 811 Performs pixel color XOR operation with the existing background pixel. 812 Be aware that if the background is white, drawing with a white pen shows a black pixel. 813 (Parameter not used, for TigerJython compatibility) 814 ''' 815 _isGPanelValid() 816 _p.setXORMode()
817
818 819 -def startPath():
820 ''' 821 Starts recording the path vertexes. The positions of subsequent draw() operations are saved. 822 The path is used to show a filled polygon when fillPath() is called. 823 ''' 824 _isGPanelValid() 825 _p.startPath()
826
827 -def storeGraphics():
828 ''' 829 Saves the current graphics into a image buffer. Use restoreGraphics() 830 to restore it. 831 832 Same as saveGraphics() (for TigerJython compatibility). 833 ''' 834 saveGraphics()
835
836 -def text(*args):
837 ''' 838 Draws a text at given position (user coordinates). 839 1 parameter: at current graph cursor position 840 2 parameters: target point (comolex/list/tuple), text 841 3 parameters: x, y, text 842 ''' 843 _isGPanelValid() 844 _p.text(*args)
845
846 -def title(title):
847 ''' 848 Sets the title in the window title bar. 849 Same as setTitle(), for TigerJython compatibility. 850 @param title: the title text 851 ''' 852 _isGPanelValid() 853 _p.setTitle(title)
854
855 -def toPixel(user):
856 ''' 857 Returns pixel coordinates (tuple) of given user coordinates (tuple). 858 ''' 859 _isGPanelValid() 860 return _p.toPixel(user)
861
862 -def toPixelHeight(userHeight):
863 ''' 864 Returns pixel y-increment of given user y-increment (always positive). 865 ''' 866 _isGPanelValid() 867 return p.toPixelHeight(userHeight)
868
869 -def toPixelWidth(userWidth):
870 ''' 871 Returns pixel x-increment of given user x-increment (always positive). 872 ''' 873 _isGPanelValid() 874 return _p.toPixelWidth(userWidth)
875
876 -def toPixelX(userX):
877 ''' 878 Returns pixel x-coordinate of given user x-coordinate. 879 ''' 880 _isGPanelValid() 881 return _p.toPixelX(userX)
882
883 -def toPixelY(userY):
884 ''' 885 Returns pixel y-coordinate of given user y-coordinate. 886 ''' 887 _isGPanelValid() 888 return _p.toPixelY(userY)
889
890 -def toUser(pixel):
891 ''' 892 Returns user coordinates (tuple) of given pixel coordinates (tuple). 893 ''' 894 _isGPanelValid() 895 return _p.toUser(pixel)
896
897 -def toUserHeight(pixelHeight):
898 ''' 899 Returns user y-increment of given pixel y-increment (always positive). 900 ''' 901 _isGPanelValid() 902 return _p.toUserHeight(pixelHeight)
903
904 -def toUserWidth(pixelWidth):
905 ''' 906 Returns user x-increment of given pixel x-increment (always positive). 907 ''' 908 _isGPanelValid() 909 return _p.toUserWidth(pixelWidth)
910
911 -def toUserX(pixelX):
912 ''' 913 Returns user x-coordinate of given pixel x-coordinate. 914 ''' 915 _isGPanelValid() 916 return _p.toUserX(pixelX)
917
918 -def toUserY(pixelY):
919 ''' 920 Returns user y-coordinate of given pixel y-coordinate. 921 ''' 922 _isGPanelValid() 923 return _p.toUserY(pixelY)
924
925 -def triangle(*args):
926 ''' 927 Draws a triangle with given corners. 928 6 parameters: x1, y1, x2, y2, x3, y3 coordinates of corners 929 3 parameters: [x1, y1], [x2, y2], [x3, y3] lists of corners 930 ''' 931 _isGPanelValid() 932 _p.triangle(*args)
933
934 -def window(xmin, xmax, ymin, ymax):
935 ''' 936 Sets user coordinate system left_x, right_x, bottom_y, top_y (inclusive). 937 Same as setUserCoords(). For TigerJython compatiblity. 938 939 @param xmin: the x coordinate (of a visible pixel) at left border 940 @param xmax: the x coordinate (of a visible pixel) at right border 941 @param ymin: the y coordinate (of a visible pixel) at bottom border 942 @param ymax: the y coordinate (of a visible pixel) at top border 943 ''' 944 _isGPanelValid() 945 _p.setUserCoords(xmin, xmax, ymin, ymax)
946
947 -def windowPosition(ulx, uly):
948 ''' 949 Sets the screen position (pixel coordinates of upper left corner). 950 ''' 951 _isGPanelValid() 952 _p.windowPosition(ulx, uly)
953
954 -def windowCenter():
955 ''' 956 Sets the window to the center of the screen. 957 ''' 958 _isGPanelValid() 959 _p.windowCenter()
960
961 -def _getCoords(*args):
962 if len(args) == 2: 963 return args[0], args[1] 964 elif len(args) == 1: 965 if type(args[0]) == complex: 966 return args[0].real, args[0].imag 967 elif type(args[0]) == list or type(args[0]) == tuple: 968 return args[0][0], args[0][1] 969 else: 970 raise ValueError("Illegal parameter type.") 971 else: 972 raise ValueError("Illegal number of parameters.")
973
974 -def _get2Coords(*args):
975 if len(args) == 4: 976 return args[0], args[1], args[2], args[3] 977 elif len(args) == 2: 978 val = [] 979 for arg in args: 980 if type(arg) == complex: 981 val.append(arg.real) 982 val.append(arg.imag) 983 elif type(args) == list or type(args) == tuple: 984 val.append(arg[0]) 985 val.append(arg[1]) 986 else: 987 raise ValueError("Illegal parameter type.") 988 return val[0], val[1], val[2], val[3] 989 else: 990 raise ValueError("Illegal number of parameters.")
991
992 # ------------------------ end of GPanel methods ----------- 993 994 -def run(f):
995 ''' 996 Calls f() in a new thread. 997 ''' 998 thread.start_new_thread(f, ())
999
1000 1001 -def getRandomX11Color():
1002 ''' 1003 Returns a random X11 color string. 1004 ''' 1005 return GPanel.getRandomX11Color()
1006
1007 # Code from: http://code.activestate.com 1008 -def linfit(X, Y):
1009 ''' 1010 Returns a and b in y = a*x + b for given list X of x values and 1011 corresponding list Y of values. 1012 ''' 1013 def mean(Xs): 1014 return sum(Xs) / len(Xs)
1015 m_X = mean(X) 1016 m_Y = mean(Y) 1017 1018 def std(Xs, m): 1019 normalizer = len(Xs) - 1 1020 return math.sqrt(sum((pow(x - m, 2) for x in Xs)) / normalizer) 1021 1022 def pearson_r(Xs, Ys): 1023 sum_xy = 0 1024 sum_sq_v_x = 0 1025 sum_sq_v_y = 0 1026 1027 for (x, y) in zip(Xs, Ys): 1028 var_x = x - m_X 1029 var_y = y - m_Y 1030 sum_xy += var_x * var_y 1031 sum_sq_v_x += pow(var_x, 2) 1032 sum_sq_v_y += pow(var_y, 2) 1033 return sum_xy / math.sqrt(sum_sq_v_x * sum_sq_v_y) 1034 1035 r = pearson_r(X, Y) 1036 b = r * (std(Y, m_Y) / std(X, m_X)) 1037 A = m_Y - b * m_X 1038 return b, A 1039
1040 1041 1042 1043 # ----------------------------- Size class ------------------------- 1044 -class Size():
1045 ''' 1046 Class that defines the pair width, height of dimension attributes. 1047 '''
1048 - def __init__(self, width, height):
1049 self.width = width 1050 self.height = height
1051
1052 1053 1054 # ===================================================================== 1055 # ============================= GPanel class ========================== 1056 # ===================================================================== 1057 -class GPanel(QtGui.QWidget):
1058 ''' 1059 Class to create a graphics window of default size 501x501 pixels (client drawing area) 1060 using a coordinate system with x-axis from left to right, y-axis from bottom to top 1061 (called user coordinates, default range 0..1, 0..1). 1062 1063 The drawing methods perform drawing operation in an offscreen buffer (QPixmap) 1064 and automatically renders it on the screen, so the graphics is shown step-by-step. 1065 1066 1067 The drawing methods perform drawing operation in an offscreen buffer (pixmap) 1068 and automatically renders it on the screen, so the graphics is shown step-by-step. 1069 1070 User coordinates: (ux, uy) 1071 Pixel coordinates: (px, py) (screen pixels) 1072 Transformation: px = px(ux), py = py(uy) 1073 Pixel coordinate range: 0..winWidth - 1 (inclusive), 0..winHeight - 1 (inclusive); (0,0) upper left corner, x to the right, y downwards 1074 User coordinate range: xmin..xmax (inclusive), ymin..ymax (inclusive); (0,0) lower left corner, x to the right, y upwards. 1075 1076 Transformation: user(ux, uy) to pixel(px, py): 1077 (width = winWidth - 1, height = winHeight - 1) 1078 px = a * ux + b 1079 py = c * uy + d 1080 with a = width / (xmax - xmin) 1081 b = width * xmin / (xmin - xmax) 1082 c = height / (ymin - ymax) 1083 d = height * ymax / (ymax - ymin) 1084 1085 Inverse: 1086 ux = (px - b) / a 1087 uy = (py - d) / c 1088 1089 Because of the transformation from float to pixel coordinates, some rounding errors 1090 may happen. If you need pixel accuracy, define a GPanel window with some user defined width x height, 1091 e.g. GPanal(Size(501, 401)). Define then user coordinates in the range 0..width-1, 0..height-1, e.g. 1092 setUserCoords(0, 500, 0, 400). Now pixels in the range 0..500 x 0..400 (inclusive) may be addressed with no 1093 rounding errors. (This is a total of 501 x 401 pixels.) 1094 1095 If you prefer a coordinate system with the origin at the upper left corner, define the y-range in reverse 1096 order, e.g. setUserCoords(0, 500, 400, 0). 1097 1098 WARNING: Because PyQt is not thread-safe, in principle all graphics drawings should be 1099 executed in the GUI thread (for GPanel the main thread or a GUI callback). 1100 1101 Typical program: 1102 1103 from pygpanel import * 1104 1105 p = GPanel(0, 10, 0, 10) 1106 for ypt in range(0, 11, 1): 1107 p.line(0, ypt, 10 - ypt, 0) 1108 time.sleep(0.1) # to see what happens 1109 p.keep() 1110 1111 keep() is blocking and keeps the graphics panel open until the close button is hit or the 1112 Python process terminates. 1113 ''' 1114
1115 - def __init__(self, *args, **kwargs):
1116 ''' 1117 Constructs a GPanel and displays a non-resizable graphics window. 1118 Defaults with no parameter: 1119 Window size: 501x501 pixels 1120 Window title: "GPanel" 1121 User coordinates: 0, 1, 0, 1 1122 Background color: white 1123 Pen color: black 1124 Pen size: 1 1125 1126 1 Parameter: Size(window_width, window_height) 1127 4 Parameters: xmin, xmax, ymin, ymax 1128 @param Size: a Size refererence that defines the width and height of the graphics window. 1129 ''' 1130 try: 1131 self._embedded = kwargs['embedded'] 1132 except: 1133 self._embedded = False 1134 else: 1135 if type(self._embedded) != bool: 1136 self._embedded = False 1137 if not self._embedded: 1138 self._app = QtGui.QApplication(sys.argv) 1139 super(GPanel, self).__init__() 1140 self.xmin = 0 1141 self.xmax = 1 1142 self.ymin = 0 1143 self.ymax = 1 1144 self.winWidth = 501 1145 self.winHeight = 501 1146 if not (len(args) == 0 or len(args) == 1 or len(args) == 4): 1147 raise ValueError("Illegal parameter list") 1148 if len(args) == 1: 1149 self.winWidth = args[0].width 1150 self.winHeight = args[0].height 1151 elif len(args) == 4: 1152 self.xmin = args[0] 1153 self.xmax = args[1] 1154 self.xmax = args[1] 1155 self.ymin = args[2] 1156 self.ymax = args[3] 1157 self._initUI()
1158
1159 - def _initUI(self):
1160 self._setDefaults() 1161 self._label = QLabel() 1162 self._pixmap = QPixmap(QSize(self.winWidth, self.winHeight)) 1163 self._vbox = QVBoxLayout() 1164 self._vbox.setContentsMargins(1, 1, 1, 1) 1165 self.setLayout(self._vbox) 1166 self._painter = QPainter(self._pixmap) 1167 self.paintEvent(0) 1168 self.clear() 1169 if not self._embedded: 1170 self.show() 1171 self.setFixedSize(self.winWidth + 2, self.winHeight + 2)
1172
1173 - def _setDefaults(self):
1174 self.setWindowTitle('GPanel') 1175 self._penSize = 1 1176 self._penColor = QColor(0, 0, 0) 1177 self._bgColor = QColor(255, 255, 255, 255) 1178 1179 # default pos of GPanel window 1180 if not self._embedded: 1181 ulx = 10 1182 uly = 10 1183 super(GPanel, self).move(ulx, uly) # position 1184 1185 self._xCurrent = 0 1186 self._yCurrent = 0 1187 self._enableRepaint = True 1188 self._adjust() 1189 self._onMousePressed = None 1190 self._onMouseReleased = None 1191 self._onMouseDragged = None 1192 self._onKeyPressed = None 1193 self._onKeyReleased = None 1194 self._isLeftMouseButton = False 1195 self._isRightMouseButton = False 1196 self._inMouseMoveCallback = False 1197 self._closeListener = None 1198 self._pathHistory = None 1199 self._savePixmap = None 1200 self._doRepaint = False
1201
1202 - def clear(self):
1203 ''' 1204 Clears the graphics window and the offscreen buffer used by the window 1205 (fully paint with background color). 1206 Sets the current graph cursor position to (0, 0). 1207 If enableRepaint(false) only clears the offscreen buffer. 1208 ''' 1209 self._painter.setPen(QPen(self._bgColor, 1)) 1210 self._painter.fillRect(QRect(0, 0, self.winWidth, self.winHeight), self._bgColor) 1211 self._painter.setPen(QPen(self._penColor, self._penSize)) 1212 self._xCurrent = 0 1213 self._yCurrent = 0 1214 if self._enableRepaint: 1215 self.repaint()
1216
1217 - def erase(self):
1218 ''' 1219 Same as clear(), but lets the current graph cursor unganged. 1220 ''' 1221 self._painter.setPen(QPen(self._bgColor, 1)) 1222 self._painter.fillRect(QRect(0, 0, self.winWidth, self.winHeight), self._bgColor) 1223 self._painter.setPen(QPen(self._penColor, self._penSize)) 1224 if self._enableRepaint: 1225 self.repaint()
1226
1227 - def keep(self):
1228 ''' 1229 Blocks until the title bar's close button is hit. Then cleans up 1230 the graphics system. 1231 ''' 1232 self._app.exec_() # blocking
1233 # self._painter.end() 1234 # sys.exit(0) 1235
1236 - def setTitle(self, title):
1237 ''' 1238 Sets the title in the window title bar. 1239 @param title: the title text 1240 ''' 1241 self.setWindowTitle(title)
1242 1243 # override
1244 - def paintEvent(self, e):
1245 if self._doRepaint: 1246 self._label.setPixmap(self._pixmap) 1247 self._vbox.addWidget(self._label) 1248 self._doRepaint = False
1249
1250 - def setColor(self, *args):
1251 ''' 1252 Same as setPenColor() 1253 ''' 1254 self.setPenColor(*args)
1255 1256
1257 - def _toRGBA(self, *args):
1258 if len(args) == 1: 1259 if type(args[0]) == str: 1260 try: 1261 color = args[0].lower() 1262 rgb = x11ColorDict[color] 1263 except KeyError: 1264 raise ValueError("X11 color", args[0], "not found") 1265 r = rgb[0] 1266 g = rgb[1] 1267 b = rgb[2] 1268 a = 255 1269 elif type(args[0]) == list or type(args[0]) == tuple: 1270 if len(args[0]) == 3: 1271 r = args[0][0] 1272 g = args[0][1] 1273 b = args[0][2] 1274 a = 255 1275 elif len(args[0]) == 4: 1276 r = args[0][0] 1277 g = args[0][1] 1278 b = args[0][2] 1279 a = args[0][3] 1280 else: 1281 raise ValueError("Illegal parameter list") 1282 else: 1283 raise ValueError("Illegal parameter list") 1284 1285 elif len(args) == 3: 1286 r = args[0] 1287 g = args[1] 1288 b = args[2] 1289 a = 255 1290 1291 elif len(args) == 4: 1292 r = args[0] 1293 g = args[1] 1294 b = args[2] 1295 a = 255 1296 1297 else: 1298 raise ValueError("Illegal number of arguments") 1299 1300 return r, g, b, a
1301
1302 - def setPenColor(self, *args):
1303 ''' 1304 Sets the current pen color. 1305 1 parameter: - string value considered as X11 color string 1306 - list considered as [r, b, g] or [r, g, b, a] 1307 - tuple considered as (r, b, g) or (r, g, b, a) 1308 3 parameters: values considered as RGB (alpha = 255) 1309 4 parameters: values considered as RGBA 1310 ''' 1311 r, g, b, a = self._toRGBA(*args) 1312 self._penColor = QColor(r, g, b, a) 1313 self._painter.setPen(QPen(self._penColor, self._penSize))
1314
1315 - def setPenSize(self, size):
1316 ''' 1317 Sets the current pen size (width) (>=1). 1318 Returns the previous pen size. 1319 @param width: the pen width >=1) 1320 ''' 1321 oldPenSize = self._penSize 1322 self._penSize = size 1323 self._painter.setPen(QPen(self._penColor, self._penSize)) 1324 return oldPenSize
1325 1326 # coordinate transformations
1327 - def toPixel(self, user):
1328 ''' 1329 Returns pixel coordinates (tuple) of given user coordinates (tupel). 1330 ''' 1331 return self.toPixelX(user[0]), self.toPixelY(user[1])
1332
1333 - def toPixelX(self, userX):
1334 ''' 1335 Returns pixel x-coordinate of given user x-coordinate. 1336 ''' 1337 return (int)(self._a * userX + self._b)
1338
1339 - def toPixelY(self, userY):
1340 ''' 1341 Returns pixel y-coordinate of given user y-coordinate. 1342 ''' 1343 return (int)(self._c * userY + self._d)
1344
1345 - def toPixelWidth(self, userWidth):
1346 ''' 1347 Returns pixel x-increment of given user x-increment (always positive). 1348 ''' 1349 return int(abs(self._a * userWidth))
1350
1351 - def toPixelHeight(self, userHeight):
1352 ''' 1353 Returns pixel y-increment of given user y-increment (always positive). 1354 ''' 1355 return int(abs(self._c * userHeight))
1356
1357 - def toUser(self, pixel):
1358 ''' 1359 Returns user coordinates (tuple) of given pixel coordinates (tuple). 1360 ''' 1361 return self.toUserX(pixel[0]), self.toUserY(pixel[1])
1362
1363 - def toUserX(self, pixelX):
1364 ''' 1365 Returns user x-coordinate of given pixel x-coordinate. 1366 ''' 1367 a = (self.winWidth - 1) / (self.xmax - self.xmin) 1368 b = (self.winWidth - 1) * self.xmin / (self.xmin - self.xmax) 1369 return (pixelX - b) / a
1370
1371 - def toUserY(self, pixelY):
1372 ''' 1373 Returns user y-coordinate of given pixel y-coordinate. 1374 ''' 1375 c = (self.winHeight - 1) / (self.ymin - self.ymax) 1376 d = (self.winHeight - 1) * self.ymax / (self.ymax - self.ymin) 1377 return (pixelY - d) / c
1378
1379 - def toUserWidth(self, pixelWidth):
1380 ''' 1381 Returns user x-increment of given pixel x-increment (always positive). 1382 ''' 1383 a = (self.winWidth - 1) / (self.xmax - self.xmin) 1384 return abs(pixelWidth / a)
1385
1386 - def toUserHeight(self, pixelHeight):
1387 ''' 1388 Returns user y-increment of given pixel y-increment (always positive). 1389 ''' 1390 c = (self.winWidth - 1) / (self._ymin - self._ymax) 1391 return abs(pixelHeight / c)
1392
1393 - def setUserCoords(self, xmin, xmax, ymin, ymax):
1394 ''' 1395 Sets user coordinate system left_x, right_x, bottom_y, top_y (inclusive). 1396 @param xmin: the x coordinate (of a visible pixel) at left border 1397 @param xmax: the x coordinate (of a visible pixel) at right border 1398 @param ymin: the y coordinate (of a visible pixel) at bottom border 1399 @param ymax: the y coordinate (of a visible pixel) at top border 1400 ''' 1401 self.xmin = xmin 1402 self.xmax = xmax 1403 self.ymin = ymin 1404 self.ymax = ymax 1405 self._adjust()
1406
1407 - def _adjust(self):
1408 self._a = (self.winWidth - 1) / (self.xmax - self.xmin) 1409 self._b = (self.winWidth - 1) * self.xmin / (self.xmin - self.xmax) 1410 self._c = (self.winHeight - 1) / (self.ymin - self.ymax) 1411 self._d = (self.winHeight - 1) * self.ymax / (self.ymax - self.ymin)
1412 1413 # end of coordinate transformations 1414
1415 - def repaint(self):
1416 ''' 1417 Renders the offscreen buffer in the graphics window. 1418 ''' 1419 self._doRepaint = True 1420 self.update() 1421 QApplication.processEvents()
1422
1423 - def enableRepaint(self, enable):
1424 ''' 1425 Enables/Disables automatic repaint in graphics drawing methods. 1426 @param enable: if True, the automatic repaint is enabled; otherwise disabled 1427 ''' 1428 self._enableRepaint = enable
1429
1430 - def line(self, x1, y1, x2, y2):
1431 ''' 1432 Draws a line with given user start and end coordinates 1433 and sets the graph cursor position to the end point. 1434 Also with 2 parameters of type complex, list or tuple. 1435 4 parameters: x1, y1, x2, y2 1436 2 parameters: pt1, pt2 as complex/list/tuple 1437 ''' 1438 xStart = self.toPixelX(x1) 1439 yStart = self.toPixelY(y1) 1440 xEnd = self.toPixelX(x2) 1441 yEnd = self.toPixelY(y2) 1442 self._painter.drawLine(xStart, yStart, xEnd, yEnd) 1443 self._xCurrent = x2 1444 self._yCurrent = y2 1445 if self._enableRepaint: 1446 self.repaint()
1447
1448 - def pos(self, x, y):
1449 ''' 1450 Sets the current graph cursor position to given user coordinates. 1451 (without drawing anything, same as move()). 1452 @param x: the x coordinate of the target point 1453 @param y: the y coordinate of the target point 1454 @param target: (alternative) the target point as complex, list or tuple 1455 ''' 1456 self._xCurrent = x 1457 self._yCurrent = y
1458
1459 - def move(self, x, y):
1460 # Overrides super.move() 1461 ''' 1462 Sets the current graph cursor position to given user coordinates. 1463 (without drawing anything, same as pos()). 1464 @param x: the x coordinate of the target point 1465 @param y: the y coordinate of the target point 1466 @param target: (alternative) the target point as complex, list or tuple 1467 ''' 1468 self.pos(x, y)
1469
1470 - def draw(self, x, y):
1471 ''' 1472 Draws a line form current graph cursor position to (x, y). 1473 Sets the graph cursor position to (x, y). 1474 @param x: the x coordinate of the target point 1475 @param y: the y coordinate of the target point 1476 @param target: (alternative) the target point as complex, list or tuple 1477 ''' 1478 self.line(self._xCurrent, self._yCurrent, x, y) 1479 if self._pathHistory != None: 1480 self._pathHistory.append([x, y])
1481
1482 - def linePlot(self, *args):
1483 ''' 1484 Draws a line plot with given x,y data. 1485 1 parameter: a list/tuple of subsequent data points [x, y] 1486 2 parameters: two lists/tuples x, y of corresponding x-y pairs 1487 The graph cursor position remains unchanged. 1488 ''' 1489 nodes = [] 1490 if len(args) == 1: 1491 for pt in args[0]: 1492 node = [pt[0], pt[1]] 1493 nodes.append(node) 1494 elif len(args) == 2: 1495 if len(args[0]) != len(args[1]): 1496 raise ValueError("x and y list/tuple must have equal size") 1497 for i in range(len(args[0])): 1498 node = [args[0][i], args[1][i]] 1499 nodes.append(node) 1500 else: 1501 raise ValueError("Illegal number of parameters.") 1502 1503 for i in range(len(nodes) - 1): 1504 x1 = self.toPixelX(nodes[i][0]) 1505 y1 = self.toPixelY(nodes[i][1]) 1506 x2 = self.toPixelX(nodes[i + 1][0]) 1507 y2 = self.toPixelY(nodes[i + 1][1]) 1508 self._painter.drawLine(x1, y1, x2, y2) 1509 1510 if self._enableRepaint: 1511 self.repaint()
1512
1513 - def getPos():
1514 ''' 1515 Returns a tuple with current graph cursor position (tuple, user coordinates). 1516 ''' 1517 return self._xCurrent, self._yCurrent
1518
1519 - def getPosX(self):
1520 ''' 1521 Returns the current graph cursor x-position (user coordinates). 1522 ''' 1523 return self._xCurrent
1524
1525 - def getPosY(self):
1526 ''' 1527 Returns the current graph cursor y-position (user coordinates). 1528 ''' 1529 return self._yCurrent
1530
1531 - def text(self, *args):
1532 ''' 1533 Draws a text at given position (user coordinates). 1534 1 parameter: at current graph cursor position 1535 2 parameters: target point (comolex/list/tuple), text 1536 3 parameters: x, y, text 1537 ''' 1538 if len(args) == 1: 1539 xPos = self.toPixelX(self._xCurrent) 1540 yPos = self.toPixelY(self._yCurrent) 1541 text = args[0] 1542 elif len(args) == 2: 1543 xPos, yPos = _getCoords(args[0][:-1]) 1544 text = args[1] 1545 elif len(args) == 3: 1546 xPos = self.toPixelX(args[0]) 1547 yPos = self.toPixelY(args[1]) 1548 text = args[2] 1549 else: 1550 raise ValueError("Illegal number of arguments") 1551 1552 self._painter.drawText(xPos, yPos, text) 1553 if self._enableRepaint: 1554 self.repaint()
1555
1556 - def addCloseListener(self, closeListener):
1557 ''' 1558 Registers the given function that is called when the title bar 1559 close button is hit. If a listener (!= None) is registered, 1560 the automatic closing is disabled. To close the window, call 1561 sys.exit(). 1562 1563 KEEP IN MIND: To use GUI callbacks, the main program must block in the keep() function. 1564 @param closeListener: a callback function called when the close button is hit 1565 ''' 1566 self._closeListener = closeListener
1567
1568 - def closeEvent(self, e):
1569 # Override 1570 if self._closeListener != None: 1571 e.ignore() 1572 self._closeListener()
1573
1574 - def setBgColor(self, *args):
1575 ''' 1576 Sets the background color. All drawings are erased and the current 1577 graph cursor is set to (0, 0). 1578 1579 1 parameter: - string value considered as X11 color string 1580 - list considered as [r, b, g] or [r, g, b, a] 1581 - tuple considered as (r, b, g) or (r, g, b, a) 1582 3 parameters: values considered as RGB (alpha = 255) 1583 4 parameters: values considered as RGBA 1584 ''' 1585 r, g, b, a = self._toRGBA(*args) 1586 self._bgColor = QColor(r, g, b, a) 1587 self.clear()
1588 1589
1590 - def circle(self, radius):
1591 ''' 1592 Draws a circle with center at the current graph cursor position 1593 with given radius in horizontal window coordinates. 1594 @param radius: the radius of the circle 1595 ''' 1596 xPix = self.toPixelX(self._xCurrent) 1597 yPix = self.toPixelY(self._yCurrent) 1598 rPix = self.toPixelWidth(radius) 1599 self._painter.drawEllipse(QPointF(xPix, yPix), rPix, rPix) 1600 if self._enableRepaint: 1601 self.repaint()
1602
1603 - def fillCircle(self, radius):
1604 ''' 1605 Draws a filled circle with center at the current graph cursor position 1606 with given radius in horizontal window coordinates (fill color = pen color). 1607 @param radius: the radius of the circle 1608 ''' 1609 xPix = self.toPixelX(self._xCurrent) 1610 yPix = self.toPixelY(self._yCurrent) 1611 rPix = self.toPixelWidth(radius) 1612 self._painter.setPen(Qt.NoPen) 1613 self._painter.setBrush(QBrush(self._penColor)) 1614 self._painter.drawEllipse(QPointF(xPix, yPix), rPix, rPix) 1615 if self._enableRepaint: 1616 self.repaint() 1617 self._painter.setPen(QPen(self._penColor, self._penSize)) 1618 self._painter.setBrush(Qt.NoBrush)
1619 1620
1621 - def ellipse(self, a, b):
1622 ''' 1623 Draws an ellipse with center at the current graph cursor position 1624 with given axes. 1625 @param a: the major ellipse axis 1626 @param b: the minor ellipse axis 1627 ''' 1628 xPix = self.toPixelX(self._xCurrent) 1629 yPix = self.toPixelY(self._yCurrent) 1630 aPix = self.toPixelWidth(a) 1631 bPix = self.toPixelHeight(b) 1632 self._painter.drawEllipse(QPointF(xPix, yPix), aPix, bPix) 1633 if self._enableRepaint: 1634 self.repaint()
1635
1636 - def fillEllipse(self, a, b):
1637 ''' 1638 Draws a filled ellipse with center at the current graph cursor position 1639 with given axes (fill color = pen color). 1640 @param a: the major ellipse axis 1641 @param b: the minor ellipse axis 1642 ''' 1643 xPix = self.toPixelX(self._xCurrent) 1644 yPix = self.toPixelY(self._yCurrent) 1645 aPix = self.toPixelWidth(a) 1646 bPix = self.toPixelHeight(b) 1647 self._painter.setPen(Qt.NoPen) 1648 self._painter.setBrush(QBrush(self._penColor)) 1649 self._painter.drawEllipse(QPointF(xPix, yPix), aPix, bPix) 1650 if self._enableRepaint: 1651 self.repaint() 1652 self._painter.setPen(QPen(self._penColor, self._penSize)) 1653 self._painter.setBrush(Qt.NoBrush)
1654
1655 - def rectangle(self, *args):
1656 ''' 1657 Draws a rectangle. 1658 2 parameters: Center at the current graph cursor position 1659 and given width and height. 1660 4 parameters: Given diagonal 1661 ''' 1662 if len(args) == 2: 1663 wPix = self.toPixelWidth(args[0]) 1664 hPix = self.toPixelHeight(args[1]) 1665 ulx = self.toPixelX(self._xCurrent) - wPix // 2 1666 uly = self.toPixelY(self._yCurrent) - hPix // 2 1667 elif len(args) == 4: 1668 wPix = self.toPixelWidth(args[2] - args[0]) 1669 hPix = self.toPixelHeight(args[3] - args[1]) 1670 ulx = self.toPixelX(args[0]) 1671 uly = self.toPixelY(args[1]) 1672 self._painter.drawRect(ulx, uly, wPix, hPix) 1673 if self._enableRepaint: 1674 self.repaint()
1675
1676 - def fillRectangle(self, *args):
1677 ''' 1678 Draws a filled rectangle (fill color = pen color). 1679 2 parameters: Center at the current graph cursor position 1680 and given width and height. 1681 4 parameters: Given diagonal 1682 ''' 1683 if len(args) == 2: 1684 wPix = self.toPixelWidth(args[0]) 1685 hPix = self.toPixelHeight(args[1]) 1686 ulx = self.toPixelX(self._xCurrent) - wPix // 2 1687 uly = self.toPixelY(self._yCurrent) - hPix // 2 1688 elif len(args) == 4: 1689 wPix = self.toPixelWidth(args[2] - args[0]) 1690 hPix = self.toPixelHeight(args[3] - args[1]) 1691 ulx = self.toPixelX(args[0]) 1692 uly = self.toPixelY(args[1]) 1693 self._painter.setPen(Qt.NoPen) 1694 self._painter.setBrush(QBrush(self._penColor)) 1695 self._painter.drawRect(ulx, uly, wPix, hPix) 1696 if self._enableRepaint: 1697 self.repaint() 1698 self._painter.setPen(QPen(self._penColor, self._penSize)) 1699 self._painter.setBrush(Qt.NoBrush)
1700
1701 - def polygon(self, *args):
1702 ''' 1703 Draws a polygon with given list of vertexes (list of [x, y] or (x, y)) 1704 (fill color = pen color). 1705 1 parameter: a list/tuple of the corners [x, y] or (x, y) 1706 2 parameters: two lists/tuples x, y of corresponding x-y pairs 1707 ''' 1708 nodes = [] 1709 if len(args) == 1: 1710 for pt in args[0]: 1711 node = QPointF(self.toPixelX(pt[0]), self.toPixelY(pt[1])) 1712 nodes.append(node) 1713 elif len(args) == 2: 1714 if len(args[0]) != len(args[1]): 1715 raise ValueError("x and y list/tuple must have equal size") 1716 for i in range(len(args[0])): 1717 node = QPointF(self.toPixelX(args[0][i]), self.toPixelY(args[1][i])) 1718 nodes.append(node) 1719 else: 1720 raise ValueError("Illegal number of parameters.") 1721 p = QPolygonF(nodes) 1722 self._painter.drawPolygon(p) 1723 if self._enableRepaint: 1724 self.repaint()
1725
1726 - def fillPolygon(self, *args):
1727 ''' 1728 Draws a filled polygon with given list of vertexes (list of [x, y] or (x, y)) 1729 (fill color = pen color). 1730 1 parameter: a list/tuple of the corners [x, y] or (x, y) 1731 2 parameters: two lists/tuples x, y of corresponding x-y pairs 1732 ''' 1733 nodes = [] 1734 if len(args) == 1: 1735 for pt in args[0]: 1736 node = QPointF(self.toPixelX(pt[0]), self.toPixelY(pt[1])) 1737 nodes.append(node) 1738 elif len(args) == 2: 1739 if len(args[0]) != len(args[1]): 1740 raise ValueError("x and y list/tuple must have equal size") 1741 for i in range(len(args[0])): 1742 node = QPointF(self.toPixelX(args[0][i]), self.toPixelY(args[1][i])) 1743 nodes.append(node) 1744 else: 1745 raise ValueError("Illegal number of parameters.") 1746 p = QPolygonF(nodes) 1747 self._painter.setPen(Qt.NoPen) 1748 self._painter.setBrush(QBrush(self._penColor)) 1749 self._painter.drawPolygon(p) 1750 if self._enableRepaint: 1751 self.repaint() 1752 self._painter.setPen(QPen(self._penColor, self._penSize)) 1753 self._painter.setBrush(Qt.NoBrush)
1754
1755 - def triangle(self, *args):
1756 ''' 1757 Draws a triangle with given corners. 1758 6 parameters: x1, y1, x2, y2, x3, y3 coordinates of corners 1759 3 parameters: [x1, y1], [x2, y2], [x3, y3] lists of corners 1760 ''' 1761 if len(args) == 6: # triangle(x1, y1, x2, y2, x3, y3) 1762 corners = [[args[0], args[1]], [args[2], args[3]], [args[4], args[5]]] 1763 self.polygon(corners) 1764 elif len(args) == 3: # triangle([x1, y1], [x2, y2], [x3, y3]) 1765 corners = [args[0], args[1], args[2]] 1766 self.polygon(corners) 1767 else: 1768 raise ValueError("Illegal number of parameters.")
1769
1770 - def fillTriangle(self, *args):
1771 ''' 1772 Draws a filled triangle with given corners. 1773 6 parameters: x1, y1, x2, y2, x3, y3 coordinates of corners 1774 3 parameters: [x1, y1], [x2, y2], [x3, y3] lists of corners 1775 ''' 1776 if len(args) == 6: # triangle(x1, y1, x2, y2, x3, y3) 1777 corners = [[args[0], args[1]], [args[2], args[3]], [args[4], args[5]]] 1778 self.fillPolygon(corners) 1779 elif len(args) == 3: # triangle([x1, y1], [x2, y2], [x3, y3]) 1780 corners = [args[0], args[1], args[2]] 1781 self.fillPolygon(corners) 1782 else: 1783 raise ValueError("Illegal number of parameters.")
1784
1785 - def arc(self, r, startAngle, spanAngle):
1786 ''' 1787 Draws a circle sector with center at the current graph cursor position, 1788 given radius and given start and span angles. 1789 @param radius: the radius of the arc 1790 @param startAngle: starting angle in degrees, zero to east, positive counter-clockwise 1791 @param spanAngle: span angle (sector angle) in degrees, positive counter-clockwise 1792 ''' 1793 xPix = self.toPixelX(self._xCurrent) 1794 yPix = self.toPixelY(self._yCurrent) 1795 rPix = self.toPixelWidth(r) 1796 topLeft = QPoint(xPix - rPix, yPix - rPix) 1797 bottomRight = QPoint(xPix + rPix, yPix + rPix) 1798 rect = QRect(topLeft, bottomRight) 1799 self._painter.drawArc(rect, int(16 * startAngle), int(16 * spanAngle)) 1800 if self._enableRepaint: 1801 self.repaint()
1802
1803 - def fillArc(self, r, startAngle, spanAngle):
1804 ''' 1805 Draws a filled circle sector with center at the current graph cursor position, 1806 given radius and given start and span angles. 1807 @param radius: the radius of the arc 1808 @param startAngle: starting angle in degrees, zero to east, positive counter-clockwise 1809 @param spanAngle: span angle (sector angle) in degrees, positive counter-clockwise 1810 ''' 1811 xPix = self.toPixelX(self._xCurrent) 1812 yPix = self.toPixelY(self._yCurrent) 1813 rPix = self.toPixelWidth(r) 1814 topLeft = QPoint(xPix - rPix, yPix - rPix) 1815 bottomRight = QPoint(xPix + rPix, yPix + rPix) 1816 rect = QRect(topLeft, bottomRight) 1817 self._painter.setPen(Qt.NoPen) 1818 self._painter.setBrush(QBrush(self._penColor)) 1819 self._painter.drawChord(rect, int(16 * startAngle), int(16 * spanAngle)) 1820 1821 # Draw sector triangle 1822 xStart = int(xPix + rPix * math.cos(math.radians(startAngle))) 1823 yStart = int(yPix - rPix * math.sin(math.radians(startAngle))) 1824 xEnd = int(xPix + rPix * math.cos(math.radians(startAngle + spanAngle))) 1825 yEnd = int(yPix - rPix * math.sin(math.radians(startAngle + spanAngle))) 1826 triangle = [[xPix, yPix], [xStart, yStart], [xEnd, yEnd]] 1827 nodes = [] 1828 for pt in triangle: 1829 node = QPointF(pt[0], pt[1]) 1830 nodes.append(node) 1831 p = QPolygonF(nodes) 1832 self._painter.drawPolygon(p) 1833 1834 if self._enableRepaint: 1835 self.repaint() 1836 self._painter.setPen(QPen(self._penColor, self._penSize)) 1837 self._painter.setBrush(Qt.NoBrush)
1838
1839 - def chord(self, r, startAngle, spanAngle):
1840 ''' 1841 Draws a circle chord with center at the current graph cursor position, 1842 given radius and given start and span angles (in degrees, positive 1843 counter-clockwise, zero to east). 1844 @param radius: the radius of the arc 1845 @param startAngle: starting angle in degrees, zero to east, positive counter-clockwise 1846 @param spanAngle: span angle (sector angle) in degrees, positive counter-clockwise 1847 ''' 1848 xPix = self.toPixelX(self._xCurrent) 1849 yPix = self.toPixelY(self._yCurrent) 1850 rPix = self.toPixelWidth(r) 1851 topLeft = QPoint(xPix - rPix, yPix - rPix) 1852 bottomRight = QPoint(xPix + rPix, yPix + rPix) 1853 rect = QRect(topLeft, bottomRight) 1854 self._painter.drawChord(rect, int(16 * startAngle), int(16 * spanAngle)) 1855 if self._enableRepaint: 1856 self.repaint()
1857
1858 - def fillChord(self, r, startAngle, spanAngle):
1859 ''' 1860 Draws a filled circle chord with center at the current graph cursor position, 1861 given radius and given start and span angles (in degrees, positive 1862 counter-clockwise, zero to east). 1863 @param radius: the radius of the arc 1864 @param startAngle: starting angle in degrees, zero to east, positive counter-clockwise 1865 @param spanAngle: span angle (sector angle) in degrees, positive counter-clockwise 1866 ''' 1867 xPix = self.toPixelX(self._xCurrent) 1868 yPix = self.toPixelY(self._yCurrent) 1869 rPix = self.toPixelWidth(r) 1870 topLeft = QPoint(xPix - rPix, yPix - rPix) 1871 bottomRight = QPoint(xPix + rPix, yPix + rPix) 1872 rect = QRect(topLeft, bottomRight) 1873 self._painter.setPen(Qt.NoPen) 1874 self._painter.setBrush(QBrush(self._penColor)) 1875 self._painter.drawChord(rect, int(16 * startAngle), int(16 * spanAngle)) 1876 if self._enableRepaint: 1877 self.repaint() 1878 self._painter.setPen(QPen(self._penColor, self._penSize)) 1879 self._painter.setBrush(Qt.NoBrush)
1880
1881 - def startPath(self):
1882 ''' 1883 Starts recording the path vertexes. The positions of subsequent draw() operations are saved. 1884 The path is used to show a filled polygon when fillPath() is called. 1885 ''' 1886 self._pathHistory = [[self._xCurrent, self._yCurrent]]
1887
1888 - def fillPath(self, color):
1889 ''' 1890 Closes the path started with startPath() and shows a filled polygon from the saved 1891 draw() positions with given color. 1892 ''' 1893 if self._pathHistory == None: 1894 raise Exception("Must call startPath() before fillPath()") 1895 oldColor = self._penColor 1896 oldSize = self._penSize 1897 self.setPenColor(color) 1898 self.setPenSize(1) 1899 self.fillPolygon(self._pathHistory) 1900 self._painter.setPen(QPen(oldColor, oldSize)) 1901 self.polygon(self._pathHistory) # draw outline again 1902 self._pathHistory = None
1903
1904 - def showImage(self, *args):
1905 ''' 1906 Draws the picture with given file path or given image at given upper-left coordinates. 1907 1st parameter: image path (string) or QImage reference 1908 2nd, 3rd parameters: llx, lly (lower left corner in user coordinates) 1909 ''' 1910 if type(args[0])== str: 1911 img = QImage(args[0]) 1912 else: 1913 img = args[0] 1914 xPix = self.toPixelX(args[1]) 1915 yPix = self.toPixelY(args[2]) - img.height() + 1 # 1 pixel border 1916 self._painter.drawImage(xPix, yPix, img) 1917 if self._enableRepaint: 1918 self.repaint()
1919
1920 - def point(self, *args):
1921 ''' 1922 Draws a single point with current pen size and pen color at given user coordinates. 1923 No params: draws a current graph cursor position 1924 @param x: the x coordinate of the target point 1925 @param y: the y coordinate of the target point 1926 @param target: (alternative) the target point as complex, list or tuple 1927 ''' 1928 if len(args) == 0: 1929 xPix = self.toPixelX(self._xCurrent) 1930 yPix = self.toPixelY(self._yCurrent) 1931 elif len(args) == 1: 1932 pt = _getCoords(*args) 1933 xPix = self.toPixelX(pt[0]) 1934 yPix = self.toPixelY(pt[1]) 1935 elif len(args) == 2: 1936 xPix = self.toPixelX(args[0]) 1937 yPix = self.toPixelY(args[1]) 1938 else: 1939 raise ValueError("Illegal number of arguments") 1940 self._painter.drawPoint(QPointF(xPix, yPix)) 1941 if self._enableRepaint: 1942 self.repaint()
1943
1944 - def getPixelColor(self, *args):
1945 ''' 1946 Returns the RGBA color tuple of a pixel with given user coordinates. 1947 No params: Returns color at current graph cursor position. 1948 ''' 1949 if len(args) == 0: 1950 xPix = self.toPixelX(self._xCurrent) 1951 yPix = self.toPixelY(self._yCurrent) 1952 elif len(args) == 2: 1953 xPix = self.toPixelX(args[0]) 1954 yPix = self.toPixelY(args[1]) 1955 else: 1956 raise ValueError("Illegal number of parameters.") 1957 img = self._pixmap.toImage() 1958 c = img.pixel(xPix, yPix) 1959 return QColor(c).getRgb() # RGBA
1960
1961 - def getPixelColorStr(self, *args):
1962 ''' 1963 Returns the X11 color string of a pixel with given user coordinates. 1964 No params: Returns color at current graph cursor position. 1965 ''' 1966 r, g, b, a = self.getPixelColor(*args) 1967 for name, rgb in x11ColorDict.items(): 1968 if name[-1] in [str(i) for i in range(10)]: # skip names with ending number 1969 continue 1970 if " " in name: # skip names with space 1971 continue 1972 if "grey" in name: # skip British gray 1973 continue 1974 if rgb == [r, g, b]: 1975 return name 1976 raise ValueError("X11 color", [r, g, b], "not found")
1977
1978 - def _toColor(self, color):
1979 if type(color) == str: 1980 try: 1981 color = color.lower() 1982 color = x11ColorDict[color] 1983 return color 1984 except KeyError: 1985 raise ValueError("X11 color", color, "not found") 1986 else: 1987 return color
1988
1989 - def fill(self, x, y, *args):
1990 ''' 1991 Fills the closed unicolored region with the inner point (x, y) with 1992 the replacement color (RGB, RGBA or X11 color string). 1993 The old color is not given, the color of the current (x, y) pixel is taken. 1994 @param x: the x coordinate of the inner point 1995 @param y: the y coordinate of the inner point 1996 @param color: the old color (RGB list/tuple or X11 color string) (may be omitted) 1997 @param replacementColor: the new color (RGB list/tuple or X11 color string) 1998 ''' 1999 xPix = self.toPixelX(x) 2000 yPix = self.toPixelY(y) 2001 2002 if len(args) == 2: 2003 color = self._toColor(args[0]) 2004 replacementColor = self._toColor(args[1]) 2005 elif len(args) == 1: 2006 im = self._pixmap.toImage() 2007 col= QColor(im.pixel(xPix, yPix)) 2008 color = [col.red(), col.green(), col.blue()] 2009 replacementColor = self._toColor(args[0]) 2010 else: 2011 raise ValueError("Illegal number of parameters.") 2012 2013 img = GPanel.floodFill(self._pixmap, [self.toPixelX(x), self.toPixelY(y)], color, replacementColor) 2014 self._painter.drawImage(0, 0, img) 2015 if self._enableRepaint: 2016 self.repaint()
2017
2018 - def getPainter(self):
2019 ''' 2020 Returns the QPainter reference used to draw into the offscreen buffer. 2021 ''' 2022 return self._painter
2023
2024 - def getFullImage(self):
2025 ''' 2026 Returns the QImage reference of the whole graphics area. 2027 ''' 2028 return self._pixmap.toImage()
2029
2030 - def drawGrid(self, *args):
2031 ''' 2032 Draws a coordinate system with annotated axes. 2033 (You must increase the user coordinate system at least 10% in both directions.) 2034 drawGrid(x, y): Grid with 10 ticks in range 0..x, 0..y. Label text depends if x, y or int or float 2035 drawGrid(x, y, color): same with given grid color 2036 drawGrid(x1, x2, y1, y2): same with given span x1..x2, y1..y2 2037 drawGrid(x1, x2, y1, y2, color): same with given grid color 2038 drawGrid(x1, x2, y1, y2, x3, y3): same with given number of ticks x3, y3 in x- and y-direction 2039 ''' 2040 if len(args) == 2: 2041 self._drawGrid(0, args[0], 0, args[1], 10, 10, None) 2042 if len(args) == 3: 2043 self._drawGrid(0, args[0], 0, args[1], 10, 10, args[2]) 2044 elif len(args) == 4: 2045 self._drawGrid(args[0], args[1], args[2], args[3], 10, 10, None) 2046 elif len(args) == 5: 2047 self._drawGrid(args[0], args[1], args[2], args[3], 10, 10, args[4]) 2048 elif len(args) == 6: 2049 self._drawGrid(args[0], args[1], args[2], args[3], args[4], args[5], None) 2050 elif len(args) == 7: 2051 self._drawGrid(args[0], args[1], args[2], args[3], args[4], args[5], args[6]) 2052 else: 2053 raise ValueError("Illegal number of parameters.")
2054
2055 - def _drawGrid(self, xmin, xmax, ymin, ymax, xticks, yticks, color):
2056 # Save current cursor and color 2057 xPos = self.getPosX() 2058 yPos = self.getPosY() 2059 if color != None: 2060 oldColor = self._penColor 2061 self.setPenColor(color) 2062 # Horizontal 2063 for i in range(yticks + 1): 2064 y = ymin + (ymax - ymin) / float(yticks) * i 2065 self.line(xmin, y, xmax, y) 2066 if isinstance(ymin, float) or isinstance(ymax, float): 2067 self.text(xmin - 0.09 * (xmax - xmin), y, str(y)) 2068 else: 2069 self.text(xmin - 0.09 * (xmax - xmin), y, str(int(y))) 2070 # Vertical 2071 for k in range(xticks + 1): 2072 x = xmin + (xmax - xmin) / float(xticks) * k 2073 self.line(x, ymin, x, ymax) 2074 if isinstance(xmin, float) or isinstance(xmax, float): 2075 self.text(x, ymin - 0.05 * (ymax - ymin), str(x)) 2076 else: 2077 self.text(x, ymin - 0.05 * (ymax - ymin), str(int(x))) 2078 # Restore cursor and color 2079 self.pos(xPos, yPos) 2080 if color != None: 2081 self._penColor = oldColor 2082 self._painter.setPen(QPen(self._penColor, self._penSize))
2083
2084 - def addMousePressListener(self, onMousePressed):
2085 ''' 2086 Registers a callback that is invoked when a mouse button is pressed. 2087 Use isLeftMouseButton() or isRightMouseButton() to check which button used. 2088 2089 KEEP IN MIND: To use GUI callbacks, the main program must block in the keep() function. 2090 @param onMousePressed: a callback function called when a mouse button is pressed 2091 ''' 2092 self._onMousePressed = onMousePressed
2093
2094 - def addMouseReleaseListener(self, onMouseReleased):
2095 ''' 2096 Registers a callback that is invoked when a mouse button is releases. 2097 Use isLeftMouseButton() or isRightMouseButton() to check which button used. 2098 2099 KEEP IN MIND: To use GUI callbacks, the main program must block in the keep() function. 2100 @param onMouseReleased: a callback function called when a mouse button is released 2101 ''' 2102 self._onMouseReleased = onMouseReleased
2103
2104 - def addMouseDragListener(self, onMouseDragged):
2105 ''' 2106 Registers a callback that is invoked when the mouse is moved while a mouse button is pressed (drag). 2107 2108 KEEP IN MIND: To use GUI callbacks, the main program must block in the keep() function. 2109 @param onMouseDragged: a callback function called when the moused is dragged 2110 ''' 2111 self._onMouseDragged = onMouseDragged
2112
2113 - def isLeftMouseButton(self):
2114 ''' 2115 Returns True, if the last mouse action was performed with the left mouse button. 2116 ''' 2117 return self._isLeftMouseButton
2118
2119 - def isRightMouseButton(self):
2120 ''' 2121 Returns True, if the last mouse action was performed with the right mouse button. 2122 ''' 2123 return self._isRightMouseButton
2124
2125 - def addKeyPressListener(self, onKeyPressed):
2126 ''' 2127 Registers a callback that is invoked when a key is pressed (and the graphics window has the focus). 2128 2129 KEEP IN MIND: To use GUI callbacks, the main program must block in the keep() function. 2130 @param onKeyPressed: a callback function called when a key is pressed 2131 ''' 2132 self._onKeyPressed = onKeyPressed
2133
2134 - def addKeyReleaseListener(self, onKeyReleased):
2135 ''' 2136 Registers a callback that is invoked when a key is released (and the graphics window has the focus). 2137 2138 KEEP IN MIND: To use GUI callbacks, the main program must block in the keep() function. 2139 @param onKeyReleased: a callback function called when a key is released 2140 ''' 2141 self._onKeyReleased = onKeyReleased
2142
2143 - def getScreenWidth(self):
2144 ''' 2145 Returns the screen width in pixels. 2146 ''' 2147 screen_resolution = self._app.desktop().screenGeometry() 2148 return screen_resolution.width()
2149
2150 - def getScreenHeight(self):
2151 ''' 2152 Returns the screen height in pixels. 2153 ''' 2154 screen_resolution = self._app.desktop().screenGeometry() 2155 return screen_resolution.height()
2156 2157
2158 - def setWindowCenter(self):
2159 ''' 2160 Sets the screen position to the center of the screen. 2161 ''' 2162 frameGm = self.frameGeometry() 2163 centerPoint = QtGui.QDesktopWidget().availableGeometry().center() 2164 frameGm.moveCenter(centerPoint) 2165 super(GPanel, self).move(frameGm.topLeft())
2166
2167 - def setWindowPos(self, ulx, uly):
2168 ''' 2169 Sets the screen position of the graphics window. 2170 @param ulx: the upper left corner's x-coordinate 2171 @param ulx: the upper left corner's y-coordinate 2172 ''' 2173 super(GPanel, self).move(ulx, uly)
2174
2175 - def saveGraphics(self):
2176 ''' 2177 Saves the current graphics into a image buffer. Use restoreGraphics() 2178 to restore it. 2179 ''' 2180 self._savePixmap = self._pixmap.copy(QRect())
2181
2182 - def restoreGraphics(self):
2183 ''' 2184 Restores the saved graphics from the image buffer. Use saveGraphics() 2185 to save it. 2186 ''' 2187 if self._savePixmap == None: 2188 raise Exception("Store graphics buffer is empty.") 2189 img = self._savePixmap.toImage() 2190 self._painter.drawImage(0, 0, img) 2191 if self._enableRepaint: 2192 self.repaint()
2193
2194 - def setXORMode(self, *args):
2195 ''' 2196 Performs pixel color XOR operation with the existing background pixel. 2197 Be aware that if the background is white, drawing with a white pen shows a black pixel. 2198 (Parameter not used, for TigerJython compatibility) 2199 ''' 2200 self._painter.setCompositionMode(QPainter.RasterOp_SourceXorDestination)
2201 2202
2203 - def setPaintMode(self):
2204 ''' 2205 Resets the drawing mode to standard (overwriting). 2206 ''' 2207 self._painter.setCompositionMode(QPainter.CompositionMode_SourceOver)
2208
2209 - def windowPosition(self, ulx, uly):
2210 ''' 2211 Sets the screen position (pixel coordinates of upper left corner). 2212 ''' 2213 super(GPanel, self).move(ulx, uly)
2214
2215 - def windowCenter(self):
2216 ''' 2217 Sets the window to the center of the screen. 2218 ''' 2219 xc, yc = GPanel.getScreenCenter() 2220 self.windowPosition(xc - self.winWidth // 2, yc - self.winHeight // 2)
2221 2222
2223 - def arrow(self, *args):
2224 ''' 2225 Draws an arrow from point pt1 = [x1, y1] to pt2 = [x2, y2] 2226 @param pt1 the starting point 2227 @param pt2: the ending point (where is the arrowhead) 2228 @param size: the length of the arrowhead's triangle (in pixels, default: 10) 2229 2230 Overloaded versions: points as list/tuple or x, y coordinates 2231 ''' 2232 2233 if len(args) == 5: 2234 self._arrow([args[0], args[1]], [args[2], args[3]], args[4]) 2235 elif len(args) == 4: 2236 self._arrow([args[0], args[1]], [args[2], args[3]]) 2237 elif len(args) == 3: 2238 self._arrow(args[0], args[1], args[2]) 2239 elif len(args) == 2: 2240 self._arrow(args[0], args[1])
2241
2242 - def _arrow(self, pt0, pt1, size = 10):
2243 s = self.toUserWidth(size) 2244 phi = math.atan2(pt1[1] - pt0[1], pt1[0] - pt0[0]) 2245 h = math.sqrt(3) / 2 * s 2246 tri = [[-h, s/2], [-h, -s/2], [0, 0]] 2247 tri = self._rotTri(tri, phi) 2248 tri = self._transTri(tri, pt1) 2249 self.fillTriangle(tri[0], tri[1], tri[2]) 2250 d = math.sqrt((pt0[0] - pt1[0]) * (pt0[0] - pt1[0]) + (pt0[1] - pt1[1]) * (pt0[1] - pt1[1])) 2251 p = self.getDividingPoint(pt0[0], pt0[1], pt1[0], pt1[1], (d - h) / d) 2252 self.line(pt0[0], pt0[1], p[0], p[1])
2253
2254 - def doubleArrow(self, *args):
2255 ''' 2256 Draws a double arrow from point pt1 = [x1, y1] to pt2 = [x2, y2] 2257 (arrowheads on both ends). 2258 @param pt1 one end of the arrow 2259 @param pt2: the other end of the arrow 2260 @param size: the length of the arrowhead's triangle (in pixels, default: 10) 2261 2262 Overloaded versions: points as list/tuple or x, y coordinates 2263 ''' 2264 2265 if len(args) == 5: 2266 self._doubleArrow([args[0], args[1]], [args[2], args[3]], args[4]) 2267 elif len(args) == 4: 2268 self._doubleArrow([args[0], args[1]], [args[2], args[3]]) 2269 elif len(args) == 3: 2270 self._doubleArrow(args[0], args[1], args[2]) 2271 elif len(args) == 2: 2272 self._doubleArrow(args[0], args[1])
2273
2274 - def _doubleArrow(self, pt0, pt1, size = 10):
2275 s = self.toUserWidth(size) 2276 phi = math.atan2(pt1[1] - pt0[1], pt1[0] - pt0[0]) 2277 h = math.sqrt(3) / 2 * s 2278 tri = [[-h, s/2], [-h, -s/2], [0, 0]] 2279 tri1 = self._rotTri(tri, phi) 2280 tri1 = self._transTri(tri1, pt1) 2281 self.fillTriangle(tri1[0], tri1[1], tri1[2]) 2282 tri2 = self._rotTri(tri, math.pi + phi) 2283 tri2 = self._transTri(tri2, pt0) 2284 self.fillTriangle(tri2[0], tri2[1], tri2[2]) 2285 d = math.sqrt((pt0[0] - pt1[0]) * (pt0[0] - pt1[0]) + (pt0[1] - pt1[1]) * (pt0[1] - pt1[1])) 2286 p1 = self.getDividingPoint(pt0[0], pt0[1], pt1[0], pt1[1], (d - h) / d) 2287 p0 = self.getDividingPoint(pt0[0], pt0[1], pt1[0], pt1[1], h / d) 2288 self.line(p0[0], p0[1], p1[0], p1[1])
2289
2290 - def _rotTri(self, tri, phi):
2291 pt0 = [math.cos(phi) * tri[0][0] - math.sin(phi) * tri[0][1], math.sin(phi) * tri[0][0] + math.cos(phi) * tri[0][1]] 2292 pt1 = [math.cos(phi) * tri[1][0] - math.sin(phi) * tri[1][1], math.sin(phi) * tri[1][0] + math.cos(phi) * tri[1][1]] 2293 pt2 = [math.cos(phi) * tri[2][0] - math.sin(phi) * tri[2][1], math.sin(phi) * tri[2][0] + math.cos(phi) * tri[2][1]] 2294 return [pt0, pt1, pt2]
2295
2296 - def _transTri(self, tri, pt):
2297 pt0 = [tri[0][0] + pt[0], tri[0][1] + pt[1]] 2298 pt1 = [tri[1][0] + pt[0], tri[1][1] + pt[1]] 2299 pt2 = [tri[2][0] + pt[0], tri[2][1] + pt[1]] 2300 return [pt0, pt1, pt2]
2301 2302 # ------------- Mouse events ----------------------------
2303 - def mousePressEvent(self, e):
2304 pos = QPoint(e.pos()) 2305 self._isLeftMouseButton = (e.button() == Qt.LeftButton) 2306 self._isRightMouseButton = (e.button() == Qt.RightButton) 2307 if self._onMousePressed != None: 2308 self._onMousePressed(self.toUserX(pos.x()), self.toUserY(pos.y()))
2309
2310 - def mouseReleaseEvent(self, e):
2311 pos = QPoint(e.pos()) 2312 self._isLeftMouseButton = (e.button() == Qt.LeftButton) 2313 self._isRightMouseButton = (e.button() != Qt.RightButton) 2314 if self._onMouseReleased != None: 2315 self._onMouseReleased(self.toUserX(pos.x()), self.toUserY(pos.y()))
2316
2317 - def mouseMoveEvent(self, e):
2318 # reject reentrance 2319 if self._inMouseMoveCallback: 2320 return 2321 self._inMouseMoveCallback = True 2322 pos = QPoint(e.pos()) 2323 if self._onMouseDragged != None: 2324 self._onMouseDragged(self.toUserX(pos.x()), self.toUserY(pos.y())) 2325 self._inMouseMoveCallback = False
2326 2327 # ------------- Key events ---------------------------
2328 - def keyPressEvent(self, e):
2329 key = e.key() 2330 if self._onKeyPressed != None: 2331 self._onKeyPressed(key)
2332
2333 - def keyReleaseEvent(self, e):
2334 key = e.key() 2335 if self._onKeyReleased != None: 2336 self._onKeyReleased(key)
2337 2338 # ------------- static methods ------------------------------- 2339 @staticmethod
2340 - def loadImage(filename, pic_format = None):
2341 ''' 2342 Returns a QImage of the picture loaded from the given file. For pic_format = None, 2343 the picture format is guessed from the file data. 2344 @param: the file path to the picture file 2345 @param pic_format: format of picture, supported: "None" (default), "GIF", "JPG", 2346 "BMP", "PNG", "PBM", "PGM", "PPM", "TIFF", "XBM" "XPM". 2347 ''' 2348 img = QImage(filename, pic_format) 2349 return img
2350 2351 @staticmethod
2352 - def getPixelColorImg(image, xPix, yPix):
2353 ''' 2354 Returns a tuple with the RGBA values at given pixel position (pixel coordinates). 2355 @param image: the QImage reference 2356 @param xPix: the pixel x-coordinate 2357 @param yPix: the pixel y-coordinate 2358 ''' 2359 c = image.pixel(xPix, yPix) 2360 return QColor(c).getRgb() # RGBA
2361 2362 @staticmethod
2363 - def scale(image, scaleFactor):
2364 ''' 2365 Returns a new QImage of the scaled picture of the given QImage. 2366 @param image: the original QImage reference 2367 @param scaleFactor: the scale factor 2368 ''' 2369 width = int(image.width() * scaleFactor) 2370 img = image.scaledToWidth(width) 2371 return img
2372 2373 @staticmethod
2374 - def crop(image, x1, y1, x2, y2):
2375 ''' 2376 Returns a QImage of the sub-area of the given QImage. 2377 @param image: the given QImage reference 2378 @param xPix: the pixel ulx-coordinate 2379 @param yPix: the pixel uly-coordinate 2380 ''' 2381 width = abs(x2 - x1) 2382 height = abs(y2 - y1) 2383 img = image.copy(x1, y1, width, height) 2384 return img
2385 2386 @staticmethod
2387 - def getDividingPoint(x1, y1, x2, y2, ratio):
2388 ''' 2389 Returns the tuple of user coordinates of the point on the line through the point pt1 = (x1, y1) 2390 and the point pt2 = (x2, y2) that is in distance ratio times the length from pt1 to pt2 from 2391 pt1. For ratio < 0 the point is in the opposite direction. 2392 3 parameteters: pt1, pt2 (complex/list/tuple), ratio 2393 5 parameteters: x1, y1, x2, y2, ratio 2394 ''' 2395 v1 = (x1, y1) 2396 v2 = (x2, y2) 2397 dv = (v2[0] - v1[0], v2[1] - v1[1]) # = v2 - v1 2398 v = (v1[0] + ratio * dv[0], v1[1] + ratio * dv[1]) # v1 + ratio * dv 2399 return v[0], v[1]
2400 2401 @staticmethod
2402 - def floodFill(pm, pt, oldColor, newColor):
2403 # Implementation from Hardik Gajjar of algorithm 2404 # at http://en.wikipedia.org/wiki/Flood_fill 2405 ''' 2406 Fills a bounded single-colored region with 2407 the given color. The given point is part of the region and used 2408 to specify it. 2409 @param pm the pixmap containing the connected region 2410 @param pt a point inside the region 2411 @param oldColor the old color of the region (RGB list/tuple) 2412 @param newColor the new color of the region (RGB list/tuple) 2413 @return a new qImage with the transformed region 2414 ''' 2415 image = pm.toImage() 2416 oldColor = QColor(oldColor[0], oldColor[1], oldColor[2]).rgb() 2417 newColor = QColor(newColor[0], newColor[1], newColor[2]).rgb() 2418 q = [pt] 2419 2420 # Perform filling operation 2421 while len(q) > 0: 2422 n = q.pop(0) 2423 if QColor(image.pixel(n[0], n[1])).rgb() != oldColor: 2424 continue 2425 2426 w = n 2427 e = [n[0] + 1, n[1]] 2428 while w[0] > 0 and QColor(image.pixel(w[0], w[1])).rgb() == oldColor: 2429 image.setPixel(w[0], w[1], newColor) 2430 if w[1] > 0 and QColor(image.pixel(w[0], w[1] - 1)).rgb() == oldColor: 2431 q.append([w[0], w[1] - 1]) 2432 if w[1] < image.height() - 1 and QColor(image.pixel(w[0], w[1] + 1)).rgb() == oldColor: 2433 q.append([w[0], w[1] + 1]) 2434 w[0] -= 1 2435 2436 while e[0] < image.width() - 1 and QColor(image.pixel(e[0], e[1])).rgb() == oldColor: 2437 image.setPixel(e[0], e[1], newColor) 2438 if e[1] > 0 and QColor(image.pixel(e[0], e[1] - 1)).rgb() == oldColor: 2439 q.append([e[0], e[1] - 1]) 2440 if e[1] < image.height() - 1 and QColor(image.pixel(e[0], e[1] + 1)).rgb() == oldColor: 2441 q.append([e[0], e[1] + 1]) 2442 e[0] += 1 2443 return image
2444 2445 @staticmethod
2446 - def getRandomX11Color():
2447 ''' 2448 Returns a random X11 color string. 2449 ''' 2450 r = random.randint(0, 540) 2451 c = x11ColorDict.keys() 2452 return c[r]
2453 2454 @staticmethod
2455 - def getScreenCenter():
2456 ''' 2457 Returns x, y coordinates tuple of the screen's center point. 2458 ''' 2459 centerPoint = QtGui.QDesktopWidget().availableGeometry().center() 2460 return centerPoint.x(), centerPoint.y()
2461 2462 # ----------------------------- GPane class ------------------------- 2463 ''' 2464 Subclass of GPanel to be used as embedded QWidget in a GUI dialog (QDialog). 2465 '''
2466 -class GPane(GPanel):
2467
2468 - def __init__(self, *args, **kwargs):
2469 ''' 2470 Creates a GPanel with no application window. 2471 ''' 2472 super(GPane, self).__init__(*args, embedded = True)
2473 2474 2475 # ----------------------------- Useful constants ------------------------- 2476 ''' 2477 X11 to RGB color mapping 2478 ''' 2479 x11ColorDict = { 2480 "aqua":[0, 255, 255], 2481 "cornflower":[100, 149, 237], 2482 "crimson":[220, 20, 60], 2483 "fuchsia":[255, 0, 255], 2484 "indigo":[75, 0, 130], 2485 "lime":[50, 205, 50], 2486 "silver":[192, 192, 192], 2487 "ghost white":[248, 248, 255], 2488 "snow":[255, 250, 250], 2489 "ghostwhite":[248, 248, 255], 2490 "white smoke":[245, 245, 245], 2491 "whitesmoke":[245, 245, 245], 2492 "gainsboro":[220, 220, 220], 2493 "floral white":[255, 250, 240], 2494 "floralwhite":[255, 250, 240], 2495 "old lace":[253, 245, 230], 2496 "oldlace":[253, 245, 230], 2497 "linen":[250, 240, 230], 2498 "antique white":[250, 235, 215], 2499 "antiquewhite":[250, 235, 215], 2500 "papaya whip":[255, 239, 213], 2501 "papayawhip":[255, 239, 213], 2502 "blanched almond":[255, 235, 205], 2503 "blanchedalmond":[255, 235, 205], 2504 "bisque":[255, 228, 196], 2505 "peach puff":[255, 218, 185], 2506 "peachpuff":[255, 218, 185], 2507 "navajo white":[255, 222, 173], 2508 "navajowhite":[255, 222, 173], 2509 "moccasin":[255, 228, 181], 2510 "cornsilk":[255, 248, 220], 2511 "ivory":[255, 255, 240], 2512 "lemon chiffon":[255, 250, 205], 2513 "lemonchiffon":[255, 250, 205], 2514 "seashell":[255, 245, 238], 2515 "honeydew":[240, 255, 240], 2516 "mint cream":[245, 255, 250], 2517 "mintcream":[245, 255, 250], 2518 "azure":[240, 255, 255], 2519 "alice blue":[240, 248, 255], 2520 "aliceblue":[240, 248, 255], 2521 "lavender":[230, 230, 250], 2522 "lavender blush":[255, 240, 245], 2523 "lavenderblush":[255, 240, 245], 2524 "misty rose":[255, 228, 225], 2525 "mistyrose":[255, 228, 225], 2526 "white":[255, 255, 255], 2527 "black":[0, 0, 0], 2528 "dark slate gray":[47, 79, 79], 2529 "darkslategray":[47, 79, 79], 2530 "dark slate grey":[47, 79, 79], 2531 "darkslategrey":[47, 79, 79], 2532 "dim gray":[105, 105, 105], 2533 "dimgray":[105, 105, 105], 2534 "dim grey":[105, 105, 105], 2535 "dimgrey":[105, 105, 105], 2536 "slate gray":[112, 128, 144], 2537 "slategray":[112, 128, 144], 2538 "slate grey":[112, 128, 144], 2539 "slategrey":[112, 128, 144], 2540 "light slate gray":[119, 136, 153], 2541 "lightslategray":[119, 136, 153], 2542 "light slate grey":[119, 136, 153], 2543 "lightslategrey":[119, 136, 153], 2544 "gray":[190, 190, 190], 2545 "grey":[190, 190, 190], 2546 "light grey":[211, 211, 211], 2547 "lightgrey":[211, 211, 211], 2548 "light gray":[211, 211, 211], 2549 "lightgray":[211, 211, 211], 2550 "midnight blue":[25, 25, 112], 2551 "midnightblue":[25, 25, 112], 2552 "navy":[0, 0, 128], 2553 "navy blue":[0, 0, 128], 2554 "navyblue":[0, 0, 128], 2555 "cornflower blue":[100, 149, 237], 2556 "cornflowerblue":[100, 149, 237], 2557 "dark slate blue":[72, 61, 139], 2558 "darkslateblue":[72, 61, 139], 2559 "slate blue":[106, 90, 205], 2560 "slateblue":[106, 90, 205], 2561 "medium slate blue":[123, 104, 238], 2562 "mediumslateblue":[123, 104, 238], 2563 "light slate blue":[132, 112, 255], 2564 "lightslateblue":[132, 112, 255], 2565 "medium blue":[0, 0, 205], 2566 "mediumblue":[0, 0, 205], 2567 "royal blue":[65, 105, 225], 2568 "royalblue":[65, 105, 225], 2569 "blue":[0, 0, 255], 2570 "dodger blue":[30, 144, 255], 2571 "dodgerblue":[30, 144, 255], 2572 "deep sky blue":[0, 191, 255], 2573 "deepskyblue":[0, 191, 255], 2574 "sky blue":[135, 206, 235], 2575 "skyblue":[135, 206, 235], 2576 "light sky blue":[135, 206, 250], 2577 "lightskyblue":[135, 206, 250], 2578 "steel blue":[70, 130, 180], 2579 "steelblue":[70, 130, 180], 2580 "light steel blue":[176, 196, 222], 2581 "lightsteelblue":[176, 196, 222], 2582 "light blue":[173, 216, 230], 2583 "lightblue":[173, 216, 230], 2584 "powder blue":[176, 224, 230], 2585 "powderblue":[176, 224, 230], 2586 "pale turquoise":[175, 238, 238], 2587 "paleturquoise":[175, 238, 238], 2588 "dark turquoise":[0, 206, 209], 2589 "darkturquoise":[0, 206, 209], 2590 "medium turquoise":[72, 209, 204], 2591 "mediumturquoise":[72, 209, 204], 2592 "turquoise":[64, 224, 208], 2593 "cyan":[0, 255, 255], 2594 "light cyan":[224, 255, 255], 2595 "lightcyan":[224, 255, 255], 2596 "cadet blue":[95, 158, 160], 2597 "cadetblue":[95, 158, 160], 2598 "medium aquamarine":[102, 205, 170], 2599 "mediumaquamarine":[102, 205, 170], 2600 "aquamarine":[127, 255, 212], 2601 "dark green":[0, 100, 0], 2602 "darkgreen":[0, 100, 0], 2603 "dark olive green":[85, 107, 47], 2604 "darkolivegreen":[85, 107, 47], 2605 "dark sea green":[143, 188, 143], 2606 "darkseagreen":[143, 188, 143], 2607 "sea green":[46, 139, 87], 2608 "seagreen":[46, 139, 87], 2609 "medium sea green":[60, 179, 113], 2610 "mediumseagreen":[60, 179, 113], 2611 "light sea green":[32, 178, 170], 2612 "lightseagreen":[32, 178, 170], 2613 "pale green":[152, 251, 152], 2614 "palegreen":[152, 251, 152], 2615 "spring green":[0, 255, 127], 2616 "springgreen":[0, 255, 127], 2617 "lawn green":[124, 252, 0], 2618 "lawngreen":[124, 252, 0], 2619 "green":[0, 255, 0], 2620 "chartreuse":[127, 255, 0], 2621 "medium spring green":[0, 250, 154], 2622 "mediumspringgreen":[0, 250, 154], 2623 "green yellow":[173, 255, 47], 2624 "greenyellow":[173, 255, 47], 2625 "lime green":[50, 205, 50], 2626 "limegreen":[50, 205, 50], 2627 "yellow green":[154, 205, 50], 2628 "yellowgreen":[154, 205, 50], 2629 "forest green":[34, 139, 34], 2630 "forestgreen":[34, 139, 34], 2631 "olive drab":[107, 142, 35], 2632 "olivedrab":[107, 142, 35], 2633 "dark khaki":[189, 183, 107], 2634 "darkkhaki":[189, 183, 107], 2635 "khaki":[240, 230, 140], 2636 "pale goldenrod":[238, 232, 170], 2637 "palegoldenrod":[238, 232, 170], 2638 "light goldenrod yellow":[250, 250, 210], 2639 "lightgoldenrodyellow":[250, 250, 210], 2640 "light yellow":[255, 255, 224], 2641 "lightyellow":[255, 255, 224], 2642 "yellow":[255, 255, 0], 2643 "gold":[255, 215, 0], 2644 "light goldenrod":[238, 221, 130], 2645 "lightgoldenrod":[238, 221, 130], 2646 "goldenrod":[218, 165, 32], 2647 "dark goldenrod":[184, 134, 11], 2648 "darkgoldenrod":[184, 134, 11], 2649 "rosy brown":[188, 143, 143], 2650 "rosybrown":[188, 143, 143], 2651 "indian red":[205, 92, 92], 2652 "indianred":[205, 92, 92], 2653 "saddle brown":[139, 69, 19], 2654 "saddlebrown":[139, 69, 19], 2655 "sienna":[160, 82, 45], 2656 "peru":[205, 133, 63], 2657 "burlywood":[222, 184, 135], 2658 "beige":[245, 245, 220], 2659 "wheat":[245, 222, 179], 2660 "sandy brown":[244, 164, 96], 2661 "sandybrown":[244, 164, 96], 2662 "tan":[210, 180, 140], 2663 "chocolate":[210, 105, 30], 2664 "firebrick":[178, 34, 34], 2665 "brown":[165, 42, 42], 2666 "dark salmon":[233, 150, 122], 2667 "darksalmon":[233, 150, 122], 2668 "salmon":[250, 128, 114], 2669 "light salmon":[255, 160, 122], 2670 "lightsalmon":[255, 160, 122], 2671 "orange":[255, 165, 0], 2672 "dark orange":[255, 140, 0], 2673 "darkorange":[255, 140, 0], 2674 "coral":[255, 127, 80], 2675 "light coral":[240, 128, 128], 2676 "lightcoral":[240, 128, 128], 2677 "tomato":[255, 99, 71], 2678 "orange red":[255, 69, 0], 2679 "orangered":[255, 69, 0], 2680 "red":[255, 0, 0], 2681 "hot pink":[255, 105, 180], 2682 "hotpink":[255, 105, 180], 2683 "deep pink":[255, 20, 147], 2684 "deeppink":[255, 20, 147], 2685 "pink":[255, 192, 203], 2686 "light pink":[255, 182, 193], 2687 "lightpink":[255, 182, 193], 2688 "pale violet red":[219, 112, 147], 2689 "palevioletred":[219, 112, 147], 2690 "maroon":[176, 48, 96], 2691 "medium violet red":[199, 21, 133], 2692 "mediumvioletred":[199, 21, 133], 2693 "violet red":[208, 32, 144], 2694 "violetred":[208, 32, 144], 2695 "magenta":[255, 0, 255], 2696 "violet":[238, 130, 238], 2697 "plum":[221, 160, 221], 2698 "orchid":[218, 112, 214], 2699 "medium orchid":[186, 85, 211], 2700 "mediumorchid":[186, 85, 211], 2701 "dark orchid":[153, 50, 204], 2702 "darkorchid":[153, 50, 204], 2703 "dark violet":[148, 0, 211], 2704 "darkviolet":[148, 0, 211], 2705 "blue violet":[138, 43, 226], 2706 "blueviolet":[138, 43, 226], 2707 "purple":[160, 32, 240], 2708 "medium purple":[147, 112, 219], 2709 "mediumpurple":[147, 112, 219], 2710 "thistle":[216, 191, 216], 2711 "snow1":[255, 250, 250], 2712 "snow2":[238, 233, 233], 2713 "snow3":[205, 201, 201], 2714 "snow4":[139, 137, 137], 2715 "seashell1":[255, 245, 238], 2716 "seashell2":[238, 229, 222], 2717 "seashell3":[205, 197, 191], 2718 "seashell4":[139, 134, 130], 2719 "antiquewhite1":[255, 239, 219], 2720 "antiquewhite2":[238, 223, 204], 2721 "antiquewhite3":[205, 192, 176], 2722 "antiquewhite4":[139, 131, 120], 2723 "bisque1":[255, 228, 196], 2724 "bisque2":[238, 213, 183], 2725 "bisque3":[205, 183, 158], 2726 "bisque4":[139, 125, 107], 2727 "peachpuff1":[255, 218, 185], 2728 "peachpuff2":[238, 203, 173], 2729 "peachpuff3":[205, 175, 149], 2730 "peachpuff4":[139, 119, 101], 2731 "navajowhite1":[255, 222, 173], 2732 "navajowhite2":[238, 207, 161], 2733 "navajowhite3":[205, 179, 139], 2734 "navajowhite4":[139, 121, 94], 2735 "lemonchiffon1":[255, 250, 205], 2736 "lemonchiffon2":[238, 233, 191], 2737 "lemonchiffon3":[205, 201, 165], 2738 "lemonchiffon4":[139, 137, 112], 2739 "cornsilk1":[255, 248, 220], 2740 "cornsilk2":[238, 232, 205], 2741 "cornsilk3":[205, 200, 177], 2742 "cornsilk4":[139, 136, 120], 2743 "ivory1":[255, 255, 240], 2744 "ivory2":[238, 238, 224], 2745 "ivory3":[205, 205, 193], 2746 "ivory4":[139, 139, 131], 2747 "honeydew1":[240, 255, 240], 2748 "honeydew2":[224, 238, 224], 2749 "honeydew3":[193, 205, 193], 2750 "honeydew4":[131, 139, 131], 2751 "lavenderblush1":[255, 240, 245], 2752 "lavenderblush2":[238, 224, 229], 2753 "lavenderblush3":[205, 193, 197], 2754 "lavenderblush4":[139, 131, 134], 2755 "mistyrose1":[255, 228, 225], 2756 "mistyrose2":[238, 213, 210], 2757 "mistyrose3":[205, 183, 181], 2758 "mistyrose4":[139, 125, 123], 2759 "azure1":[240, 255, 255], 2760 "azure2":[224, 238, 238], 2761 "azure3":[193, 205, 205], 2762 "azure4":[131, 139, 139], 2763 "slateblue1":[131, 111, 255], 2764 "slateblue2":[122, 103, 238], 2765 "slateblue3":[105, 89, 205], 2766 "slateblue4":[71, 60, 139], 2767 "royalblue1":[72, 118, 255], 2768 "royalblue2":[67, 110, 238], 2769 "royalblue3":[58, 95, 205], 2770 "royalblue4":[39, 64, 139], 2771 "blue1":[0, 0, 255], 2772 "blue2":[0, 0, 238], 2773 "blue3":[0, 0, 205], 2774 "blue4":[0, 0, 139], 2775 "dodgerblue1":[30, 144, 255], 2776 "dodgerblue2":[28, 134, 238], 2777 "dodgerblue3":[24, 116, 205], 2778 "dodgerblue4":[16, 78, 139], 2779 "steelblue1":[99, 184, 255], 2780 "steelblue2":[92, 172, 238], 2781 "steelblue3":[79, 148, 205], 2782 "steelblue4":[54, 100, 139], 2783 "deepskyblue1":[0, 191, 255], 2784 "deepskyblue2":[0, 178, 238], 2785 "deepskyblue3":[0, 154, 205], 2786 "deepskyblue4":[0, 104, 139], 2787 "skyblue1":[135, 206, 255], 2788 "skyblue2":[126, 192, 238], 2789 "skyblue3":[108, 166, 205], 2790 "skyblue4":[74, 112, 139], 2791 "lightskyblue1":[176, 226, 255], 2792 "lightskyblue2":[164, 211, 238], 2793 "lightskyblue3":[141, 182, 205], 2794 "lightskyblue4":[96, 123, 139], 2795 "slategray1":[198, 226, 255], 2796 "slategray2":[185, 211, 238], 2797 "slategray3":[159, 182, 205], 2798 "slategray4":[108, 123, 139], 2799 "lightsteelblue1":[202, 225, 255], 2800 "lightsteelblue2":[188, 210, 238], 2801 "lightsteelblue3":[162, 181, 205], 2802 "lightsteelblue4":[110, 123, 139], 2803 "lightblue1":[191, 239, 255], 2804 "lightblue2":[178, 223, 238], 2805 "lightblue3":[154, 192, 205], 2806 "lightblue4":[104, 131, 139], 2807 "lightcyan1":[224, 255, 255], 2808 "lightcyan2":[209, 238, 238], 2809 "lightcyan3":[180, 205, 205], 2810 "lightcyan4":[122, 139, 139], 2811 "paleturquoise1":[187, 255, 255], 2812 "paleturquoise2":[174, 238, 238], 2813 "paleturquoise3":[150, 205, 205], 2814 "paleturquoise4":[102, 139, 139], 2815 "cadetblue1":[152, 245, 255], 2816 "cadetblue2":[142, 229, 238], 2817 "cadetblue3":[122, 197, 205], 2818 "cadetblue4":[83, 134, 139], 2819 "turquoise1":[0, 245, 255], 2820 "turquoise2":[0, 229, 238], 2821 "turquoise3":[0, 197, 205], 2822 "turquoise4":[0, 134, 139], 2823 "cyan1":[0, 255, 255], 2824 "cyan2":[0, 238, 238], 2825 "cyan3":[0, 205, 205], 2826 "cyan4":[0, 139, 139], 2827 "darkslategray1":[151, 255, 255], 2828 "darkslategray2":[141, 238, 238], 2829 "darkslategray3":[121, 205, 205], 2830 "darkslategray4":[82, 139, 139], 2831 "aquamarine1":[127, 255, 212], 2832 "aquamarine2":[118, 238, 198], 2833 "aquamarine3":[102, 205, 170], 2834 "aquamarine4":[69, 139, 116], 2835 "darkseagreen1":[193, 255, 193], 2836 "darkseagreen2":[180, 238, 180], 2837 "darkseagreen3":[155, 205, 155], 2838 "darkseagreen4":[105, 139, 105], 2839 "seagreen1":[84, 255, 159], 2840 "seagreen2":[78, 238, 148], 2841 "seagreen3":[67, 205, 128], 2842 "seagreen4":[46, 139, 87], 2843 "palegreen1":[154, 255, 154], 2844 "palegreen2":[144, 238, 144], 2845 "palegreen3":[124, 205, 124], 2846 "palegreen4":[84, 139, 84], 2847 "springgreen1":[0, 255, 127], 2848 "springgreen2":[0, 238, 118], 2849 "springgreen3":[0, 205, 102], 2850 "springgreen4":[0, 139, 69], 2851 "green1":[0, 255, 0], 2852 "green2":[0, 238, 0], 2853 "green3":[0, 205, 0], 2854 "green4":[0, 139, 0], 2855 "chartreuse1":[127, 255, 0], 2856 "chartreuse2":[118, 238, 0], 2857 "chartreuse3":[102, 205, 0], 2858 "chartreuse4":[69, 139, 0], 2859 "olivedrab1":[192, 255, 62], 2860 "olivedrab2":[179, 238, 58], 2861 "olivedrab3":[154, 205, 50], 2862 "olivedrab4":[105, 139, 34], 2863 "darkolivegreen1":[202, 255, 112], 2864 "darkolivegreen2":[188, 238, 104], 2865 "darkolivegreen3":[162, 205, 90], 2866 "darkolivegreen4":[110, 139, 61], 2867 "khaki1":[255, 246, 143], 2868 "khaki2":[238, 230, 133], 2869 "khaki3":[205, 198, 115], 2870 "khaki4":[139, 134, 78], 2871 "lightgoldenrod1":[255, 236, 139], 2872 "lightgoldenrod2":[238, 220, 130], 2873 "lightgoldenrod3":[205, 190, 112], 2874 "lightgoldenrod4":[139, 129, 76], 2875 "lightyellow1":[255, 255, 224], 2876 "lightyellow2":[238, 238, 209], 2877 "lightyellow3":[205, 205, 180], 2878 "lightyellow4":[139, 139, 122], 2879 "yellow1":[255, 255, 0], 2880 "yellow2":[238, 238, 0], 2881 "yellow3":[205, 205, 0], 2882 "yellow4":[139, 139, 0], 2883 "gold1":[255, 215, 0], 2884 "gold2":[238, 201, 0], 2885 "gold3":[205, 173, 0], 2886 "gold4":[139, 117, 0], 2887 "goldenrod1":[255, 193, 37], 2888 "goldenrod2":[238, 180, 34], 2889 "goldenrod3":[205, 155, 29], 2890 "goldenrod4":[139, 105, 20], 2891 "darkgoldenrod1":[255, 185, 15], 2892 "darkgoldenrod2":[238, 173, 14], 2893 "darkgoldenrod3":[205, 149, 12], 2894 "darkgoldenrod4":[139, 101, 8], 2895 "rosybrown1":[255, 193, 193], 2896 "rosybrown2":[238, 180, 180], 2897 "rosybrown3":[205, 155, 155], 2898 "rosybrown4":[139, 105, 105], 2899 "indianred1":[255, 106, 106], 2900 "indianred2":[238, 99, 99], 2901 "indianred3":[205, 85, 85], 2902 "indianred4":[139, 58, 58], 2903 "sienna1":[255, 130, 71], 2904 "sienna2":[238, 121, 66], 2905 "sienna3":[205, 104, 57], 2906 "sienna4":[139, 71, 38], 2907 "burlywood1":[255, 211, 155], 2908 "burlywood2":[238, 197, 145], 2909 "burlywood3":[205, 170, 125], 2910 "burlywood4":[139, 115, 85], 2911 "wheat1":[255, 231, 186], 2912 "wheat2":[238, 216, 174], 2913 "wheat3":[205, 186, 150], 2914 "wheat4":[139, 126, 102], 2915 "tan1":[255, 165, 79], 2916 "tan2":[238, 154, 73], 2917 "tan3":[205, 133, 63], 2918 "tan4":[139, 90, 43], 2919 "chocolate1":[255, 127, 36], 2920 "chocolate2":[238, 118, 33], 2921 "chocolate3":[205, 102, 29], 2922 "chocolate4":[139, 69, 19], 2923 "firebrick1":[255, 48, 48], 2924 "firebrick2":[238, 44, 44], 2925 "firebrick3":[205, 38, 38], 2926 "firebrick4":[139, 26, 26], 2927 "brown1":[255, 64, 64], 2928 "brown2":[238, 59, 59], 2929 "brown3":[205, 51, 51], 2930 "brown4":[139, 35, 35], 2931 "salmon1":[255, 140, 105], 2932 "salmon2":[238, 130, 98], 2933 "salmon3":[205, 112, 84], 2934 "salmon4":[139, 76, 57], 2935 "lightsalmon1":[255, 160, 122], 2936 "lightsalmon2":[238, 149, 114], 2937 "lightsalmon3":[205, 129, 98], 2938 "lightsalmon4":[139, 87, 66], 2939 "orange1":[255, 165, 0], 2940 "orange2":[238, 154, 0], 2941 "orange3":[205, 133, 0], 2942 "orange4":[139, 90, 0], 2943 "darkorange1":[255, 127, 0], 2944 "darkorange2":[238, 118, 0], 2945 "darkorange3":[205, 102, 0], 2946 "darkorange4":[139, 69, 0], 2947 "coral1":[255, 114, 86], 2948 "coral2":[238, 106, 80], 2949 "coral3":[205, 91, 69], 2950 "coral4":[139, 62, 47], 2951 "tomato1":[255, 99, 71], 2952 "tomato2":[238, 92, 66], 2953 "tomato3":[205, 79, 57], 2954 "tomato4":[139, 54, 38], 2955 "orangered1":[255, 69, 0], 2956 "orangered2":[238, 64, 0], 2957 "orangered3":[205, 55, 0], 2958 "orangered4":[139, 37, 0], 2959 "red1":[255, 0, 0], 2960 "red2":[238, 0, 0], 2961 "red3":[205, 0, 0], 2962 "red4":[139, 0, 0], 2963 "deeppink1":[255, 20, 147], 2964 "deeppink2":[238, 18, 137], 2965 "deeppink3":[205, 16, 118], 2966 "deeppink4":[139, 10, 80], 2967 "hotpink1":[255, 110, 180], 2968 "hotpink2":[238, 106, 167], 2969 "hotpink3":[205, 96, 144], 2970 "hotpink4":[139, 58, 98], 2971 "pink1":[255, 181, 197], 2972 "pink2":[238, 169, 184], 2973 "pink3":[205, 145, 158], 2974 "pink4":[139, 99, 108], 2975 "lightpink1":[255, 174, 185], 2976 "lightpink2":[238, 162, 173], 2977 "lightpink3":[205, 140, 149], 2978 "lightpink4":[139, 95, 101], 2979 "palevioletred1":[255, 130, 171], 2980 "palevioletred2":[238, 121, 159], 2981 "palevioletred3":[205, 104, 137], 2982 "palevioletred4":[139, 71, 93], 2983 "maroon1":[255, 52, 179], 2984 "maroon2":[238, 48, 167], 2985 "maroon3":[205, 41, 144], 2986 "maroon4":[139, 28, 98], 2987 "violetred1":[255, 62, 150], 2988 "violetred2":[238, 58, 140], 2989 "violetred3":[205, 50, 120], 2990 "violetred4":[139, 34, 82], 2991 "magenta1":[255, 0, 255], 2992 "magenta2":[238, 0, 238], 2993 "magenta3":[205, 0, 205], 2994 "magenta4":[139, 0, 139], 2995 "orchid1":[255, 131, 250], 2996 "orchid2":[238, 122, 233], 2997 "orchid3":[205, 105, 201], 2998 "orchid4":[139, 71, 137], 2999 "plum1":[255, 187, 255], 3000 "plum2":[238, 174, 238], 3001 "plum3":[205, 150, 205], 3002 "plum4":[139, 102, 139], 3003 "mediumorchid1":[224, 102, 255], 3004 "mediumorchid2":[209, 95, 238], 3005 "mediumorchid3":[180, 82, 205], 3006 "mediumorchid4":[122, 55, 139], 3007 "darkorchid1":[191, 62, 255], 3008 "darkorchid2":[178, 58, 238], 3009 "darkorchid3":[154, 50, 205], 3010 "darkorchid4":[104, 34, 139], 3011 "purple1":[155, 48, 255], 3012 "purple2":[145, 44, 238], 3013 "purple3":[125, 38, 205], 3014 "purple4":[85, 26, 139], 3015 "mediumpurple1":[171, 130, 255], 3016 "mediumpurple2":[159, 121, 238], 3017 "mediumpurple3":[137, 104, 205], 3018 "mediumpurple4":[93, 71, 139], 3019 "thistle1":[255, 225, 255], 3020 "thistle2":[238, 210, 238], 3021 "thistle3":[205, 181, 205], 3022 "thistle4":[139, 123, 139], 3023 "gray0":[0, 0, 0], 3024 "grey0":[0, 0, 0], 3025 "gray1":[3, 3, 3], 3026 "grey1":[3, 3, 3], 3027 "gray2":[5, 5, 5], 3028 "grey2":[5, 5, 5], 3029 "gray3":[8, 8, 8], 3030 "grey3":[8, 8, 8], 3031 "gray4":[10, 10, 10], 3032 "grey4":[10, 10, 10], 3033 "gray5":[13, 13, 13], 3034 "grey5":[13, 13, 13], 3035 "gray6":[15, 15, 15], 3036 "grey6":[15, 15, 15], 3037 "gray7":[18, 18, 18], 3038 "grey7":[18, 18, 18], 3039 "gray8":[20, 20, 20], 3040 "grey8":[20, 20, 20], 3041 "gray9":[23, 23, 23], 3042 "grey9":[23, 23, 23], 3043 "gray10":[26, 26, 26], 3044 "grey10":[26, 26, 26], 3045 "gray11":[28, 28, 28], 3046 "grey11":[28, 28, 28], 3047 "gray12":[31, 31, 31], 3048 "grey12":[31, 31, 31], 3049 "gray13":[33, 33, 33], 3050 "grey13":[33, 33, 33], 3051 "gray14":[36, 36, 36], 3052 "grey14":[36, 36, 36], 3053 "gray15":[38, 38, 38], 3054 "grey15":[38, 38, 38], 3055 "gray16":[41, 41, 41], 3056 "grey16":[41, 41, 41], 3057 "gray17":[43, 43, 43], 3058 "grey17":[43, 43, 43], 3059 "gray18":[46, 46, 46], 3060 "grey18":[46, 46, 46], 3061 "gray19":[48, 48, 48], 3062 "grey19":[48, 48, 48], 3063 "gray20":[51, 51, 51], 3064 "grey20":[51, 51, 51], 3065 "gray21":[54, 54, 54], 3066 "grey21":[54, 54, 54], 3067 "gray22":[56, 56, 56], 3068 "grey22":[56, 56, 56], 3069 "gray23":[59, 59, 59], 3070 "grey23":[59, 59, 59], 3071 "gray24":[61, 61, 61], 3072 "grey24":[61, 61, 61], 3073 "gray25":[64, 64, 64], 3074 "grey25":[64, 64, 64], 3075 "gray26":[66, 66, 66], 3076 "grey26":[66, 66, 66], 3077 "gray27":[69, 69, 69], 3078 "grey27":[69, 69, 69], 3079 "gray28":[71, 71, 71], 3080 "grey28":[71, 71, 71], 3081 "gray29":[74, 74, 74], 3082 "grey29":[74, 74, 74], 3083 "gray30":[77, 77, 77], 3084 "grey30":[77, 77, 77], 3085 "gray31":[79, 79, 79], 3086 "grey31":[79, 79, 79], 3087 "gray32":[82, 82, 82], 3088 "grey32":[82, 82, 82], 3089 "gray33":[84, 84, 84], 3090 "grey33":[84, 84, 84], 3091 "gray34":[87, 87, 87], 3092 "grey34":[87, 87, 87], 3093 "gray35":[89, 89, 89], 3094 "grey35":[89, 89, 89], 3095 "gray36":[92, 92, 92], 3096 "grey36":[92, 92, 92], 3097 "gray37":[94, 94, 94], 3098 "grey37":[94, 94, 94], 3099 "gray38":[97, 97, 97], 3100 "grey38":[97, 97, 97], 3101 "gray39":[99, 99, 99], 3102 "grey39":[99, 99, 99], 3103 "gray40":[102, 102, 102], 3104 "grey40":[102, 102, 102], 3105 "gray41":[105, 105, 105], 3106 "grey41":[105, 105, 105], 3107 "gray42":[107, 107, 107], 3108 "grey42":[107, 107, 107], 3109 "gray43":[110, 110, 110], 3110 "grey43":[110, 110, 110], 3111 "gray44":[112, 112, 112], 3112 "grey44":[112, 112, 112], 3113 "gray45":[115, 115, 115], 3114 "grey45":[115, 115, 115], 3115 "gray46":[117, 117, 117], 3116 "grey46":[117, 117, 117], 3117 "gray47":[120, 120, 120], 3118 "grey47":[120, 120, 120], 3119 "gray48":[122, 122, 122], 3120 "grey48":[122, 122, 122], 3121 "gray49":[125, 125, 125], 3122 "grey49":[125, 125, 125], 3123 "gray50":[127, 127, 127], 3124 "grey50":[127, 127, 127], 3125 "gray51":[130, 130, 130], 3126 "grey51":[130, 130, 130], 3127 "gray52":[133, 133, 133], 3128 "grey52":[133, 133, 133], 3129 "gray53":[135, 135, 135], 3130 "grey53":[135, 135, 135], 3131 "gray54":[138, 138, 138], 3132 "grey54":[138, 138, 138], 3133 "gray55":[140, 140, 140], 3134 "grey55":[140, 140, 140], 3135 "gray56":[143, 143, 143], 3136 "grey56":[143, 143, 143], 3137 "gray57":[145, 145, 145], 3138 "grey57":[145, 145, 145], 3139 "gray58":[148, 148, 148], 3140 "grey58":[148, 148, 148], 3141 "gray59":[150, 150, 150], 3142 "grey59":[150, 150, 150], 3143 "gray60":[153, 153, 153], 3144 "grey60":[153, 153, 153], 3145 "gray61":[156, 156, 156], 3146 "grey61":[156, 156, 156], 3147 "gray62":[158, 158, 158], 3148 "grey62":[158, 158, 158], 3149 "gray63":[161, 161, 161], 3150 "grey63":[161, 161, 161], 3151 "gray64":[163, 163, 163], 3152 "grey64":[163, 163, 163], 3153 "gray65":[166, 166, 166], 3154 "grey65":[166, 166, 166], 3155 "gray66":[168, 168, 168], 3156 "grey66":[168, 168, 168], 3157 "gray67":[171, 171, 171], 3158 "grey67":[171, 171, 171], 3159 "gray68":[173, 173, 173], 3160 "grey68":[173, 173, 173], 3161 "gray69":[176, 176, 176], 3162 "grey69":[176, 176, 176], 3163 "gray70":[179, 179, 179], 3164 "grey70":[179, 179, 179], 3165 "gray71":[181, 181, 181], 3166 "grey71":[181, 181, 181], 3167 "gray72":[184, 184, 184], 3168 "grey72":[184, 184, 184], 3169 "gray73":[186, 186, 186], 3170 "grey73":[186, 186, 186], 3171 "gray74":[189, 189, 189], 3172 "grey74":[189, 189, 189], 3173 "gray75":[191, 191, 191], 3174 "grey75":[191, 191, 191], 3175 "gray76":[194, 194, 194], 3176 "grey76":[194, 194, 194], 3177 "gray77":[196, 196, 196], 3178 "grey77":[196, 196, 196], 3179 "gray78":[199, 199, 199], 3180 "grey78":[199, 199, 199], 3181 "gray79":[201, 201, 201], 3182 "grey79":[201, 201, 201], 3183 "gray80":[204, 204, 204], 3184 "grey80":[204, 204, 204], 3185 "gray81":[207, 207, 207], 3186 "grey81":[207, 207, 207], 3187 "gray82":[209, 209, 209], 3188 "grey82":[209, 209, 209], 3189 "gray83":[212, 212, 212], 3190 "grey83":[212, 212, 212], 3191 "gray84":[214, 214, 214], 3192 "grey84":[214, 214, 214], 3193 "gray85":[217, 217, 217], 3194 "grey85":[217, 217, 217], 3195 "gray86":[219, 219, 219], 3196 "grey86":[219, 219, 219], 3197 "gray87":[222, 222, 222], 3198 "grey87":[222, 222, 222], 3199 "gray88":[224, 224, 224], 3200 "grey88":[224, 224, 224], 3201 "gray89":[227, 227, 227], 3202 "grey89":[227, 227, 227], 3203 "gray90":[229, 229, 229], 3204 "grey90":[229, 229, 229], 3205 "gray91":[232, 232, 232], 3206 "grey91":[232, 232, 232], 3207 "gray92":[235, 235, 235], 3208 "grey92":[235, 235, 235], 3209 "gray93":[237, 237, 237], 3210 "grey93":[237, 237, 237], 3211 "gray94":[240, 240, 240], 3212 "grey94":[240, 240, 240], 3213 "gray95":[242, 242, 242], 3214 "grey95":[242, 242, 242], 3215 "gray96":[245, 245, 245], 3216 "grey96":[245, 245, 245], 3217 "gray97":[247, 247, 247], 3218 "grey97":[247, 247, 247], 3219 "gray98":[250, 250, 250], 3220 "grey98":[250, 250, 250], 3221 "gray99":[252, 252, 252], 3222 "grey99":[252, 252, 252], 3223 "gray100":[255, 255, 255], 3224 "grey100":[255, 255, 255], 3225 "dark grey":[169, 169, 169], 3226 "darkgrey":[169, 169, 169], 3227 "dark gray":[169, 169, 169], 3228 "darkgray":[169, 169, 169], 3229 "dark blue":[0, 0, 139], 3230 "darkblue":[0, 0, 139], 3231 "dark cyan":[0, 139, 139], 3232 "darkcyan":[0, 139, 139], 3233 "dark magenta":[139, 0, 139], 3234 "darkmagenta":[139, 0, 139], 3235 "dark red":[139, 0, 0], 3236 "darkred":[139, 0, 0], 3237 "light green":[144, 238, 144], 3238 "lightgreen":[144, 238, 144], 3239 "olive":[128, 128, 0], 3240 "teal":[0, 128, 128]} 3241 3242 3243 # ------------- Key constants ------------------------------- 3244 3245 ''' 3246 The key names used by Qt. 3247 Constant Value Description 3248 3249 Qt.Key_Escape 0x01000000 3250 3251 Qt.Key_Tab 0x01000001 3252 3253 Qt.Key_Backtab 0x01000002 3254 3255 Qt.Key_Backspace 0x01000003 3256 3257 Qt.Key_Return 0x01000004 3258 3259 Qt.Key_Enter 0x01000005 Typically located on the keypad. 3260 3261 Qt.Key_Insert 0x01000006 3262 3263 Qt.Key_Delete 0x01000007 3264 3265 Qt.Key_Pause 0x01000008 The Pause/Break key (Note: Not anything to do with pausing media) 3266 3267 Qt.Key_Print 0x01000009 3268 3269 Qt.Key_SysReq 0x0100000a 3270 3271 Qt.Key_Clear 0x0100000b 3272 3273 Qt.Key_Home 0x01000010 3274 3275 Qt.Key_End 0x01000011 3276 3277 Qt.Key_Left 0x01000012 3278 3279 Qt.Key_Up 0x01000013 3280 3281 Qt.Key_Right 0x01000014 3282 3283 Qt.Key_Down 0x01000015 3284 3285 Qt.Key_PageUp 0x01000016 3286 3287 Qt.Key_PageDown 0x01000017 3288 3289 Qt.Key_Shift 0x01000020 3290 3291 Qt.Key_Control 0x01000021 On Mac OS X, this corresponds to the Command keys. 3292 3293 Qt.Key_Meta 0x01000022 On Mac OS X, this corresponds to the Control keys. On Windows keyboards, this key is mapped to the Windows key. 3294 3295 Qt.Key_Alt 0x01000023 3296 3297 Qt.Key_AltGr 0x01001103 On Windows, when the KeyDown event for this key is sent, the Ctrl+Alt modifiers are also set. 3298 3299 Qt.Key_CapsLock 0x01000024 3300 3301 Qt.Key_NumLock 0x01000025 3302 3303 Qt.Key_ScrollLock 0x01000026 3304 3305 Qt.Key_F1 0x01000030 3306 3307 Qt.Key_F2 0x01000031 3308 3309 Qt.Key_F3 0x01000032 3310 3311 Qt.Key_F4 0x01000033 3312 3313 Qt.Key_F5 0x01000034 3314 3315 Qt.Key_F6 0x01000035 3316 3317 Qt.Key_F7 0x01000036 3318 3319 Qt.Key_F8 0x01000037 3320 3321 Qt.Key_F9 0x01000038 3322 3323 Qt.Key_F10 0x01000039 3324 3325 Qt.Key_F11 0x0100003a 3326 3327 Qt.Key_F12 0x0100003b 3328 3329 Qt.Key_F13 0x0100003c 3330 3331 Qt.Key_F14 0x0100003d 3332 3333 Qt.Key_F15 0x0100003e 3334 3335 Qt.Key_F16 0x0100003f 3336 3337 Qt.Key_F17 0x01000040 3338 3339 Qt.Key_F18 0x01000041 3340 3341 Qt.Key_F19 0x01000042 3342 3343 Qt.Key_F20 0x01000043 3344 3345 Qt.Key_F21 0x01000044 3346 3347 Qt.Key_F22 0x01000045 3348 3349 Qt.Key_F23 0x01000046 3350 3351 Qt.Key_F24 0x01000047 3352 3353 Qt.Key_F25 0x01000048 3354 3355 Qt.Key_F26 0x01000049 3356 3357 Qt.Key_F27 0x0100004a 3358 3359 Qt.Key_F28 0x0100004b 3360 3361 Qt.Key_F29 0x0100004c 3362 3363 Qt.Key_F30 0x0100004d 3364 3365 Qt.Key_F31 0x0100004e 3366 3367 Qt.Key_F32 0x0100004f 3368 3369 Qt.Key_F33 0x01000050 3370 3371 Qt.Key_F34 0x01000051 3372 3373 Qt.Key_F35 0x01000052 3374 3375 Qt.Key_Super_L 0x01000053 3376 3377 Qt.Key_Super_R 0x01000054 3378 3379 Qt.Key_Menu 0x01000055 3380 3381 Qt.Key_Hyper_L 0x01000056 3382 3383 Qt.Key_Hyper_R 0x01000057 3384 3385 Qt.Key_Help 0x01000058 3386 3387 Qt.Key_Direction_L 0x01000059 3388 3389 Qt.Key_Direction_R 0x01000060 3390 3391 Qt.Key_Space 0x20 3392 3393 Qt.Key_Any Key_Space 3394 3395 Qt.Key_Exclam 0x21 3396 3397 Qt.Key_QuoteDbl 0x22 3398 3399 Qt.Key_NumberSign 0x23 3400 3401 Qt.Key_Dollar 0x24 3402 3403 Qt.Key_Percent 0x25 3404 3405 Qt.Key_Ampersand 0x26 3406 3407 Qt.Key_Apostrophe 0x27 3408 3409 Qt.Key_ParenLeft 0x28 3410 3411 Qt.Key_ParenRight 0x29 3412 3413 Qt.Key_Asterisk 0x2a 3414 3415 Qt.Key_Plus 0x2b 3416 3417 Qt.Key_Comma 0x2c 3418 3419 Qt.Key_Minus 0x2d 3420 3421 Qt.Key_Period 0x2e 3422 3423 Qt.Key_Slash 0x2f 3424 3425 Qt.Key_0 0x30 3426 3427 Qt.Key_1 0x31 3428 3429 Qt.Key_2 0x32 3430 3431 Qt.Key_3 0x33 3432 3433 Qt.Key_4 0x34 3434 3435 Qt.Key_5 0x35 3436 3437 Qt.Key_6 0x36 3438 3439 Qt.Key_7 0x37 3440 3441 Qt.Key_8 0x38 3442 3443 Qt.Key_9 0x39 3444 3445 Qt.Key_Colon 0x3a 3446 3447 Qt.Key_Semicolon 0x3b 3448 3449 Qt.Key_Less 0x3c 3450 3451 Qt.Key_Equal 0x3d 3452 3453 Qt.Key_Greater 0x3e 3454 3455 Qt.Key_Question 0x3f 3456 3457 Qt.Key_At 0x40 3458 3459 Qt.Key_A 0x41 3460 3461 Qt.Key_B 0x42 3462 3463 Qt.Key_C 0x43 3464 3465 Qt.Key_D 0x44 3466 3467 Qt.Key_E 0x45 3468 3469 Qt.Key_F 0x46 3470 3471 Qt.Key_G 0x47 3472 3473 Qt.Key_H 0x48 3474 3475 Qt.Key_I 0x49 3476 3477 Qt.Key_J 0x4a 3478 3479 Qt.Key_K 0x4b 3480 3481 Qt.Key_L 0x4c 3482 3483 Qt.Key_M 0x4d 3484 3485 Qt.Key_N 0x4e 3486 3487 Qt.Key_O 0x4f 3488 3489 Qt.Key_P 0x50 3490 3491 Qt.Key_Q 0x51 3492 3493 Qt.Key_R 0x52 3494 3495 Qt.Key_S 0x53 3496 3497 Qt.Key_T 0x54 3498 3499 Qt.Key_U 0x55 3500 3501 Qt.Key_V 0x56 3502 3503 Qt.Key_W 0x57 3504 3505 Qt.Key_X 0x58 3506 3507 Qt.Key_Y 0x59 3508 3509 Qt.Key_Z 0x5a 3510 3511 Qt.Key_BracketLeft 0x5b 3512 3513 Qt.Key_Backslash 0x5c 3514 3515 Qt.Key_BracketRight 0x5d 3516 3517 Qt.Key_AsciiCircum 0x5e 3518 3519 Qt.Key_Underscore 0x5f 3520 3521 Qt.Key_QuoteLeft 0x60 3522 3523 Qt.Key_BraceLeft 0x7b 3524 3525 Qt.Key_Bar 0x7c 3526 3527 Qt.Key_BraceRight 0x7d 3528 3529 Qt.Key_AsciiTilde 0x7e 3530 3531 Qt.Key_nobreakspace 0x0a0 3532 3533 Qt.Key_exclamdown 0x0a1 3534 3535 Qt.Key_cent 0x0a2 3536 3537 Qt.Key_sterling 0x0a3 3538 3539 Qt.Key_currency 0x0a4 3540 3541 Qt.Key_yen 0x0a5 3542 3543 Qt.Key_brokenbar 0x0a6 3544 3545 Qt.Key_section 0x0a7 3546 3547 Qt.Key_diaeresis 0x0a8 3548 3549 Qt.Key_copyright 0x0a9 3550 3551 Qt.Key_ordfeminine 0x0aa 3552 3553 Qt.Key_guillemotleft 0x0ab 3554 3555 Qt.Key_notsign 0x0ac 3556 3557 Qt.Key_hyphen 0x0ad 3558 3559 Qt.Key_registered 0x0ae 3560 3561 Qt.Key_macron 0x0af 3562 3563 Qt.Key_degree 0x0b0 3564 3565 Qt.Key_plusminus 0x0b1 3566 3567 Qt.Key_twosuperior 0x0b2 3568 3569 Qt.Key_threesuperior 0x0b3 3570 3571 Qt.Key_acute 0x0b4 3572 3573 Qt.Key_mu 0x0b5 3574 3575 Qt.Key_paragraph 0x0b6 3576 3577 Qt.Key_periodcentered 0x0b7 3578 3579 Qt.Key_cedilla 0x0b8 3580 3581 Qt.Key_onesuperior 0x0b9 3582 3583 Qt.Key_masculine 0x0ba 3584 3585 Qt.Key_guillemotright 0x0bb 3586 3587 Qt.Key_onequarter 0x0bc 3588 3589 Qt.Key_onehalf 0x0bd 3590 3591 Qt.Key_threequarters 0x0be 3592 3593 Qt.Key_questiondown 0x0bf 3594 3595 Qt.Key_Agrave 0x0c0 3596 3597 Qt.Key_Aacute 0x0c1 3598 3599 Qt.Key_Acircumflex 0x0c2 3600 3601 Qt.Key_Atilde 0x0c3 3602 3603 Qt.Key_Adiaeresis 0x0c4 3604 3605 Qt.Key_Aring 0x0c5 3606 3607 Qt.Key_AE 0x0c6 3608 3609 Qt.Key_Ccedilla 0x0c7 3610 3611 Qt.Key_Egrave 0x0c8 3612 3613 Qt.Key_Eacute 0x0c9 3614 3615 Qt.Key_Ecircumflex 0x0ca 3616 3617 Qt.Key_Ediaeresis 0x0cb 3618 3619 Qt.Key_Igrave 0x0cc 3620 3621 Qt.Key_Iacute 0x0cd 3622 3623 Qt.Key_Icircumflex 0x0ce 3624 3625 Qt.Key_Idiaeresis 0x0cf 3626 3627 Qt.Key_ETH 0x0d0 3628 3629 Qt.Key_Ntilde 0x0d1 3630 3631 Qt.Key_Ograve 0x0d2 3632 3633 Qt.Key_Oacute 0x0d3 3634 3635 Qt.Key_Ocircumflex 0x0d4 3636 3637 Qt.Key_Otilde 0x0d5 3638 3639 Qt.Key_Odiaeresis 0x0d6 3640 3641 Qt.Key_multiply 0x0d7 3642 3643 Qt.Key_Ooblique 0x0d8 3644 3645 Qt.Key_Ugrave 0x0d9 3646 3647 Qt.Key_Uacute 0x0da 3648 3649 Qt.Key_Ucircumflex 0x0db 3650 3651 Qt.Key_Udiaeresis 0x0dc 3652 3653 Qt.Key_Yacute 0x0dd 3654 3655 Qt.Key_THORN 0x0de 3656 3657 Qt.Key_ssharp 0x0df 3658 3659 Qt.Key_division 0x0f7 3660 3661 Qt.Key_ydiaeresis 0x0ff 3662 3663 Qt.Key_Multi_key 0x01001120 3664 3665 Qt.Key_Codeinput 0x01001137 3666 3667 Qt.Key_SingleCandidate 0x0100113c 3668 3669 Qt.Key_MultipleCandidate 0x0100113d 3670 3671 Qt.Key_PreviousCandidate 0x0100113e 3672 3673 Qt.Key_Mode_switch 0x0100117e 3674 3675 Qt.Key_Kanji 0x01001121 3676 3677 Qt.Key_Muhenkan 0x01001122 3678 3679 Qt.Key_Henkan 0x01001123 3680 3681 Qt.Key_Romaji 0x01001124 3682 3683 Qt.Key_Hiragana 0x01001125 3684 3685 Qt.Key_Katakana 0x01001126 3686 3687 Qt.Key_Hiragana_Katakana 0x01001127 3688 3689 Qt.Key_Zenkaku 0x01001128 3690 3691 Qt.Key_Hankaku 0x01001129 3692 3693 Qt.Key_Zenkaku_Hankaku 0x0100112a 3694 3695 Qt.Key_Touroku 0x0100112b 3696 3697 Qt.Key_Massyo 0x0100112c 3698 3699 Qt.Key_Kana_Lock 0x0100112d 3700 3701 Qt.Key_Kana_Shift 0x0100112e 3702 3703 Qt.Key_Eisu_Shift 0x0100112f 3704 3705 Qt.Key_Eisu_toggle 0x01001130 3706 3707 Qt.Key_Hangul 0x01001131 3708 3709 Qt.Key_Hangul_Start 0x01001132 3710 3711 Qt.Key_Hangul_End 0x01001133 3712 3713 Qt.Key_Hangul_Hanja 0x01001134 3714 3715 Qt.Key_Hangul_Jamo 0x01001135 3716 3717 Qt.Key_Hangul_Romaja 0x01001136 3718 3719 Qt.Key_Hangul_Jeonja 0x01001138 3720 3721 Qt.Key_Hangul_Banja 0x01001139 3722 3723 Qt.Key_Hangul_PreHanja 0x0100113a 3724 3725 Qt.Key_Hangul_PostHanja 0x0100113b 3726 3727 Qt.Key_Hangul_Special 0x0100113f 3728 3729 Qt.Key_Dead_Grave 0x01001250 3730 3731 Qt.Key_Dead_Acute 0x01001251 3732 3733 Qt.Key_Dead_Circumflex 0x01001252 3734 3735 Qt.Key_Dead_Tilde 0x01001253 3736 3737 Qt.Key_Dead_Macron 0x01001254 3738 3739 Qt.Key_Dead_Breve 0x01001255 3740 3741 Qt.Key_Dead_Abovedot 0x01001256 3742 3743 Qt.Key_Dead_Diaeresis 0x01001257 3744 3745 Qt.Key_Dead_Abovering 0x01001258 3746 3747 Qt.Key_Dead_Doubleacute 0x01001259 3748 3749 Qt.Key_Dead_Caron 0x0100125a 3750 3751 Qt.Key_Dead_Cedilla 0x0100125b 3752 3753 Qt.Key_Dead_Ogonek 0x0100125c 3754 3755 Qt.Key_Dead_Iota 0x0100125d 3756 3757 Qt.Key_Dead_Voiced_Sound 0x0100125e 3758 3759 Qt.Key_Dead_Semivoiced_Sound 0x0100125f 3760 3761 Qt.Key_Dead_Belowdot 0x01001260 3762 3763 Qt.Key_Dead_Hook 0x01001261 3764 3765 Qt.Key_Dead_Horn 0x01001262 3766 3767 Qt.Key_Back 0x01000061 3768 3769 Qt.Key_Forward 0x01000062 3770 3771 Qt.Key_Stop 0x01000063 3772 3773 Qt.Key_Refresh 0x01000064 3774 3775 Qt.Key_VolumeDown 0x01000070 3776 3777 Qt.Key_VolumeMute 0x01000071 3778 3779 Qt.Key_VolumeUp 0x01000072 3780 3781 Qt.Key_BassBoost 0x01000073 3782 3783 Qt.Key_BassUp 0x01000074 3784 3785 Qt.Key_BassDown 0x01000075 3786 3787 Qt.Key_TrebleUp 0x01000076 3788 3789 Qt.Key_TrebleDown 0x01000077 3790 3791 Qt.Key_MediaPlay 0x01000080 A key setting the state of the media player to play 3792 3793 Qt.Key_MediaStop 0x01000081 A key setting the state of the media player to stop 3794 3795 Qt.Key_MediaPrevious 0x01000082 3796 3797 Qt.Key_MediaNext 0x01000083 3798 3799 Qt.Key_MediaRecord 0x01000084 3800 3801 Qt.Key_MediaPause 0x1000085 A key setting the state of the media player to pause (Note: not the pause/break key) 3802 3803 Qt.Key_MediaTogglePlayPause 0x1000086 A key to toggle the play/pause state in the media player (rather than setting an absolute state) 3804 3805 Qt.Key_HomePage 0x01000090 3806 3807 Qt.Key_Favorites 0x01000091 3808 3809 Qt.Key_Search 0x01000092 3810 3811 Qt.Key_Standby 0x01000093 3812 3813 Qt.Key_OpenUrl 0x01000094 3814 3815 Qt.Key_LaunchMail 0x010000a0 3816 3817 Qt.Key_LaunchMedia 0x010000a1 3818 3819 Qt.Key_Launch0 0x010000a2 On X11 this key is mapped to "My Computer" (XF86XK_MyComputer) key for legacy reasons. 3820 3821 Qt.Key_Launch1 0x010000a3 On X11 this key is mapped to "Calculator" (XF86XK_Calculator) key for legacy reasons. 3822 3823 Qt.Key_Launch2 0x010000a4 On X11 this key is mapped to XF86XK_Launch0 key for legacy reasons. 3824 3825 Qt.Key_Launch3 0x010000a5 On X11 this key is mapped to XF86XK_Launch1 key for legacy reasons. 3826 3827 Qt.Key_Launch4 0x010000a6 On X11 this key is mapped to XF86XK_Launch2 key for legacy reasons. 3828 3829 Qt.Key_Launch5 0x010000a7 On X11 this key is mapped to XF86XK_Launch3 key for legacy reasons. 3830 3831 Qt.Key_Launch6 0x010000a8 On X11 this key is mapped to XF86XK_Launch4 key for legacy reasons. 3832 3833 Qt.Key_Launch7 0x010000a9 On X11 this key is mapped to XF86XK_Launch5 key for legacy reasons. 3834 3835 Qt.Key_Launch8 0x010000aa On X11 this key is mapped to XF86XK_Launch6 key for legacy reasons. 3836 3837 Qt.Key_Launch9 0x010000ab On X11 this key is mapped to XF86XK_Launch7 key for legacy reasons. 3838 3839 Qt.Key_LaunchA 0x010000ac On X11 this key is mapped to XF86XK_Launch8 key for legacy reasons. 3840 3841 Qt.Key_LaunchB 0x010000ad On X11 this key is mapped to XF86XK_Launch9 key for legacy reasons. 3842 3843 Qt.Key_LaunchC 0x010000ae On X11 this key is mapped to XF86XK_LaunchA key for legacy reasons. 3844 3845 Qt.Key_LaunchD 0x010000af On X11 this key is mapped to XF86XK_LaunchB key for legacy reasons. 3846 3847 Qt.Key_LaunchE 0x010000b0 On X11 this key is mapped to XF86XK_LaunchC key for legacy reasons. 3848 3849 Qt.Key_LaunchF 0x010000b1 On X11 this key is mapped to XF86XK_LaunchD key for legacy reasons. 3850 3851 Qt.Key_LaunchG 0x0100010e On X11 this key is mapped to XF86XK_LaunchE key for legacy reasons. 3852 3853 Qt.Key_LaunchH 0x0100010f On X11 this key is mapped to XF86XK_LaunchF key for legacy reasons. 3854 3855 Qt.Key_MonBrightnessUp 0x010000b2 3856 3857 Qt.Key_MonBrightnessDown 0x010000b3 3858 3859 Qt.Key_KeyboardLightOnOff 0x010000b4 3860 3861 Qt.Key_KeyboardBrightnessUp 0x010000b5 3862 3863 Qt.Key_KeyboardBrightnessDown 0x010000b6 3864 3865 Qt.Key_PowerOff 0x010000b7 3866 3867 Qt.Key_WakeUp 0x010000b8 3868 3869 Qt.Key_Eject 0x010000b9 3870 3871 Qt.Key_ScreenSaver 0x010000ba 3872 3873 Qt.Key_WWW 0x010000bb 3874 3875 Qt.Key_Memo 0x010000bc 3876 3877 Qt.Key_LightBulb 0x010000bd 3878 3879 Qt.Key_Shop 0x010000be 3880 3881 Qt.Key_History 0x010000bf 3882 3883 Qt.Key_AddFavorite 0x010000c0 3884 3885 Qt.Key_HotLinks 0x010000c1 3886 3887 Qt.Key_BrightnessAdjust 0x010000c2 3888 3889 Qt.Key_Finance 0x010000c3 3890 3891 Qt.Key_Community 0x010000c4 3892 3893 Qt.Key_AudioRewind 0x010000c5 3894 3895 Qt.Key_BackForward 0x010000c6 3896 3897 Qt.Key_ApplicationLeft 0x010000c7 3898 3899 Qt.Key_ApplicationRight 0x010000c8 3900 3901 Qt.Key_Book 0x010000c9 3902 3903 Qt.Key_CD 0x010000ca 3904 3905 Qt.Key_Calculator 0x010000cb On X11 this key is not mapped for legacy reasons. Use Qt.Key_Launch1 instead. 3906 3907 Qt.Key_ToDoList 0x010000cc 3908 3909 Qt.Key_ClearGrab 0x010000cd 3910 3911 Qt.Key_Close 0x010000ce 3912 3913 Qt.Key_Copy 0x010000cf 3914 3915 Qt.Key_Cut 0x010000d0 3916 3917 Qt.Key_Display 0x010000d1 3918 3919 Qt.Key_DOS 0x010000d2 3920 3921 Qt.Key_Documents 0x010000d3 3922 3923 Qt.Key_Excel 0x010000d4 3924 3925 Qt.Key_Explorer 0x010000d5 3926 3927 Qt.Key_Game 0x010000d6 3928 3929 Qt.Key_Go 0x010000d7 3930 3931 Qt.Key_iTouch 0x010000d8 3932 3933 Qt.Key_LogOff 0x010000d9 3934 3935 Qt.Key_Market 0x010000da 3936 3937 Qt.Key_Meeting 0x010000db 3938 3939 Qt.Key_MenuKB 0x010000dc 3940 3941 Qt.Key_MenuPB 0x010000dd 3942 3943 Qt.Key_MySites 0x010000de 3944 3945 Qt.Key_News 0x010000df 3946 3947 Qt.Key_OfficeHome 0x010000e0 3948 3949 Qt.Key_Option 0x010000e1 3950 3951 Qt.Key_Paste 0x010000e2 3952 3953 Qt.Key_Phone 0x010000e3 3954 3955 Qt.Key_Calendar 0x010000e4 3956 3957 Qt.Key_Reply 0x010000e5 3958 3959 Qt.Key_Reload 0x010000e6 3960 3961 Qt.Key_RotateWindows 0x010000e7 3962 3963 Qt.Key_RotationPB 0x010000e8 3964 3965 Qt.Key_RotationKB 0x010000e9 3966 3967 Qt.Key_Save 0x010000ea 3968 3969 Qt.Key_Send 0x010000eb 3970 3971 Qt.Key_Spell 0x010000ec 3972 3973 Qt.Key_SplitScreen 0x010000ed 3974 3975 Qt.Key_Support 0x010000ee 3976 3977 Qt.Key_TaskPane 0x010000ef 3978 3979 Qt.Key_Terminal 0x010000f0 3980 3981 Qt.Key_Tools 0x010000f1 3982 3983 Qt.Key_Travel 0x010000f2 3984 3985 Qt.Key_Video 0x010000f3 3986 3987 Qt.Key_Word 0x010000f4 3988 3989 Qt.Key_Xfer 0x010000f5 3990 3991 Qt.Key_ZoomIn 0x010000f6 3992 3993 Qt.Key_ZoomOut 0x010000f7 3994 3995 Qt.Key_Away 0x010000f8 3996 3997 Qt.Key_Messenger 0x010000f9 3998 3999 Qt.Key_WebCam 0x010000fa 4000 4001 Qt.Key_MailForward 0x010000fb 4002 4003 Qt.Key_Pictures 0x010000fc 4004 4005 Qt.Key_Music 0x010000fd 4006 4007 Qt.Key_Battery 0x010000fe 4008 4009 Qt.Key_Bluetooth 0x010000ff 4010 4011 Qt.Key_WLAN 0x01000100 4012 4013 Qt.Key_UWB 0x01000101 4014 4015 Qt.Key_AudioForward 0x01000102 4016 4017 Qt.Key_AudioRepeat 0x01000103 4018 4019 Qt.Key_AudioRandomPlay 0x01000104 4020 4021 Qt.Key_Subtitle 0x01000105 4022 4023 Qt.Key_AudioCycleTrack 0x01000106 4024 4025 Qt.Key_Time 0x01000107 4026 4027 Qt.Key_Hibernate 0x01000108 4028 4029 Qt.Key_View 0x01000109 4030 4031 Qt.Key_TopMenu 0x0100010a 4032 4033 Qt.Key_PowerDown 0x0100010b 4034 4035 Qt.Key_Suspend 0x0100010c 4036 4037 Qt.Key_ContrastAdjust 0x0100010d 4038 4039 Qt.Key_MediaLast 0x0100ffff 4040 4041 Qt.Key_unknown 0x01ffffff 4042 4043 Qt.Key_Call 0x01100004 A key to answer or initiate a call (see Qt.Key_ToggleCallHangup for a key to toggle current call state) 4044 4045 Qt.Key_Camera 0x01100020 A key to activate the camera shutter 4046 4047 Qt.Key_CameraFocus 0x01100021 A key to focus the camera 4048 4049 Qt.Key_Context1 0x01100000 4050 4051 Qt.Key_Context2 0x01100001 4052 4053 Qt.Key_Context3 0x01100002 4054 4055 Qt.Key_Context4 0x01100003 4056 4057 Qt.Key_Flip 0x01100006 4058 4059 Qt.Key_Hangup 0x01100005 A key to end an ongoing call (see Qt.Key_ToggleCallHangup for a key to toggle current call state) 4060 4061 Qt.Key_No 0x01010002 4062 4063 Qt.Key_Select 0x01010000 4064 4065 Qt.Key_Yes 0x01010001 4066 4067 Qt.Key_ToggleCallHangup 0x01100007 A key to toggle the current call state (ie. either answer, or hangup) depending on current call state 4068 4069 Qt.Key_VoiceDial 0x01100008 4070 4071 Qt.Key_LastNumberRedial 0x01100009 4072 4073 Qt.Key_Execute 0x01020003 4074 4075 Qt.Key_Printer 0x01020002 4076 4077 Qt.Key_Play 0x01020005 4078 4079 Qt.Key_Sleep 0x01020004 4080 4081 Qt.Key_Zoom 0x01020006 4082 4083 Qt.Key_Cancel 0x01020001 4084 ''' 4085